Skip to content

Commit dc7d424

Browse files
authored
Merge pull request #948 from CLIMADA-project/bugfix/imp-calc-mdr-zeros
Bug fix in Hazard.get_mdr and impact calculation in case of a single exposure point and MDR values of 0
2 parents 2d4f771 + 4e917d3 commit dc7d424

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

CHANGELOG.md

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

2222
### Fixed
2323

24+
- Avoids a ValueError in the impact calculation for cases with a single exposure point and MDR values of 0, by explicitly removing zeros in `climada.hazard.Hazard.get_mdr` [#933](https://github.com/CLIMADA-project/climada_python/pull/948)
25+
2426
### Deprecated
2527

2628
### Removed

climada/engine/test/test_impact_calc.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828

2929
from climada import CONFIG
3030
from climada.entity.entity_def import Entity
31-
from climada.entity import Exposures, ImpactFuncSet, ImpactFunc
32-
from climada.hazard.base import Hazard
31+
from climada.entity import Exposures, ImpactFuncSet, ImpactFunc, ImpfTropCyclone
32+
from climada.hazard.base import Hazard, Centroids
3333
from climada.engine import ImpactCalc, Impact
3434
from climada.engine.impact_calc import LOGGER as ILOG
3535
from climada.util.constants import ENT_DEMO_TODAY, DEMO_DIR
@@ -471,6 +471,34 @@ def test_stitch_risk_metrics(self):
471471
np.testing.assert_array_equal(eai_exp, [2.25, 1.25, 4.5])
472472
self.assertEqual(aai_agg, 8.0) # Sum of eai_exp
473473

474+
def test_single_exp_zero_mdr(self):
475+
"""Test for case where exposure has a single value and MDR or fraction contains zeros"""
476+
centroids = Centroids.from_lat_lon([-26.16], [28.20])
477+
haz = Hazard(
478+
intensity=sparse.csr_matrix(np.array([[31.5], [19.0]])),
479+
event_id=np.arange(2),
480+
event_name=[0,1],
481+
frequency=np.ones(2) / 2,
482+
fraction=sparse.csr_matrix(np.zeros((2,1))),
483+
date=np.array([0, 1]),
484+
centroids=centroids,
485+
haz_type='TC'
486+
)
487+
exp = Exposures({'value': [1.],
488+
'longitude': 28.22,
489+
'latitude': -26.17,
490+
'impf_TC': 1},
491+
crs="EPSG:4326")
492+
imp_evt = 0.00250988804927603
493+
aai_agg = imp_evt/2
494+
eai_exp = np.array([aai_agg])
495+
at_event = np.array([imp_evt, 0])
496+
exp.set_geometry_points()
497+
impf_tc = ImpfTropCyclone.from_emanuel_usa()
498+
impf_set = ImpactFuncSet([impf_tc])
499+
impf_set.check()
500+
imp = ImpactCalc(exp, impf_set, haz).impact(save_mat=True)
501+
check_impact(self, imp, haz, exp, aai_agg, eai_exp, at_event, at_event)
474502

475503
class TestImpactMatrixCalc(unittest.TestCase):
476504
"""Verify the computation of the impact matrix"""

climada/hazard/base.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,9 @@ def get_mdr(self, cent_idx, impf):
11031103
impf.id)
11041104
mdr_array = impf.calc_mdr(mdr.toarray().ravel()).reshape(mdr.shape)
11051105
mdr = sparse.csr_matrix(mdr_array)
1106-
return mdr[:, indices]
1106+
mdr_out = mdr[:, indices]
1107+
mdr_out.eliminate_zeros()
1108+
return mdr_out
11071109

11081110
def get_paa(self, cent_idx, impf):
11091111
"""

climada/hazard/test/test_base.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,14 @@ def test_get_mdr(self):
11761176
true_mdr = np.digitize(haz.intensity[:, idx].toarray(), [0, 1])
11771177
np.testing.assert_array_almost_equal(mdr.toarray(), true_mdr)
11781178

1179+
# #case with zeros everywhere
1180+
cent_idx = np.array([0, 0, 1])
1181+
impf.mdd=np.array([0,0,0,1])
1182+
# how many non-zeros values are expected
1183+
num_nz_values = 5
1184+
mdr = haz.get_mdr(cent_idx, impf)
1185+
self.assertEqual(mdr.nnz, num_nz_values)
1186+
11791187
def test_get_paa(self):
11801188
haz = dummy_hazard()
11811189
impf = dummy_step_impf(haz)

0 commit comments

Comments
 (0)