Skip to content

Commit 8276fd0

Browse files
committed
Resolve merge conflict in hazard tutorial
2 parents 0c1d6db + beb7e75 commit 8276fd0

37 files changed

+2473
-2705
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior/error:
15+
1.
16+
17+
Code example:
18+
```python
19+
# Your code here
20+
```
21+
22+
**Expected behavior**
23+
A clear and concise description of what you expected to happen.
24+
25+
**Screenshots**
26+
If applicable, add screenshots to help explain your problem.
27+
28+
**Climada Version:** [Version or branch]
29+
30+
**System Information (please complete the following information):**
31+
- Operating system and version: [e.g. Ubuntu 22.04, macOS 14.3.1, Windows 10]
32+
- Python version: [e.g. 3.10]
33+
(to obtain this information execute > import sys >print(sys.version))
34+
35+
**Additional context**
36+
Add any other context about the problem here.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Code feature request
3+
about: Suggest an idea to improve the code
4+
title: ''
5+
labels: enhancement
6+
assignees: ''
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Describe alternatives you've considered**
17+
A clear and concise description of any alternative solutions or features you've considered.
18+
19+
**Additional context**
20+
Add any other context or screenshots about the feature request here.

AUTHORS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@
3232
* Kam Lam Yeung
3333
* Sarah Hülsen
3434
* Timo Schmid
35+
* Luca Severino
36+
* Samuel Juhel

CHANGELOG.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,62 @@ Code freeze date: YYYY-MM-DD
1010

1111
### Dependency Changes
1212

13-
### Added
14-
1513
### Changed
1614

15+
- Centroids complete overhaul. Most function should be backward compatible. Internal data is stored in a geodataframe attribute. Raster are now stored as points, and the meta attribute is removed. Several methds were deprecated or removed. [#787](https://github.com/CLIMADA-project/climada_python/pull/787)
16+
- Improved error messages produced by `ImpactCalc.impact()` in case impact function in the exposures is not found in impf_set [#863](https://github.com/CLIMADA-project/climada_python/pull/863)
17+
1718
### Fixed
1819

20+
### Added
21+
22+
- climada.hazard.centroids.centr.Centroids.get_area_pixel
23+
- climada.hazard.centroids.centr.Centroids.get_dist_coast
24+
- climada.hazard.centroids.centr.Centroids.get_elevation
25+
- climada.hazard.centroids.centr.Centroids.get_meta
26+
- climada.hazard.centroids.centr.Centroids.get_pixel_shapes
27+
- climada.hazard.centroids.centr.Centroids.to_crs
28+
- climada.hazard.centroids.centr.Centroids.to_default_crs
29+
- climada.hazard.centroids.centr.Centroids.write_csv
30+
- climada.hazard.centroids.centr.Centroids.write_excel
31+
1932
### Deprecated
2033

34+
- climada.hazard.centroids.centr.Centroids.from_lat_lon
35+
- climada.hazard.centroids.centr.Centroids.def set_area_pixel
36+
- climada.hazard.centroids.centr.Centroids.def set_area_approx
37+
- climada.hazard.centroids.centr.Centroids.set_dist_coast
38+
- climada.hazard.centroids.centr.Centroids.empty_geometry_points
39+
- climada.hazard.centroids.centr.Centroids.set_meta_to_lat_lon
40+
- climada.hazard.centroids.centr.Centroids.set_lat_lon_to_meta
41+
2142
### Removed
2243

44+
- climada.hazard.base.Hazard.clear
45+
- climada.hazard.base.Hazard.raster_to_vector
46+
- climada.hazard.base.Hazard.read_mat
47+
- climada.hazard.base.Hazard.reproject_raster
48+
- climada.hazard.base.Hazard.set_vector
49+
- climada.hazard.base.Hazard.vector_to_raster
50+
- climada.hazard.centroids.centr.Centroids.calc_pixels_polygons
51+
- climada.hazard.centroids.centr.Centroids.check
52+
- climada.hazard.centroids.centr.Centroids.clear
53+
- climada.hazard.centroids.centr.Centroids.equal
54+
- climada.hazard.centroids.centr.Centroids.from_mat
55+
- climada.hazard.centroids.centr.Centroids.from_base_grid
56+
- climada.hazard.centroids.centr.Centroids.read_excel
57+
- climada.hazard.centroids.centr.Centroids.read_hdf5
58+
- climada.hazard.centroids.centr.Centroids.read_mat
59+
- climada.hazard.centroids.centr.Centroids.set_elevation
60+
- climada.hazard.centroids.centr.Centroids.set_geometry_points
61+
- climada.hazard.centroids.centr.Centroids.set_lat_lon
62+
- climada.hazard.centroids.centr.Centroids.set_raster_file
63+
- climada.hazard.centroids.centr.Centroids.set_raster_from_pnt_bounds
64+
- climada.hazard.centroids.centr.Centroids.set_vector_file
65+
- climada.hazard.centroids.centr.Centroids.values_from_raster_files
66+
- climada.hazard.centroids.centr.Centroids.values_from_vector_files
67+
- climada.hazard.centroids.centr.generate_nat_earth_centroids
68+
2369
## 4.1.1
2470

2571
Release date: 2024-02-21

climada/engine/forecast.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from matplotlib.ticker import PercentFormatter, ScalarFormatter
3232
from matplotlib.colors import ListedColormap, BoundaryNorm
3333
import cartopy.crs as ccrs
34+
from matplotlib import colormaps as cm
3435
import pyproj
3536
import shapely
3637
from cartopy.io import shapereader
@@ -88,7 +89,7 @@
8889
warnprob_colors_extended = np.repeat(warnprob_colors, 10, axis=0)
8990
CMAP_WARNPROB = ListedColormap(warnprob_colors_extended)
9091
# colors for impact forecast
91-
color_map_pre = plt.get_cmap("plasma", 90)
92+
color_map_pre = cm.get_cmap("plasma").resampled(90)
9293
impact_colors = color_map_pre(np.linspace(0, 1, 90))
9394
white_extended = np.repeat([[255 / 255, 255 / 255, 255 / 255, 1]], 10, axis=0)
9495
impact_colors_extended = np.append(white_extended, impact_colors, axis=0)

climada/engine/impact_calc.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def impact(self, save_mat=True, assign_centroids=True,
112112
apply_deductible_to_mat : apply deductible to impact matrix
113113
apply_cover_to_mat : apply cover to impact matrix
114114
"""
115-
# check for compability of exposures and hazard type
115+
# check for compatibility of exposures and hazard type
116116
if all(name not in self.exposures.gdf.columns for
117117
name in ['if_', f'if_{self.hazard.haz_type}',
118118
'impf_', f'impf_{self.hazard.haz_type}']):
@@ -121,14 +121,28 @@ def impact(self, save_mat=True, assign_centroids=True,
121121
f"for hazard type {self.hazard.haz_type} in exposures."
122122
)
123123

124-
# check for compability of impact function and hazard type
124+
# check for compatibility of impact function and hazard type
125125
if not self.impfset.get_func(haz_type=self.hazard.haz_type):
126126
raise AttributeError(
127127
"Impact calculation not possible. No impact functions found "
128128
f"for hazard type {self.hazard.haz_type} in impf_set."
129129
)
130130

131131
impf_col = self.exposures.get_impf_column(self.hazard.haz_type)
132+
known_impact_functions = self.impfset.get_ids(haz_type=self.hazard.haz_type)
133+
134+
# check for compatibility of impact function id between impact function set and exposure
135+
if not all(self.exposures.gdf[impf_col].isin(known_impact_functions)):
136+
unknown_impact_functions = list(self.exposures.gdf[
137+
~self.exposures.gdf[impf_col].isin(known_impact_functions)
138+
][impf_col].drop_duplicates().astype(int).astype(str))
139+
raise ValueError(
140+
f"The associated impact function(s) with id(s) "
141+
f"{', '.join(unknown_impact_functions)} have no match in impact function set for"
142+
f" hazard type \'{self.hazard.haz_type}\'.\nPlease make sure that all exposure "
143+
"points are associated with an impact function that is included in the impact "
144+
"function set.")
145+
132146
exp_gdf = self.minimal_exp_gdf(impf_col, assign_centroids, ignore_cover, ignore_deductible)
133147
if exp_gdf.size == 0:
134148
return self._return_empty(save_mat)

climada/engine/test/test_cost_benefit.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,15 @@
3535
from climada.test import get_test_file
3636

3737

38-
HAZ_TEST_MAT = get_test_file('atl_prob_no_name', file_format='matlab')
3938
ENT_TEST_MAT = get_test_file('demo_today', file_format='MAT-file')
40-
39+
HAZ_TEST_TC :Path = get_test_file('test_tc_florida')
4140

4241
class TestSteps(unittest.TestCase):
4342
"""Test intermediate steps"""
4443
def test_calc_impact_measures_pass(self):
4544
"""Test _calc_impact_measures against reference value"""
46-
self.assertTrue(HAZ_TEST_MAT.is_file(), "{} is not a file".format(HAZ_TEST_MAT))
47-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
45+
self.assertTrue(HAZ_TEST_TC.is_file(), "{} is not a file".format(HAZ_TEST_TC))
46+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
4847

4948
self.assertTrue(ENT_TEST_MAT.is_file(), "{} is not a file".format(ENT_TEST_MAT))
5049
entity = Entity.from_mat(ENT_TEST_MAT)
@@ -230,7 +229,7 @@ def test_cb_one_meas_fut_pass(self):
230229

231230
def test_calc_cb_no_change_pass(self):
232231
"""Test _calc_cost_benefit without present value against reference value"""
233-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
232+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
234233
entity = Entity.from_mat(ENT_TEST_MAT)
235234
entity.measures._data['TC'] = entity.measures._data.pop('XX')
236235
for meas in entity.measures.get_measure('TC'):
@@ -267,7 +266,7 @@ def test_calc_cb_no_change_pass(self):
267266

268267
def test_calc_cb_change_pass(self):
269268
"""Test _calc_cost_benefit with present value against reference value"""
270-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
269+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
271270
entity = Entity.from_mat(ENT_TEST_MAT)
272271
entity.measures._data['TC'] = entity.measures._data.pop('XX')
273272
for meas in entity.measures.get_measure('TC'):
@@ -438,7 +437,7 @@ def test_norm_value(self):
438437

439438
def test_combine_fut_pass(self):
440439
"""Test combine_measures with present and future"""
441-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
440+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
442441
entity = Entity.from_excel(ENT_DEMO_TODAY)
443442
entity.check()
444443
entity.exposures.ref_year = 2018
@@ -498,7 +497,7 @@ def test_combine_fut_pass(self):
498497

499498
def test_combine_current_pass(self):
500499
"""Test combine_measures with only future"""
501-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
500+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
502501
entity = Entity.from_excel(ENT_DEMO_TODAY)
503502
entity.check()
504503
entity.exposures.ref_year = 2018
@@ -538,7 +537,7 @@ def test_combine_current_pass(self):
538537

539538
def test_apply_transf_current_pass(self):
540539
"""Test apply_risk_transfer with only future"""
541-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
540+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
542541
entity = Entity.from_excel(ENT_DEMO_TODAY)
543542
entity.check()
544543
entity.exposures.ref_year = 2018
@@ -588,7 +587,7 @@ def test_apply_transf_current_pass(self):
588587

589588
def test_apply_transf_cost_fact_pass(self):
590589
"""Test apply_risk_transfer with only future annd cost factor"""
591-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
590+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
592591
entity = Entity.from_excel(ENT_DEMO_TODAY)
593592
entity.check()
594593
entity.exposures.ref_year = 2018
@@ -636,7 +635,7 @@ def test_apply_transf_cost_fact_pass(self):
636635

637636
def test_apply_transf_future_pass(self):
638637
"""Test apply_risk_transfer with present and future"""
639-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
638+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
640639
entity = Entity.from_excel(ENT_DEMO_TODAY)
641640
entity.check()
642641
entity.exposures.ref_year = 2018
@@ -692,7 +691,7 @@ def test_apply_transf_future_pass(self):
692691

693692
def test_remove_measure(self):
694693
"""Test remove_measure method"""
695-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
694+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
696695
entity = Entity.from_excel(ENT_DEMO_TODAY)
697696
entity.check()
698697
entity.exposures.ref_year = 2018
@@ -720,7 +719,7 @@ class TestCalc(unittest.TestCase):
720719
def test_calc_change_pass(self):
721720
"""Test calc with future change"""
722721
# present
723-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
722+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
724723
entity = Entity.from_excel(ENT_DEMO_TODAY)
725724
entity.exposures.gdf.rename(columns={'impf_': 'impf_TC'}, inplace=True)
726725
entity.check()
@@ -777,7 +776,7 @@ def test_calc_change_pass(self):
777776

778777
def test_calc_no_change_pass(self):
779778
"""Test calc without future change"""
780-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
779+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
781780
entity = Entity.from_excel(ENT_DEMO_TODAY)
782781
entity.check()
783782
entity.exposures.ref_year = 2018
@@ -808,7 +807,7 @@ class TestRiskFuncs(unittest.TestCase):
808807
def test_impact(self):
809808
ent = Entity.from_excel(ENT_DEMO_TODAY)
810809
ent.check()
811-
hazard = Hazard.from_mat(HAZ_TEST_MAT)
810+
hazard = Hazard.from_hdf5(HAZ_TEST_TC)
812811
impact = ImpactCalc(ent.exposures, ent.impact_funcs, hazard).impact()
813812
return impact
814813

climada/engine/test/test_forecast.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,12 @@ def test_Forecast_plot(self):
110110
HAZ_DIR.joinpath('storm_europe_cosmoe_forecast_vmax_testfile.nc'),
111111
run_datetime=dt.datetime(2018,1,1),
112112
event_date=dt.datetime(2018,1,3))
113-
haz1.centroids.lat += 0.6
114-
haz1.centroids.lon -= 1.2
113+
haz1.centroids.gdf.geometry = haz1.centroids.gdf.geometry.translate(-1.2, 0.6)
115114
haz2 = StormEurope.from_cosmoe_file(
116115
HAZ_DIR.joinpath('storm_europe_cosmoe_forecast_vmax_testfile.nc'),
117116
run_datetime=dt.datetime(2018,1,1),
118117
event_date=dt.datetime(2018,1,3))
119-
haz2.centroids.lat += 0.6
120-
haz2.centroids.lon -= 1.2
118+
haz2.centroids.gdf.geometry = haz2.centroids.gdf.geometry.translate(-1.2, 0.6)
121119
#exposure
122120
data = {}
123121
data['latitude'] = haz1.centroids.lat

climada/engine/test/test_impact_calc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,26 @@ def test_error_handling_mismatch_haz_type(self):
135135
except Exception as e:
136136
self.assertEqual(str(e), "Impact calculation not possible. No impact "
137137
"functions found for hazard type TC in impf_set.")
138+
def test_error_handling_mismatch_impf_ids(self):
139+
"""Test error handling in case impf ids in exposures
140+
does not appear in impf_set"""
141+
haz = Hazard('TC')
142+
exp = Exposures()
143+
exp.gdf.loc[0,'impf_TC'] = 1
144+
exp.gdf.loc[1,'impf_TC'] = 2
145+
impf_exp = ImpactFunc(haz_type='TC', id=1)
146+
impf_noexp = deepcopy(impf_exp)
147+
impf_noexp.id = 3
148+
impfset = ImpactFuncSet([impf_exp, impf_noexp])
149+
150+
with self.assertRaises(ValueError) as cm:
151+
ImpactCalc(exp, impfset, haz).impact()
152+
the_exception = cm.exception
153+
self.assertEqual(the_exception.args[0],
154+
"The associated impact function(s) with id(s) 2 have no match in "
155+
"impact function set for hazard type \'TC\'.\nPlease make sure "
156+
"that all exposure points are associated with an impact "
157+
"function that is included in the impact function set.")
138158

139159
def test_calc_impact_TC_pass(self):
140160
"""Test compute impact"""

climada/engine/unsequa/unc_output.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import numpy as np
3434
import matplotlib.pyplot as plt
3535
import matplotlib as mpl
36+
from matplotlib import colormaps as cm
3637

3738
from climada import CONFIG
3839

@@ -1034,7 +1035,7 @@ def plot_sensitivity_map(self, salib_si='S1', **kwargs):
10341035
if len(n) > 0 :
10351036
n = n[0]
10361037
cmap = mpl.colors.ListedColormap(
1037-
plt.get_cmap(MAP_CMAP).colors[:len(labels)]
1038+
cm.get_cmap(MAP_CMAP).colors[:len(labels)]
10381039
)
10391040
colors = list(cmap.colors)
10401041
colors[n] = tuple(np.repeat(0.93, 3))

0 commit comments

Comments
 (0)