Skip to content

Commit d2f035f

Browse files
committed
update tests using pytest
1 parent db32170 commit d2f035f

File tree

1 file changed

+110
-107
lines changed

1 file changed

+110
-107
lines changed

climada/engine/test/test_impact_calc.py

Lines changed: 110 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import geopandas as gpd
2828
import numpy as np
2929
import pandas as pd
30+
import pytest
3031
from scipy import sparse
3132

3233
from climada import CONFIG
@@ -49,6 +50,88 @@
4950
DATA_FOLDER.mkdir(exist_ok=True)
5051

5152

53+
@pytest.fixture(autouse=True)
54+
def exposure_fixture():
55+
n_exp = 50
56+
lats = np.linspace(-10, 10, n_exp)
57+
lons = np.linspace(-10, 10, n_exp)
58+
data = gpd.GeoDataFrame(
59+
{
60+
"impf_TC": 1,
61+
"value": 1,
62+
},
63+
index=range(n_exp),
64+
geometry=gpd.points_from_xy(lons, lats),
65+
crs="EPSG:4326",
66+
)
67+
exposures = Exposures(data=data)
68+
return exposures
69+
70+
71+
@pytest.fixture(autouse=True)
72+
def hazard_fixture(exposure_fixture):
73+
n_events = 10
74+
centroids = Centroids(
75+
lat=exposure_fixture.gdf.geometry.x,
76+
lon=exposure_fixture.gdf.geometry.y,
77+
)
78+
intensity = (
79+
np.ones((n_events, exposure_fixture.gdf.shape[0])) * 50
80+
) # uniform intensity
81+
haz = Hazard()
82+
haz.haz_type = "TC"
83+
haz.centroids = centroids
84+
haz.intensity = intensity
85+
haz.frequency = 1 / 10 * np.ones(n_events) # uniform frequency (10 n_events)
86+
return haz
87+
88+
89+
@pytest.fixture(autouse=True)
90+
def hazard_forecast_fixture(hazard_fixture):
91+
n_events = hazard_fixture.size
92+
lead_time = pd.timedelta_range("1h", periods=n_events).to_numpy()
93+
member = np.arange(10)
94+
haz_fc = HazardForecast.from_hazard(
95+
hazard=hazard_fixture,
96+
lead_time=lead_time,
97+
member=member,
98+
)
99+
return haz_fc
100+
101+
102+
@pytest.fixture(autouse=True)
103+
def impact_func_set_fixture(exposure_fixture, hazard_fixture):
104+
step_impf = ImpactFunc()
105+
step_impf.id = exposure_fixture.data[f"impf_{hazard_fixture.haz_type}"].unique()[0]
106+
step_impf.haz_type = hazard_fixture.haz_type
107+
step_impf.name = "fixture step function"
108+
step_impf.intensity_unit = ""
109+
step_impf.intensity = np.array([0, 0.495, 0.4955, 0.5, 1, 10])
110+
step_impf.mdd = np.array([0, 0, 0, 1, 1, 1])
111+
step_impf.paa = np.sort(np.linspace(1, 1, num=6))
112+
return ImpactFuncSet([step_impf])
113+
114+
115+
@pytest.fixture(autouse=True)
116+
def impact_calc_fixture(exposure_fixture, hazard_fixture, impact_func_set_fixture):
117+
imp_mat = np.ones(
118+
(
119+
len(hazard_fixture.event_id),
120+
exposure_fixture.gdf.shape[0],
121+
exposure_fixture.gdf.shape[0],
122+
)
123+
)
124+
aai_agg = np.sum(exposure_fixture.gdf["value"]) * hazard_fixture.frequency[0]
125+
eai_exp = np.ones(exposure_fixture.gdf.shape[0]) * hazard_fixture.frequency[0]
126+
at_event = np.ones(hazard_fixture.size) * np.sum(exposure_fixture.gdf["value"])
127+
return {
128+
"imp_mat": imp_mat,
129+
"aai_agg": aai_agg,
130+
"eai_exp": eai_exp,
131+
"at_event": at_event,
132+
}
133+
134+
52135
def check_impact(self, imp, haz, exp, aai_agg, eai_exp, at_event, imp_mat_array=None):
53136
"""Test properties of impacts"""
54137
self.assertEqual(len(haz.event_id), len(imp.at_event))
@@ -609,108 +692,34 @@ def test_single_exp_zero_mdr(self):
609692
check_impact(self, imp, haz, exp, aai_agg, eai_exp, at_event, at_event)
610693

611694

612-
class TestImpactCalcForecast(unittest.TestCase):
695+
class TestImpactCalcForecast:
613696
"""Test impact calc for forecast hazard"""
614697

615-
def test_impactForecast(self):
698+
def test_impactForecast_type(
699+
exposure_fixture,
700+
hazard_forecast_fixture,
701+
impact_func_set_fixture,
702+
impact_calc_fixture,
703+
):
616704
"""Test that ImpactForecast is returned correctly"""
617-
lead_time = pd.timedelta_range("1h", periods=6).to_numpy()
618-
member = np.arange(6)
619-
_haz = Hazard.from_hdf5(get_test_file("test_hazard_US_flood_random_locations"))
620-
haz_fc = HazardForecast.from_hazard(_haz, lead_time=lead_time, member=member)
621705

622-
exp = Exposures.from_hdf5(
623-
get_test_file("test_exposure_US_flood_random_locations")
624-
)
625-
impf_set = ImpactFuncSet.from_excel(
626-
Path(__file__).parent / "data" / "flood_imp_func_set.xls"
627-
)
628-
icalc = ImpactCalc(exp, impf_set, haz_fc)
629-
impact = icalc.impact(assign_centroids=False)
630-
aai_agg = 161436.05112960344
631-
eai_exp = np.array(
632-
[
633-
1.61159701e05,
634-
1.33742847e02,
635-
0.00000000e00,
636-
4.21352988e-01,
637-
1.42185609e02,
638-
0.00000000e00,
639-
0.00000000e00,
640-
0.00000000e00,
641-
]
642-
)
643-
at_event = np.array(
644-
[
645-
0.00000000e00,
646-
0.00000000e00,
647-
9.85233619e04,
648-
3.41245461e04,
649-
7.73566566e07,
650-
0.00000000e00,
651-
0.00000000e00,
652-
]
653-
)
654-
# fmt: off
655-
imp_mat_array = np.array(
656-
[
657-
[
658-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
659-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
660-
],
661-
[
662-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
663-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
664-
],
665-
[
666-
0.00000000e00, 6.41965663e04, 0.00000000e00, 2.02249434e02,
667-
3.41245461e04, 0.00000000e00, 0.00000000e00, 0.00000000e00,
668-
],
669-
[
670-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
671-
3.41245461e04, 0.00000000e00, 0.00000000e00, 0.00000000e00,
672-
],
673-
[
674-
7.73566566e07, 0.00000000e00, 0.00000000e00, 0.00000000e00,
675-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
676-
],
677-
[
678-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
679-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
680-
],
681-
[
682-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
683-
0.00000000e00, 0.00000000e00, 0.00000000e00, 0.00000000e00,
684-
],
685-
]
686-
)
687-
# fmt: on
688-
check_impact(
689-
self, impact, haz_fc, exp, aai_agg, eai_exp, at_event, imp_mat_array
706+
# check that impact is indeed ImpactForecast
707+
assert isinstance(impact, ImpactForecast)
708+
np.testing.assert_array_equal(
709+
impact.lead_time, hazard_forecast_fixture.lead_time
690710
)
711+
assert impact.lead_time.dtype == hazard_forecast_fixture.lead_time.dtype
712+
np.testing.assert_array_equal(impact.member, hazard_forecast_fixture.member)
691713

692-
# additional test to check that impact is indeed ImpactForecast
693-
self.assertIsInstance(impact, ImpactForecast)
694-
np.testing.assert_array_equal(impact.lead_time, lead_time)
695-
self.assertIs(impact.lead_time.dtype, lead_time.dtype)
696-
np.testing.assert_array_equal(impact.member, member)
697-
698-
def test_impact_forecast_empty_impmat_error(self):
714+
def test_impact_forecast_empty_impmat_error(
715+
hazard_forecast_fixture, exposure_fixture, impact_func_set_fixture
716+
):
699717
"""Test that error is raised when trying to compute impact forecast
700718
without saving impact matrix
701719
"""
702-
lead_time = pd.timedelta_range("1h", periods=6).to_numpy()
703-
member = np.arange(6)
704-
_haz = Hazard.from_hdf5(get_test_file("test_hazard_US_flood_random_locations"))
705-
haz_fc = HazardForecast.from_hazard(_haz, lead_time=lead_time, member=member)
706-
707-
exp = Exposures.from_hdf5(
708-
get_test_file("test_exposure_US_flood_random_locations")
709-
)
710-
impf_set = ImpactFuncSet.from_excel(
711-
Path(__file__).parent / "data" / "flood_imp_func_set.xls"
720+
icalc = ImpactCalc(
721+
exposure_fixture, impact_func_set_fixture, hazard_forecast_fixture
712722
)
713-
icalc = ImpactCalc(exp, impf_set, haz_fc)
714723
with self.assertRaises(ValueError) as cm:
715724
icalc.impact(assign_centroids=False, save_mat=False)
716725
no_impmat_exception = cm.exception
@@ -720,25 +729,19 @@ def test_impact_forecast_empty_impmat_error(self):
720729
"Please set save_mat=True.",
721730
)
722731

723-
def test_impact_forecast_blocked_nonsense_attrs(self):
732+
def test_impact_forecast_blocked_nonsense_attrs(
733+
hazard_forecast_fixture, exposure_fixture, impact_func_set_fixture
734+
):
724735
"""Test that nonsense attributes are blocked when computing impact forecast"""
725-
lead_time = pd.timedelta_range("1h", periods=6).to_numpy()
726-
member = np.arange(6)
727-
haz = Hazard.from_hdf5(get_test_file("test_hazard_US_flood_random_locations"))
728-
haz_fc = HazardForecast.from_hazard(haz, lead_time=lead_time, member=member)
736+
lead_time = hazard_fixture.lead_time
737+
member = hazard_fixture.member
729738

730-
exp = Exposures.from_hdf5(
731-
get_test_file("test_exposure_US_flood_random_locations")
732-
)
733-
impf_set = ImpactFuncSet.from_excel(
734-
Path(__file__).parent / "data" / "flood_imp_func_set.xls"
735-
)
736-
impact = ImpactCalc(exp, impf_set, haz_fc).impact(
737-
assign_centroids=False, save_mat=True
738-
)
739+
impact = ImpactCalc(
740+
exposure_fixture, impact_func_set_fixture, hazard_forecast_fixture
741+
).impact(assign_centroids=True, save_mat=True)
739742
assert np.isnan(impact.aai_agg)
740743
assert np.all(np.isnan(impact.eai_exp))
741-
assert impact.eai_exp.shape == (len(exp.gdf),)
744+
assert impact.eai_exp.shape == (len(exposure_fixture.gdf),)
742745

743746

744747
class TestImpactMatrixCalc(unittest.TestCase):

0 commit comments

Comments
 (0)