Skip to content

Commit 6279ec5

Browse files
Merge branch 'develop' into feature/pickle_free_centroids_store
2 parents 6d19c26 + 1d266b6 commit 6279ec5

File tree

8 files changed

+47
-74
lines changed

8 files changed

+47
-74
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Code freeze date: YYYY-MM-DD
1313
Removed:
1414

1515
- `pandas-datareader`
16+
- `intensity_thres` of `Hazard`, `StormEurope`, and `TropCyclones` object [#1065](https://github.com/CLIMADA-project/climada_python/pull/1065)
17+
- Deprecated method `climada.hazard.trop_cyclone.trop_cyclone.TropCyclone.set_from_tracks` [#1065](https://github.com/CLIMADA-project/climada_python/pull/1065)
1618

1719
### Added
1820
- Added optional parameter to `geo_im_from_array`, `plot_from_gdf`, `plot_rp_imp`, `plot_rp_intensity`,

climada/engine/unsequa/test/test_unsequa.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ def test_calc_sensitivity_all_pass(self):
650650
}
651651

652652
def test_sensitivity_method(
653-
exp_unc, impf_unc, haz_unc, sensitivity_method, param_dict
653+
exp_unc, impf_unc, haz_unc, sensitivity_method, param_dict, places
654654
):
655655
"""Function to test each seaprate sensitivity method"""
656656
unc_calc = CalcImpact(exp_unc, impf_unc, haz_unc)
@@ -681,7 +681,7 @@ def test_sensitivity_method(
681681
self.assertAlmostEqual(
682682
param_dict["test_si_value"][0],
683683
unc_data.aai_agg_sens_df["aai_agg"][param_dict["test_si_value"][1]],
684-
places=5,
684+
places=places,
685685
)
686686

687687
self.assertEqual(unc_data.aai_agg_unc_df.size, unc_data.n_samples)
@@ -695,7 +695,12 @@ def test_sensitivity_method(
695695
# loop over each method and do test
696696
for sensitivity_method, method_params in test_dict.items():
697697
test_sensitivity_method(
698-
exp_unc, impf_unc, haz_unc, sensitivity_method, method_params
698+
exp_unc,
699+
impf_unc,
700+
haz_unc,
701+
sensitivity_method,
702+
method_params,
703+
places=2 if sensitivity_method == "rbd_fast" else 5,
699704
)
700705

701706

climada/hazard/base.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ class Hazard(HazardIO, HazardPlot):
101101
(i.e., is equivalent to fraction is 1 everywhere).
102102
"""
103103

104-
intensity_thres = 10
105-
"""Intensity threshold per hazard used to filter lower intensities. To be
106-
set for every hazard type"""
107-
108104
vars_oblig = {
109105
"units",
110106
"centroids",
@@ -485,7 +481,7 @@ def local_exceedance_intensity(
485481
self,
486482
return_periods=(25, 50, 100, 250),
487483
method="interpolate",
488-
min_intensity=None,
484+
min_intensity=0,
489485
log_frequency=True,
490486
log_intensity=True,
491487
bin_decimals=None,
@@ -512,8 +508,7 @@ def local_exceedance_intensity(
512508
periods and extends the interpolation between these points to the given return period
513509
(similar for small return periods). Defauls to "interpolate".
514510
min_intensity : float, optional
515-
Minimum threshold to filter the hazard intensity. If set to None, self.intensity_thres
516-
will be used. Defaults to None.
511+
Minimum threshold to filter the hazard intensity. Defaults to 0.
517512
log_frequency : bool, optional
518513
If set to True, (cummulative) frequency values are converted to log scale before
519514
inter- and extrapolation. Defaults to True.
@@ -554,8 +549,6 @@ def local_exceedance_intensity(
554549
intensities range from 1e6 to 1e9, you could use bin_decimals=-5, if your intensities
555550
range from 0.0001 to .01, you could use bin_decimals=5.
556551
"""
557-
if not min_intensity and min_intensity != 0:
558-
min_intensity = self.intensity_thres
559552
# check frequency unit
560553
return_period_unit = u_dt.convert_frequency_unit_to_time_unit(
561554
self.frequency_unit
@@ -639,7 +632,7 @@ def local_return_period(
639632
self,
640633
threshold_intensities=(10.0, 20.0),
641634
method="interpolate",
642-
min_intensity=None,
635+
min_intensity=0,
643636
log_frequency=True,
644637
log_intensity=True,
645638
bin_decimals=None,
@@ -667,8 +660,7 @@ def local_return_period(
667660
points to the given threshold intensity (similar for small threshold intensites).
668661
Defaults to "interpolate".
669662
min_intensity : float, optional
670-
Minimum threshold to filter the hazard intensity. If set to None, self.intensity_thres
671-
will be used. Defaults to None.
663+
Minimum threshold to filter the hazard intensity. Defaults to 0.
672664
log_frequency : bool, optional
673665
If set to True, (cummulative) frequency values are converted to log scale before
674666
inter- and extrapolation. Defaults to True.
@@ -710,8 +702,6 @@ def local_return_period(
710702
intensities range from 1e6 to 1e9, you could use bin_decimals=-5, if your intensities
711703
range from 0.0001 to .01, you could use bin_decimals=5.
712704
"""
713-
if not min_intensity and min_intensity != 0:
714-
min_intensity = self.intensity_thres
715705
# check frequency unit
716706
return_period_unit = u_dt.convert_frequency_unit_to_time_unit(
717707
self.frequency_unit

climada/hazard/storm_europe.py

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
N_PROB_EVENTS = 5 * 6
5858
"""Number of events per historic event in probabilistic dataset"""
5959

60+
DEF_INTENSITY_THRES = 14.7
61+
"""
62+
Default value for the threshold below which wind speeds (in m/s) are stored as 0.
63+
Same as used by WISC SSI calculations.
64+
"""
65+
6066

6167
class StormEurope(Hazard):
6268
"""A hazard set containing european winter storm events. Historic storm
@@ -79,10 +85,8 @@ class StormEurope(Hazard):
7985
values only.
8086
ssi : np.array, float
8187
SSI as set by set_ssi; uses the Dawkins definition by default.
82-
"""
8388
84-
intensity_thres = 14.7
85-
"""Intensity threshold for storage in m/s; same as used by WISC SSI calculations."""
89+
"""
8690

8791
vars_opt = Hazard.vars_opt.union({"ssi_wisc", "ssi", "ssi_full_area"})
8892
"""Name of the variables that aren't need to compute the impact."""
@@ -139,7 +143,7 @@ def from_footprints(
139143
centroids=None,
140144
files_omit="fp_era20c_1990012515_701_0.nc",
141145
combine_threshold=None,
142-
intensity_thres=None,
146+
intensity_thres=DEF_INTENSITY_THRES,
143147
):
144148
"""Create new StormEurope object from WISC footprints.
145149
@@ -171,18 +175,15 @@ def from_footprints(
171175
events are combined into one.
172176
Default is None, Advised for WISC is 2
173177
intensity_thres : float, optional
174-
Intensity threshold for storage in m/s. Default: class attribute
175-
StormEurope.intensity_thres (same as used by WISC SSI calculations)
178+
Intensity threshold for storage in m/s. Default: 14.7
179+
(same as used by WISC SSI calculations)
176180
177181
Returns
178182
-------
179183
haz : StormEurope
180184
StormEurope object with data from WISC footprints.
181185
"""
182186
# pylint: disable=protected-access
183-
intensity_thres = (
184-
cls.intensity_thres if intensity_thres is None else intensity_thres
185-
)
186187
file_names = get_file_names(path)
187188

188189
if ref_raster is not None and centroids is not None:
@@ -300,7 +301,7 @@ def from_cosmoe_file(
300301
event_date=None,
301302
model_name="COSMO-2E",
302303
description=None,
303-
intensity_thres=None,
304+
intensity_thres=DEF_INTENSITY_THRES,
304305
):
305306
"""Create a new StormEurope object with gust footprint from weather forecast.
306307
@@ -331,17 +332,14 @@ def from_cosmoe_file(
331332
description of the events, defaults
332333
to a combination of model_name and run_datetime
333334
intensity_thres : float, optional
334-
Intensity threshold for storage in m/s. Default: class attribute
335-
StormEurope.intensity_thres (same as used by WISC SSI calculations)
335+
Intensity threshold for storage in m/s. Default: 14.7
336+
(same as used by WISC SSI calculations)
336337
337338
Returns
338339
-------
339340
haz : StormEurope
340341
StormEurope object with data from COSMO ensemble file.
341342
"""
342-
intensity_thres = (
343-
cls.intensity_thres if intensity_thres is None else intensity_thres
344-
)
345343

346344
# read intensity from file
347345
with xr.open_dataset(fp_file) as ncdf:
@@ -435,7 +433,7 @@ def from_icon_grib(
435433
description=None,
436434
grib_dir=None,
437435
delete_raw_data=True,
438-
intensity_thres=None,
436+
intensity_thres=DEF_INTENSITY_THRES,
439437
):
440438
"""Create new StormEurope object from DWD icon weather forecast footprints.
441439
@@ -472,18 +470,15 @@ def from_icon_grib(
472470
.grib.bz2 file format should be stored on the computer or
473471
removed
474472
intensity_thres : float, optional
475-
Intensity threshold for storage in m/s. Default: class attribute
476-
StormEurope.intensity_thres (same as used by WISC SSI calculations)
473+
Intensity threshold for storage in m/s. Default: 14.7
474+
(same as used by WISC SSI calculations)
477475
478476
Returns
479477
-------
480478
haz : StormEurope
481479
StormEurope object with data from DWD icon weather forecast footprints.
482480
"""
483481
# pylint: disable=protected-access
484-
intensity_thres = (
485-
cls.intensity_thres if intensity_thres is None else intensity_thres
486-
)
487482

488483
if not (run_datetime.hour == 0 or run_datetime.hour == 12):
489484
LOGGER.warning(
@@ -724,8 +719,7 @@ def calc_ssi(
724719
ignoring the intensities at sea. Defaults to true, whereas
725720
the MATLAB version did not.
726721
threshold : float, optional
727-
Intensity threshold used in index
728-
definition. Cannot be lower than the read-in value.
722+
Intensity threshold used in index definition.
729723
sel_cen : np.array, bool
730724
A boolean vector selecting centroids.
731725
Takes precendence over on_land.
@@ -739,12 +733,7 @@ def calc_ssi(
739733
intensity = self.intensity
740734

741735
if threshold is not None:
742-
assert (
743-
threshold >= self.intensity_thres
744-
), "threshold cannot be below threshold upon read_footprint"
745736
intensity = intensity.multiply(intensity > threshold)
746-
else:
747-
intensity = intensity.multiply(intensity > self.intensity_thres)
748737

749738
cent = self.centroids
750739
area_pixel = cent.get_area_pixel()

climada/hazard/test/test_base.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,6 @@ def test_local_exceedance_intensity(self):
11561156
"""Test local exceedance frequencies with lin lin interpolation"""
11571157
haz = dummy_hazard()
11581158
haz.intensity = sparse.csr_matrix([[1.0, 3.0, 1.0], [2.0, 3.0, 0.0]])
1159-
haz.intensity_thres = 0.5
11601159
haz.frequency = np.full(2, 1.0)
11611160
return_period = np.array([0.5, 2.0 / 3.0, 1.0])
11621161
# first centroid has intensities 1,2 with cum frequencies 2,1
@@ -1180,17 +1179,19 @@ def test_local_exceedance_intensity_methods(self):
11801179
haz.intensity = sparse.csr_matrix(
11811180
[[0, 0, 1e1], [0.2, 1e1, 1e2], [1e3, 1e3, 1e3]]
11821181
)
1183-
haz.intensity_thres = 0.5
1182+
min_intensity = 0.5
11841183
haz.frequency = np.array([1.0, 0.1, 0.01])
1185-
return_period = (1000, 30, 0.1)
1184+
return_periods = (1000, 30, 0.1)
11861185
# first centroid has intensities 1e3 with frequencies .01, cum freq .01
11871186
# second centroid has intensities 1e1, 1e3 with cum frequencies .1, .01, cum freq .11, .01
11881187
# third centroid has intensities 1e1, 1e2, 1e3 with cum frequencies 1., .1, .01, cum freq 1.11, .11, .01
11891188
# testing at frequencies .001, .033, 10.
11901189

11911190
# test stepfunction
11921191
inten_stats, _, _ = haz.local_exceedance_intensity(
1193-
return_periods=(1000, 30, 0.1), method="stepfunction"
1192+
return_periods=return_periods,
1193+
method="stepfunction",
1194+
min_intensity=min_intensity,
11941195
)
11951196
np.testing.assert_allclose(
11961197
inten_stats.values[:, 1:].astype(float),
@@ -1199,7 +1200,9 @@ def test_local_exceedance_intensity_methods(self):
11991200

12001201
# test log log extrapolation
12011202
inten_stats, _, _ = haz.local_exceedance_intensity(
1202-
return_periods=(1000, 30, 0.1), method="extrapolate"
1203+
return_periods=return_periods,
1204+
method="extrapolate",
1205+
min_intensity=min_intensity,
12031206
)
12041207
np.testing.assert_allclose(
12051208
inten_stats.values[:, 1:].astype(float),
@@ -1209,7 +1212,9 @@ def test_local_exceedance_intensity_methods(self):
12091212

12101213
# test log log interpolation and extrapolation with constant
12111214
inten_stats, _, _ = haz.local_exceedance_intensity(
1212-
return_periods=(1000, 30, 0.1), method="extrapolate_constant"
1215+
return_periods=return_periods,
1216+
method="extrapolate_constant",
1217+
min_intensity=min_intensity,
12131218
)
12141219
np.testing.assert_allclose(
12151220
inten_stats.values[:, 1:].astype(float),
@@ -1219,7 +1224,7 @@ def test_local_exceedance_intensity_methods(self):
12191224

12201225
# test log log interpolation and no extrapolation
12211226
inten_stats, _, _ = haz.local_exceedance_intensity(
1222-
return_periods=(1000, 30, 0.1)
1227+
return_periods=return_periods, min_intensity=min_intensity
12231228
)
12241229
np.testing.assert_allclose(
12251230
inten_stats.values[:, 1:].astype(float),
@@ -1235,6 +1240,7 @@ def test_local_exceedance_intensity_methods(self):
12351240
log_frequency=False,
12361241
log_intensity=False,
12371242
method="extrapolate_constant",
1243+
min_intensity=min_intensity,
12381244
)
12391245
np.testing.assert_allclose(
12401246
inten_stats.values[:, 1:].astype(float),
@@ -1270,7 +1276,6 @@ def test_local_return_period_methods(self):
12701276
haz.intensity = sparse.csr_matrix(
12711277
[[0, 0, 1e1], [0.0, 1e1, 1e2], [1e3, 1e3, 1e3]]
12721278
)
1273-
haz.intensity_thres = 0.5
12741279
haz.frequency = np.array([1.0, 0.1, 0.01])
12751280
# first centroid has intensities 1e3 with frequencies .01, cum freq .01
12761281
# second centroid has intensities 1e1, 1e3 with cum frequencies .1, .01, cum freq .11, .01

climada/hazard/trop_cyclone/trop_cyclone.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,8 @@ class TropCyclone(Hazard):
8888
For each event, the full velocity vectors at each centroid and track position in a sparse
8989
matrix of shape (npositions, ncentroids * 2) that can be reshaped to a full ndarray of
9090
shape (npositions, ncentroids, 2).
91-
"""
9291
93-
intensity_thres = DEF_INTENSITY_THRES
94-
"""intensity threshold for storage in m/s"""
92+
"""
9593

9694
vars_opt = Hazard.vars_opt.union({"category"})
9795
"""Name of the variables that are not needed to compute the impact."""
@@ -142,19 +140,6 @@ def __init__(
142140
self.basin = basin if basin is not None else []
143141
self.windfields = windfields if windfields is not None else []
144142

145-
def set_from_tracks(self, *args, **kwargs):
146-
"""This function is deprecated, use TropCyclone.from_tracks instead."""
147-
LOGGER.warning(
148-
"The use of TropCyclone.set_from_tracks is deprecated."
149-
"Use TropCyclone.from_tracks instead."
150-
)
151-
if "intensity_thres" not in kwargs:
152-
# some users modify the threshold attribute before calling `set_from_tracks`
153-
kwargs["intensity_thres"] = self.intensity_thres
154-
if self.pool is not None and "pool" not in kwargs:
155-
kwargs["pool"] = self.pool
156-
self.__dict__ = TropCyclone.from_tracks(*args, **kwargs).__dict__
157-
158143
@classmethod
159144
def from_tracks(
160145
cls,
@@ -381,7 +366,6 @@ def from_tracks(
381366
LOGGER.debug("Concatenate events.")
382367
haz = cls.concat(tc_haz_list)
383368
haz.pool = pool
384-
haz.intensity_thres = intensity_thres
385369
LOGGER.debug("Compute frequency.")
386370
haz.frequency_from_tracks(tracks.data)
387371
return haz
@@ -709,7 +693,6 @@ def from_single_track(
709693
)
710694

711695
new_haz = cls(haz_type=HAZ_TYPE)
712-
new_haz.intensity_thres = intensity_thres
713696
new_haz.intensity = intensity_sparse
714697
if store_windfields:
715698
new_haz.windfields = [windfields_sparse]

doc/misc/citation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ If you use specific tools and modules of CLIMADA, please cite the appropriate pu
2020
* - *Any*
2121
- The `Zenodo archive <https://doi.org/10.5281/zenodo.4598943>`_ of the CLIMADA version you are using
2222
* - :doc:`Impact calculations </user-guide/climada_engine_Impact>`
23-
- Aznar-Siguan, G. and Bresch, D. N. (2019): CLIMADA v1: A global weather and climate risk assessment platform, Geosci. Model Dev., 12, 3085–3097, https://doi.org/10.5194/gmd-14-351-2021
23+
- Aznar-Siguan, G. and Bresch, D. N. (2019): CLIMADA v1: A global weather and climate risk assessment platform, Geosci. Model Dev., 12, 3085–3097, https://doi.org/10.5194/gmd-12-3085-2019
2424
* - :doc:`Cost-benefit analysis </user-guide/climada_engine_CostBenefit>`
2525
- Bresch, D. N. and Aznar-Siguan, G. (2021): CLIMADA v1.4.1: Towards a globally consistent adaptation options appraisal tool, Geosci. Model Dev., 14, 351–363, https://doi.org/10.5194/gmd-14-351-2021
2626
* - :doc:`Uncertainty and sensitivity analysis </user-guide/climada_engine_unsequa>`

doc/user-guide/climada_util_local_exceedance_values.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
},
4141
{
4242
"cell_type": "code",
43-
"execution_count": 1,
43+
"execution_count": null,
4444
"metadata": {},
4545
"outputs": [
4646
{
@@ -86,7 +86,6 @@
8686
" frequency_unit=\"1/year\",\n",
8787
" units=\"m/s\",\n",
8888
")\n",
89-
"hazard.intensity_thres = 0\n",
9089
"\n",
9190
"# plot first event of Hazard object\n",
9291
"hazard.plot_intensity(event=1, smooth=False, figsize=(4, 4));"

0 commit comments

Comments
 (0)