From 396239aba9a4bbbf12fa8ba723a679773d8ebd44 Mon Sep 17 00:00:00 2001 From: Chahan Kropf Date: Tue, 9 Dec 2025 13:10:26 +0100 Subject: [PATCH 1/6] Add extended select impact forecast test --- climada/engine/test/test_impact_forecast.py | 47 ++++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/climada/engine/test/test_impact_forecast.py b/climada/engine/test/test_impact_forecast.py index 0d421152c2..8f18e2ca53 100644 --- a/climada/engine/test/test_impact_forecast.py +++ b/climada/engine/test/test_impact_forecast.py @@ -86,14 +86,49 @@ def test_impact_forecast_from_impact( def test_impact_forecast_select(impact_forecast, lead_time, member, impact_kwargs): """Check if Impact.select works on the derived class""" - event_ids = impact_kwargs["event_id"][np.array([2, 0])] - impact_fc = impact_forecast.select(event_ids=event_ids) - # NOTE: Events keep their original order + select_mask = np.array([1, 2]) + ordered_select_mask = np.array([1, 2]) + vars_to_select = { + "event_id": "event_ids", + "event_name": "event_names", + "date": "dates", + } + + for var, var_select in vars_to_select.items(): + var_value = np.array(impact_kwargs[var])[select_mask] + # event_name is a list, convert to numpy array for indexing + impact_fc = impact_forecast.select(**{var_select: var_value}) + # NOTE: Events keep their original order + npt.assert_array_equal( + impact_fc.event_id, + impact_forecast.event_id[ordered_select_mask], + ) + npt.assert_array_equal( + impact_fc.event_name, + np.array(impact_forecast.event_name)[ordered_select_mask], + ) + npt.assert_array_equal( + impact_fc.date, impact_forecast.date[ordered_select_mask] + ) + npt.assert_array_equal( + impact_fc.frequency, impact_forecast.frequency[ordered_select_mask] + ) + npt.assert_array_equal(impact_fc.member, member[ordered_select_mask]) + npt.assert_array_equal(impact_fc.lead_time, lead_time[ordered_select_mask]) + npt.assert_array_equal( + impact_fc.imp_mat.todense(), + impact_forecast.imp_mat.todense()[ordered_select_mask], + ) + + exp_col = 0 + select_mask = np.array([exp_col]) + coord_exp = impact_kwargs["coord_exp"][select_mask] + impact_fc = impact_forecast.select(coord_exp=coord_exp) + npt.assert_array_equal(impact_fc.member, member) + npt.assert_array_equal(impact_fc.lead_time, lead_time) npt.assert_array_equal( - impact_fc.event_id, impact_forecast.event_id[np.array([0, 2])] + impact_fc.imp_mat.todense(), impact_forecast.imp_mat.todense()[:, exp_col] ) - npt.assert_array_equal(impact_fc.member, member[np.array([0, 2])]) - npt.assert_array_equal(impact_fc.lead_time, lead_time[np.array([0, 2])]) @pytest.mark.skip("Concat from base class does not work") From 260dfc2bdbd6a0fc6ded96a4d8496140541a79eb Mon Sep 17 00:00:00 2001 From: Chahan Kropf Date: Tue, 9 Dec 2025 14:02:26 +0100 Subject: [PATCH 2/6] Add extended hazard forecast test --- climada/hazard/test/test_forecast.py | 49 ++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/climada/hazard/test/test_forecast.py b/climada/hazard/test/test_forecast.py index 646ccaa0cf..969c1c2dd8 100644 --- a/climada/hazard/test/test_forecast.py +++ b/climada/hazard/test/test_forecast.py @@ -100,10 +100,47 @@ def test_hazard_forecast_concat(haz_fc, lead_time, member): npt.assert_array_equal(haz_fc_concat.member, np.concatenate([member, member])) -def test_hazard_forecast_select(haz_fc, lead_time, member): +def test_hazard_forecast_select(haz_fc, lead_time, member, haz_kwargs): """Check if Hazard.select works on the derived class""" - haz_fc_select = haz_fc.select(event_id=[4, 1]) - # NOTE: Events keep their original order - npt.assert_array_equal(haz_fc_select.event_id, haz_fc.event_id[np.array([3, 0])]) - npt.assert_array_equal(haz_fc_select.member, member[np.array([3, 0])]) - npt.assert_array_equal(haz_fc_select.lead_time, lead_time[np.array([3, 0])]) + # haz_fc_select = haz_fc.select(event_id=[4, 1]) + # # NOTE: Events keep their original order + # npt.assert_array_equal(haz_fc_select.event_id, haz_fc.event_id[np.array([3, 0])]) + # npt.assert_array_equal(haz_fc_select.member, member[np.array([3, 0])]) + # npt.assert_array_equal(haz_fc_select.lead_time, lead_time[np.array([3, 0])]) + + select_mask = np.array([2, 3]) + ordered_select_mask = np.array([2, 3]) + vars_to_select = { + "event_id": "event_id", + "event_name": "event_names", + "date": "date", + } + + for var, var_select in vars_to_select.items(): + var_value = np.array(haz_kwargs[var])[select_mask] + # event_name is a list, convert to numpy array for indexing + haz_fc_sel = haz_fc.select(**{var_select: var_value}) + npt.assert_array_equal( + haz_fc_sel.event_id, + haz_fc.event_id[ordered_select_mask], + ) + npt.assert_array_equal( + haz_fc_sel.event_name, + np.array(haz_fc.event_name)[ordered_select_mask], + ) + npt.assert_array_equal(haz_fc_sel.date, haz_fc.date[ordered_select_mask]) + npt.assert_array_equal( + haz_fc_sel.frequency, haz_fc.frequency[ordered_select_mask] + ) + npt.assert_array_equal(haz_fc_sel.member, member[ordered_select_mask]) + npt.assert_array_equal(haz_fc_sel.lead_time, lead_time[ordered_select_mask]) + npt.assert_array_equal( + haz_fc_sel.intensity.todense(), + haz_fc.intensity.todense()[ordered_select_mask], + ) + npt.assert_array_equal( + haz_fc_sel.fraction.todense(), + haz_fc.fraction.todense()[ordered_select_mask], + ) + + assert haz_fc_sel.centroids == haz_fc.centroids From d7084ce2883ecc6bec3ff51aebc591306c7a8f79 Mon Sep 17 00:00:00 2001 From: "Chahan M. Kropf" Date: Tue, 9 Dec 2025 14:24:13 +0100 Subject: [PATCH 3/6] Update climada/hazard/test/test_forecast.py Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com> --- climada/hazard/test/test_forecast.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/climada/hazard/test/test_forecast.py b/climada/hazard/test/test_forecast.py index 969c1c2dd8..a55a98cf39 100644 --- a/climada/hazard/test/test_forecast.py +++ b/climada/hazard/test/test_forecast.py @@ -102,11 +102,6 @@ def test_hazard_forecast_concat(haz_fc, lead_time, member): def test_hazard_forecast_select(haz_fc, lead_time, member, haz_kwargs): """Check if Hazard.select works on the derived class""" - # haz_fc_select = haz_fc.select(event_id=[4, 1]) - # # NOTE: Events keep their original order - # npt.assert_array_equal(haz_fc_select.event_id, haz_fc.event_id[np.array([3, 0])]) - # npt.assert_array_equal(haz_fc_select.member, member[np.array([3, 0])]) - # npt.assert_array_equal(haz_fc_select.lead_time, lead_time[np.array([3, 0])]) select_mask = np.array([2, 3]) ordered_select_mask = np.array([2, 3]) From bf57de1fae69e8e82edfb6b48d93bc214bec1b00 Mon Sep 17 00:00:00 2001 From: "Chahan M. Kropf" Date: Tue, 9 Dec 2025 15:02:23 +0100 Subject: [PATCH 4/6] Update climada/hazard/test/test_forecast.py Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com> --- climada/hazard/test/test_forecast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/climada/hazard/test/test_forecast.py b/climada/hazard/test/test_forecast.py index a55a98cf39..60bc9263f8 100644 --- a/climada/hazard/test/test_forecast.py +++ b/climada/hazard/test/test_forecast.py @@ -103,7 +103,7 @@ def test_hazard_forecast_concat(haz_fc, lead_time, member): def test_hazard_forecast_select(haz_fc, lead_time, member, haz_kwargs): """Check if Hazard.select works on the derived class""" - select_mask = np.array([2, 3]) + select_mask = np.array([3, 2]) ordered_select_mask = np.array([2, 3]) vars_to_select = { "event_id": "event_id", From 9249e017de41b33574639c8477c7721e31254a74 Mon Sep 17 00:00:00 2001 From: "Chahan M. Kropf" Date: Tue, 9 Dec 2025 15:02:30 +0100 Subject: [PATCH 5/6] Update climada/engine/test/test_impact_forecast.py Co-authored-by: Lukas Riedel <34276446+peanutfun@users.noreply.github.com> --- climada/engine/test/test_impact_forecast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/climada/engine/test/test_impact_forecast.py b/climada/engine/test/test_impact_forecast.py index 8f18e2ca53..9b5c768956 100644 --- a/climada/engine/test/test_impact_forecast.py +++ b/climada/engine/test/test_impact_forecast.py @@ -86,7 +86,7 @@ def test_impact_forecast_from_impact( def test_impact_forecast_select(impact_forecast, lead_time, member, impact_kwargs): """Check if Impact.select works on the derived class""" - select_mask = np.array([1, 2]) + select_mask = np.array([2, 1]) ordered_select_mask = np.array([1, 2]) vars_to_select = { "event_id": "event_ids", From dd78facdaab3b082bf2eae642fedc6f910ad68a9 Mon Sep 17 00:00:00 2001 From: Chahan Kropf Date: Tue, 9 Dec 2025 15:40:59 +0100 Subject: [PATCH 6/6] Rewrite select test with test parameters --- climada/engine/test/test_impact_forecast.py | 71 +++++++++++--------- climada/hazard/test/test_forecast.py | 73 +++++++++++---------- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/climada/engine/test/test_impact_forecast.py b/climada/engine/test/test_impact_forecast.py index 9b5c768956..9e18658a4c 100644 --- a/climada/engine/test/test_impact_forecast.py +++ b/climada/engine/test/test_impact_forecast.py @@ -84,42 +84,49 @@ def test_impact_forecast_from_impact( self.assert_impact_kwargs(impact_forecast, **impact_kwargs) -def test_impact_forecast_select(impact_forecast, lead_time, member, impact_kwargs): +@pytest.mark.parametrize( + "var, var_select", + [("event_id", "event_ids"), ("event_name", "event_names"), ("date", "dates")], +) +def test_impact_forecast_select_events( + impact_forecast, lead_time, member, impact_kwargs, var, var_select +): """Check if Impact.select works on the derived class""" select_mask = np.array([2, 1]) ordered_select_mask = np.array([1, 2]) - vars_to_select = { - "event_id": "event_ids", - "event_name": "event_names", - "date": "dates", - } - - for var, var_select in vars_to_select.items(): - var_value = np.array(impact_kwargs[var])[select_mask] - # event_name is a list, convert to numpy array for indexing - impact_fc = impact_forecast.select(**{var_select: var_value}) - # NOTE: Events keep their original order - npt.assert_array_equal( - impact_fc.event_id, - impact_forecast.event_id[ordered_select_mask], - ) - npt.assert_array_equal( - impact_fc.event_name, - np.array(impact_forecast.event_name)[ordered_select_mask], - ) - npt.assert_array_equal( - impact_fc.date, impact_forecast.date[ordered_select_mask] - ) - npt.assert_array_equal( - impact_fc.frequency, impact_forecast.frequency[ordered_select_mask] - ) - npt.assert_array_equal(impact_fc.member, member[ordered_select_mask]) - npt.assert_array_equal(impact_fc.lead_time, lead_time[ordered_select_mask]) - npt.assert_array_equal( - impact_fc.imp_mat.todense(), - impact_forecast.imp_mat.todense()[ordered_select_mask], - ) + if var == "date": + # Date needs to be a valid delta + select_mask = np.array([1, 2]) + ordered_select_mask = np.array([1, 2]) + + var_value = np.array(impact_kwargs[var])[select_mask] + # event_name is a list, convert to numpy array for indexing + impact_fc = impact_forecast.select(**{var_select: var_value}) + # NOTE: Events keep their original order + npt.assert_array_equal( + impact_fc.event_id, + impact_forecast.event_id[ordered_select_mask], + ) + npt.assert_array_equal( + impact_fc.event_name, + np.array(impact_forecast.event_name)[ordered_select_mask], + ) + npt.assert_array_equal(impact_fc.date, impact_forecast.date[ordered_select_mask]) + npt.assert_array_equal( + impact_fc.frequency, impact_forecast.frequency[ordered_select_mask] + ) + npt.assert_array_equal(impact_fc.member, member[ordered_select_mask]) + npt.assert_array_equal(impact_fc.lead_time, lead_time[ordered_select_mask]) + npt.assert_array_equal( + impact_fc.imp_mat.todense(), + impact_forecast.imp_mat.todense()[ordered_select_mask], + ) + +def test_impact_forecast_select_exposure( + impact_forecast, lead_time, member, impact_kwargs +): + """Check if Impact.select works on the derived class""" exp_col = 0 select_mask = np.array([exp_col]) coord_exp = impact_kwargs["coord_exp"][select_mask] diff --git a/climada/hazard/test/test_forecast.py b/climada/hazard/test/test_forecast.py index 60bc9263f8..8b496934a4 100644 --- a/climada/hazard/test/test_forecast.py +++ b/climada/hazard/test/test_forecast.py @@ -100,42 +100,43 @@ def test_hazard_forecast_concat(haz_fc, lead_time, member): npt.assert_array_equal(haz_fc_concat.member, np.concatenate([member, member])) -def test_hazard_forecast_select(haz_fc, lead_time, member, haz_kwargs): +@pytest.mark.parametrize( + "var, var_select", + [("event_id", "event_id"), ("event_name", "event_names"), ("date", "date")], +) +def test_hazard_forecast_select(haz_fc, lead_time, member, haz_kwargs, var, var_select): """Check if Hazard.select works on the derived class""" select_mask = np.array([3, 2]) - ordered_select_mask = np.array([2, 3]) - vars_to_select = { - "event_id": "event_id", - "event_name": "event_names", - "date": "date", - } - - for var, var_select in vars_to_select.items(): - var_value = np.array(haz_kwargs[var])[select_mask] - # event_name is a list, convert to numpy array for indexing - haz_fc_sel = haz_fc.select(**{var_select: var_value}) - npt.assert_array_equal( - haz_fc_sel.event_id, - haz_fc.event_id[ordered_select_mask], - ) - npt.assert_array_equal( - haz_fc_sel.event_name, - np.array(haz_fc.event_name)[ordered_select_mask], - ) - npt.assert_array_equal(haz_fc_sel.date, haz_fc.date[ordered_select_mask]) - npt.assert_array_equal( - haz_fc_sel.frequency, haz_fc.frequency[ordered_select_mask] - ) - npt.assert_array_equal(haz_fc_sel.member, member[ordered_select_mask]) - npt.assert_array_equal(haz_fc_sel.lead_time, lead_time[ordered_select_mask]) - npt.assert_array_equal( - haz_fc_sel.intensity.todense(), - haz_fc.intensity.todense()[ordered_select_mask], - ) - npt.assert_array_equal( - haz_fc_sel.fraction.todense(), - haz_fc.fraction.todense()[ordered_select_mask], - ) - - assert haz_fc_sel.centroids == haz_fc.centroids + ordered_select_mask = np.array([3, 2]) + if var == "date": + # Date needs to be a valid delta + select_mask = np.array([2, 3]) + ordered_select_mask = np.array([2, 3]) + + var_value = np.array(haz_kwargs[var])[select_mask] + # event_name is a list, convert to numpy array for indexing + haz_fc_sel = haz_fc.select(**{var_select: var_value}) + # Note: order is preserved + npt.assert_array_equal( + haz_fc_sel.event_id, + haz_fc.event_id[ordered_select_mask], + ) + npt.assert_array_equal( + haz_fc_sel.event_name, + np.array(haz_fc.event_name)[ordered_select_mask], + ) + npt.assert_array_equal(haz_fc_sel.date, haz_fc.date[ordered_select_mask]) + npt.assert_array_equal(haz_fc_sel.frequency, haz_fc.frequency[ordered_select_mask]) + npt.assert_array_equal(haz_fc_sel.member, member[ordered_select_mask]) + npt.assert_array_equal(haz_fc_sel.lead_time, lead_time[ordered_select_mask]) + npt.assert_array_equal( + haz_fc_sel.intensity.todense(), + haz_fc.intensity.todense()[ordered_select_mask], + ) + npt.assert_array_equal( + haz_fc_sel.fraction.todense(), + haz_fc.fraction.todense()[ordered_select_mask], + ) + + assert haz_fc_sel.centroids == haz_fc.centroids