Skip to content

Commit 7adb8e9

Browse files
Merge branch 'develop' into update-readme
2 parents b9203d2 + 60d3957 commit 7adb8e9

60 files changed

Lines changed: 5003 additions & 1852 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@ Code freeze date: YYYY-MM-DD
1212

1313
### Added
1414

15+
- Better type hints and overloads signatures for ImpactFuncSet [#1250](https://github.com/CLIMADA-project/climada_python/pull/1250)
16+
1517
### Changed
18+
- Updated Impact Calculation Tutorial (`doc.climada_engine_Impact.ipynb`) [#1095](https://github.com/CLIMADA-project/climada_python/pull/1095).
1619

1720
### Fixed
1821

22+
- Fixed asset count in impact logging message [#1195](https://github.com/CLIMADA-project/climada_python/pull/1195).
23+
1924
### Deprecated
2025

2126
### Removed
27+
- `climada.util.earth_engine.py` Google Earth Engine methods did not facilitate direct use of GEE data in CLIMADA. Code was relocated to [climada-snippets](https://github.com/CLIMADA-project/climada-snippets). [#1109](https://github.com/CLIMADA-project/climada_python/pull/1109)
28+
- `doc.climada_util_earth_engine.ipynb` Tutorial about GEE not relevant to CLIMADA Core. Tutorial notebook was relocated to [climada-snippets](https://github.com/CLIMADA-project/climada-snippets). [#1109](https://github.com/CLIMADA-project/climada_python/pull/1109)
2229

2330
## 6.1.0
2431

@@ -151,9 +158,9 @@ Removed:
151158
- `climada.entity.impact_funcs.trop_cyclone.ImpfSetTropCyclone.get_impf_id_regions_per_countries` function [#1034](https://github.com/CLIMADA-project/climada_python/pull/1034)
152159
- `climada.hazard.tc_tracks.BasinBoundsStorm` Enum class `climada.hazard.tc_tracks.subset_by_basin` function [#1031](https://github.com/CLIMADA-project/climada_python/pull/1031)
153160
- `climada.hazard.tc_tracks.TCTracks.subset_years` function [#1023](https://github.com/CLIMADA-project/climada_python/pull/1023)
154-
-`climada.hazard.tc_tracks.compute_track_density` function, `climada.hazard.tc_tracks.compute_genesis_density` function, `climada.hazard.plot.plot_track_density` function
161+
- `climada.hazard.tc_tracks.compute_track_density` function, `climada.hazard.tc_tracks.compute_genesis_density` function, `climada.hazard.plot.plot_track_density` function
155162
[#1003](https://github.com/CLIMADA-project/climada_python/pull/1003)
156-
-`climada.hazard.tc_tracks.TCTracks.from_FAST` function, add Australia basin (AU) [#993](https://github.com/CLIMADA-project/climada_python/pull/993)
163+
- `climada.hazard.tc_tracks.TCTracks.from_FAST` function, add Australia basin (AU) [#993](https://github.com/CLIMADA-project/climada_python/pull/993)
157164
- Add `osm-flex` package to CLIMADA core [#981](https://github.com/CLIMADA-project/climada_python/pull/981)
158165
- `doc.tutorial.climada_entity_Exposures_osm.ipynb` tutorial explaining how to use `osm-flex` with CLIMADA
159166
- `climada.util.coordinates.bounding_box_global` function [#980](https://github.com/CLIMADA-project/climada_python/pull/980)
-335 Bytes
Binary file not shown.

climada/engine/impact_calc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def impact(
186186
return self._return_empty(save_mat)
187187
LOGGER.info(
188188
"Calculating impact for %s assets (>0) and %s events.",
189-
exp_gdf.size,
189+
len(exp_gdf),
190190
self.n_events,
191191
)
192192
imp_mat_gen = self.imp_mat_gen(exp_gdf, impf_col)

climada/engine/test/test_impact_calc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ def test_calc_insured_impact_no_insurance(self):
441441
self.assertEqual(
442442
logs.output,
443443
[
444-
"INFO:climada.engine.impact_calc:Calculating impact for 150 assets (>0) and 14450 events."
444+
"INFO:climada.engine.impact_calc:Calculating impact for 50 assets (>0) and 14450 events."
445445
],
446446
)
447447
self.assertEqual(icalc.n_events, len(impact.at_event))

climada/engine/unsequa/input_var.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,8 @@ def haz(haz_list, n_ev=None, bounds_int=None, bounds_frac=None, bounds_freq=None
246246
The frequency of all events is multiplied by a number
247247
sampled uniformly from a distribution with (min, max) = bounds_freq
248248
HL: sample uniformly from hazard list
249-
From the provided list of hazard is elements are uniformly
250-
sampled. For example, Hazards outputs from dynamical models
251-
for different input factors.
249+
For each sample, one element is drawn uniformly from the provided list of hazards.
250+
For example, Hazards outputs from dynamical models for different input factors.
252251
253252
If a bounds is None, this parameter is assumed to have no uncertainty.
254253
@@ -310,8 +309,8 @@ def exp(exp_list, bounds_totval=None, bounds_noise=None):
310309
with (min, max) = bounds_noise. EN is the value of the seed
311310
for the uniform random number generator.
312311
EL: sample uniformly from exposure list
313-
From the provided list of exposure is elements are uniformly
314-
sampled. For example, LitPop instances with different exponents.
312+
For each sample, one element is drawn uniformly from the provided list of exposures.
313+
For example, LitPop instances with different exponents.
315314
316315
If a bounds is None, this parameter is assumed to have no uncertainty.
317316
@@ -376,9 +375,8 @@ def impfset(
376375
sampled uniformly from a distribution with
377376
(min, max) = bounds_int
378377
IL: sample uniformly from impact function set list
379-
From the provided list of impact function sets elements are uniformly
380-
sampled. For example, impact functions obtained from different
381-
calibration methods.
378+
For each sample, one element is drawn uniformly from the provided list of impact function sets.
379+
For example, impact functions obtained from different calibration methods.
382380
383381
384382
If a bounds is None, this parameter is assumed to have no uncertainty.
@@ -468,8 +466,8 @@ def ent(
468466
with (min, max) = bounds_noise. EN is the value of the seed
469467
for the uniform random number generator.
470468
EL: sample uniformly from exposure list
471-
From the provided list of exposure is elements are uniformly
472-
sampled. For example, LitPop instances with different exponents.
469+
For each sample, one element is drawn uniformly from the provided list of exposures.
470+
For example, LitPop instances with different exponents.
473471
MDD: scale the mdd (homogeneously)
474472
The value of mdd at each intensity is multiplied by a number
475473
sampled uniformly from a distribution with
@@ -483,9 +481,8 @@ def ent(
483481
sampled uniformly from a distribution with
484482
(min, max) = bounds_int
485483
IL: sample uniformly from impact function set list
486-
From the provided list of impact function sets elements are uniformly
487-
sampled. For example, impact functions obtained from different
488-
calibration methods.
484+
For each sample, one element is drawn uniformly from the provided list of impact function sets.
485+
For example, impact functions obtained from different calibration methods.
489486
490487
If a bounds is None, this parameter is assumed to have no uncertainty.
491488
@@ -566,7 +563,7 @@ def ent(
566563
bounds_noise=bounds_noise,
567564
exp_list=exp_list,
568565
meas_set=meas_set,
569-
**kwargs
566+
**kwargs,
570567
),
571568
_ent_unc_dict(
572569
bounds_totval=bounds_totval,
@@ -616,8 +613,8 @@ def entfut(
616613
with (min, max) = bounds_noise. EN is the value of the seed
617614
for the uniform random number generator.
618615
EL: sample uniformly from exposure list
619-
From the provided list of exposure is elements are uniformly
620-
sampled. For example, LitPop instances with different exponents.
616+
For each sample, one element is drawn uniformly from the provided list of exposures.
617+
For example, LitPop instances with different exponents.
621618
MDD: scale the mdd (homogeneously)
622619
The value of mdd at each intensity is multiplied by a number
623620
sampled uniformly from a distribution with
@@ -631,9 +628,8 @@ def entfut(
631628
sampled uniformly from a distribution with
632629
(min, max) = bounds_impfi
633630
IL: sample uniformly from impact function set list
634-
From the provided list of impact function sets elements are uniformly
635-
sampled. For example, impact functions obtained from different
636-
calibration methods.
631+
For each sample, one element is drawn uniformly from the provided list of impact function sets.
632+
For example, impact functions obtained from different calibration methods.
637633
638634
If a bounds is None, this parameter is assumed to have no uncertainty.
639635
@@ -706,7 +702,7 @@ def entfut(
706702
impf_set_list=impf_set_list,
707703
exp_list=exp_list,
708704
meas_set=meas_set,
709-
**kwargs
705+
**kwargs,
710706
),
711707
_entfut_unc_dict(
712708
bounds_eg=bounds_eg,

climada/engine/unsequa/test/test_unsequa.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,18 @@
4141
from climada.entity import Exposures, ImpactFunc, ImpactFuncSet
4242
from climada.entity.entity_def import Entity
4343
from climada.hazard import Hazard
44-
from climada.util.api_client import Client
44+
from climada.test import get_test_file
4545
from climada.util.constants import (
4646
ENT_DEMO_FUTURE,
4747
ENT_DEMO_TODAY,
48-
EXP_DEMO_H5,
4948
HAZ_DEMO_H5,
5049
TEST_UNC_OUTPUT_COSTBEN,
5150
TEST_UNC_OUTPUT_IMPACT,
5251
)
5352

54-
test_unc_output_impact = Client().get_dataset_file(
55-
name=TEST_UNC_OUTPUT_IMPACT, status="test_dataset"
56-
)
57-
test_unc_output_costben = Client().get_dataset_file(
58-
name=TEST_UNC_OUTPUT_COSTBEN, status="test_dataset"
59-
)
53+
EXP_DEMO_H5 = get_test_file("exp_demo_today", file_format="hdf5")
54+
test_unc_output_impact = get_test_file(TEST_UNC_OUTPUT_IMPACT)
55+
test_unc_output_costben = get_test_file(TEST_UNC_OUTPUT_COSTBEN)
6056

6157

6258
def impf_dem(x_paa=1, x_mdd=1):
@@ -578,7 +574,7 @@ def test_calc_sensitivity_all_pass(self):
578574
"sensitivity_kwargs": {"S": 10, "seed": 12345},
579575
"test_param_name": ["x_exp", 0],
580576
"test_si_name": ["CV", 16],
581-
"test_si_value": [0.25000, 2],
577+
"test_si_value": [0.250000, 2],
582578
},
583579
"hdmr": {
584580
"sampling_method": "saltelli",
@@ -587,7 +583,7 @@ def test_calc_sensitivity_all_pass(self):
587583
"sensitivity_kwargs": {},
588584
"test_param_name": ["x_exp", 2],
589585
"test_si_name": ["Sa", 4],
590-
"test_si_value": [0.004658, 3],
586+
"test_si_value": [0.004649, 3],
591587
},
592588
"ff": {
593589
"sampling_method": "ff",
@@ -618,7 +614,7 @@ def test_calc_sensitivity_all_pass(self):
618614
},
619615
"test_param_name": ["x_exp", 0],
620616
"test_si_name": ["dgsm", 8],
621-
"test_si_value": [1.697516e-01, 9],
617+
"test_si_value": [0.1697516, 9],
622618
},
623619
"fast": {
624620
"sampling_method": "fast_sampler",
@@ -627,7 +623,7 @@ def test_calc_sensitivity_all_pass(self):
627623
"sensitivity_kwargs": {"M": 4, "seed": 12345},
628624
"test_param_name": ["x_exp", 0],
629625
"test_si_name": ["S1_conf", 8],
630-
"test_si_value": [0.671396, 1],
626+
"test_si_value": [0.671546, 1],
631627
},
632628
"rbd_fast": {
633629
"sampling_method": "saltelli",
@@ -636,7 +632,7 @@ def test_calc_sensitivity_all_pass(self):
636632
"sensitivity_kwargs": {"M": 4, "seed": 12345},
637633
"test_param_name": ["x_exp", 0],
638634
"test_si_name": ["S1_conf", 4],
639-
"test_si_value": [0.152609, 4],
635+
"test_si_value": [0.129919, 4],
640636
},
641637
"morris": {
642638
"sampling_method": "morris",
@@ -645,7 +641,7 @@ def test_calc_sensitivity_all_pass(self):
645641
"sensitivity_kwargs": {},
646642
"test_param_name": ["x_exp", 0],
647643
"test_si_name": ["mu", 1],
648-
"test_si_value": [5066460029.63911, 8],
644+
"test_si_value": [7935400297.813827, 8],
649645
},
650646
}
651647

@@ -700,7 +696,7 @@ def test_sensitivity_method(
700696
haz_unc,
701697
sensitivity_method,
702698
method_params,
703-
places=2 if sensitivity_method == "rbd_fast" else 5,
699+
places=5,
704700
)
705701

706702

climada/entity/exposures/base.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ def __init__(
403403

404404
self.description = self._consolidate(meta, "description", description)
405405
self.ref_year = self._consolidate(meta, "ref_year", ref_year, DEF_REF_YEAR)
406+
407+
if geodata.shape[0] > 0:
408+
value_unit = self._consolidate(geodata.iloc[0], "value_unit", value_unit)
406409
self.value_unit = self._consolidate(
407410
meta, "value_unit", value_unit, DEF_VALUE_UNIT
408411
)
@@ -644,15 +647,17 @@ def assign_centroids(
644647
645648
Caution: nearest neighbourg matching can introduce serious artefacts
646649
such as:
647-
- exposure and hazard centroids with shifted grids can lead
648-
to systematically wrong assignements.
649-
- hazard centroids covering larger areas than exposures may lead
650-
to sub-optimal matching if the threshold is too large
651-
- projected crs often diverge at the anti-meridian and close points
652-
on either side will be at a large distance. For proper handling
653-
of the anti-meridian please use degree coordinates in EPSG:4326.
654-
This might be relevant for countries like the Fidji or the US that
655-
cross the anti-meridian.
650+
651+
- exposure and hazard centroids with shifted grids can lead
652+
to systematically wrong assignements.
653+
- hazard centroids covering larger areas than exposures may lead
654+
to sub-optimal matching if the threshold is too large
655+
- projected crs often diverge at the anti-meridian and close points
656+
on either side will be at a large distance. For proper handling
657+
of the anti-meridian please use degree coordinates in EPSG:4326.
658+
This might be relevant for countries like the Fidji or the US that
659+
cross the anti-meridian.
660+
656661
657662
Users are free to implement their own matching alrogithm and save the
658663
matching centroid index in the appropriate column ``centr_[hazard.HAZ_TYPE]``.

climada/entity/exposures/test/test_base.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def test__init__mda_in_kwargs(self):
182182
def test_read_raster_pass(self):
183183
"""from_raster"""
184184
exp = Exposures.from_raster(
185-
HAZ_DEMO_FL, window=Window(10, 20, 50, 60), attrs={"value_unit": "USD"}
185+
HAZ_DEMO_FL, window=Window(10, 20, 50, 60), attrs={"value_unit": "PKR"}
186186
)
187187
exp.check()
188188
self.assertTrue(u_coord.equal_crs(exp.crs, DEF_CRS))
@@ -204,7 +204,7 @@ def test_read_raster_pass(self):
204204
self.assertAlmostEqual(
205205
exp.gdf["value"].values.reshape((60, 50))[25, 12], 0.056825936
206206
)
207-
self.assertEqual(exp.value_unit, "USD")
207+
self.assertEqual(exp.value_unit, "PKR")
208208

209209
def test_assign_raster_pass(self):
210210
"""Test assign_centroids with raster hazard"""
@@ -429,16 +429,23 @@ def test_read_template_pass(self):
429429
exp_df = Exposures(df)
430430
# set metadata
431431
exp_df.ref_year = 2020
432-
exp_df.value_unit = "XSD"
432+
exp_df.value_unit = "PAK"
433433
exp_df.check()
434434

435+
def test_handling_unit_conflicts_pass(self):
436+
"""Check that the value_unit is correctly set when there are conflicting value_unit definitions in the data frame and the meta attribute."""
437+
df = pd.read_excel(ENT_TEMPLATE_XLS)
438+
exp_df = Exposures(df, meta={"value_unit": "XSD"}, value_unit="XSD")
439+
exp_df.check()
440+
self.assertEqual(exp_df.value_unit, "XSD")
441+
with self.assertRaises(ValueError) as cm:
442+
exp_df = Exposures(df, meta={"value_unit": "XSD"}, value_unit="PAK")
443+
435444
def test_io_hdf5_pass(self):
436445
"""write and read hdf5"""
437-
exp = Exposures(pd.read_excel(ENT_TEMPLATE_XLS), crs="epsg:32632")
438-
439-
# set metadata
440-
exp.ref_year = 2020
441-
exp.value_unit = "XSD"
446+
exp = Exposures(
447+
pd.read_excel(ENT_TEMPLATE_XLS), crs="epsg:32632", ref_year=2020
448+
)
442449

443450
# add another geometry column
444451
exp.data["geocol2"] = exp.data.geometry.copy(deep=True)

climada/entity/impact_funcs/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def from_step_impf(
189189
haz_type: str,
190190
mdd: tuple[float, float] = (0, 1),
191191
paa: tuple[float, float] = (1, 1),
192-
impf_id: int = 1,
192+
impf_id: int | str = 1,
193193
**kwargs,
194194
):
195195
"""Step function type impact function.
@@ -207,7 +207,7 @@ def from_step_impf(
207207
(min, max) mdd values. The default is (0, 1)
208208
paa: tuple(float, float)
209209
(min, max) paa values. The default is (1, 1)
210-
impf_id : int, optional, default=1
210+
impf_id : int|str, optional, default=1
211211
impact function id
212212
kwargs :
213213
keyword arguments passed to ImpactFunc()
@@ -250,7 +250,7 @@ def from_sigmoid_impf(
250250
k: float,
251251
x0: float,
252252
haz_type: str,
253-
impf_id: int = 1,
253+
impf_id: int | str = 1,
254254
**kwargs,
255255
):
256256
r"""Sigmoid type impact function hinging on three parameter.
@@ -320,7 +320,7 @@ def from_poly_s_shape(
320320
scale: float,
321321
exponent: float,
322322
haz_type: str,
323-
impf_id: int = 1,
323+
impf_id: int | str = 1,
324324
**kwargs,
325325
):
326326
r"""S-shape polynomial impact function hinging on four parameter.

0 commit comments

Comments
 (0)