From 986afaaee46b4fca9a53a14ccccc6c49916c719a Mon Sep 17 00:00:00 2001 From: spjuhel Date: Tue, 16 Jun 2026 16:24:44 +0200 Subject: [PATCH 1/3] Fixes a bug in eai metric --- climada/trajectories/calc_risk_metrics.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/climada/trajectories/calc_risk_metrics.py b/climada/trajectories/calc_risk_metrics.py index 39c0b8fca..56509c4fd 100644 --- a/climada/trajectories/calc_risk_metrics.py +++ b/climada/trajectories/calc_risk_metrics.py @@ -255,7 +255,12 @@ def calc_eai_gdf(self) -> pd.DataFrame: """ - metric_df = pd.DataFrame(self.per_date_eai, index=self._date_idx) + metric_df = pd.DataFrame( + self.per_date_eai, + index=self._date_idx, + columns=self.snapshots[0].exposure.gdf.index, + ) + metric_df = metric_df.reset_index().melt( id_vars=DATE_COL_NAME, var_name=COORD_ID_COL_NAME, value_name=RISK_COL_NAME ) @@ -868,7 +873,11 @@ def calc_eai_gdf(self) -> pd.DataFrame: (notably for `value` and `group_id`). """ - metric_df = pd.DataFrame(self.per_date_eai, index=self.date_idx) + metric_df = pd.DataFrame( + self.per_date_eai, + index=self._date_idx, + columns=self.snapshot_start.exposure.gdf.index, + ) metric_df = metric_df.reset_index().melt( id_vars=DEFAULT_PERIOD_INDEX_NAME, var_name=COORD_ID_COL_NAME, From d5ecbf93aee95db7488d72741afcd39cd7de6b0a Mon Sep 17 00:00:00 2001 From: spjuhel Date: Mon, 26 Oct 2026 15:57:28 +0100 Subject: [PATCH 2/3] Adds a specific index to exposure geodataframe --- climada/trajectories/test/conftest.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/climada/trajectories/test/conftest.py b/climada/trajectories/test/conftest.py index 57a1d3a27..5ff7e6a64 100644 --- a/climada/trajectories/test/conftest.py +++ b/climada/trajectories/test/conftest.py @@ -39,7 +39,8 @@ EXP_DESC = "Test exposure dataset" EXPOSURE_REF_YEAR = 2020 EXPOSURE_VALUE_UNIT = "USD" -VALUES = np.array([0, 1000, 2000, 3000, 4000, 5000]) +EXPOSURE_INDICES = np.array([0, 1, 2, 7, 8, 5]) +EXPOSURE_VALUES = np.array([0, 1000, 2000, 3000, 4000, 5000]) CATEGORIES = np.array([1, 1, 2, 1, 1, 3]) # Exposure coordinates @@ -60,7 +61,7 @@ # Hazard events EVENT_IDS = np.array([1, 2, 3, 4, 5]) EVENT_NAMES = ["ev1", "ev2", "ev3", "ev4", "ev5"] -DATES = np.array([1, 2, 3, 4, 5]) +DATES = np.array([1, 2, 7, 4, 5]) # Frequency are choosen so that they cumulate nicely # to correspond to 250, 100, 50, and 20y return periods (for impacts) @@ -80,9 +81,9 @@ IMPF_NAME = "IMPF_1" # Sanity checks -for const in [VALUES, CATEGORIES, EXP_LONS, EXP_LATS]: +for const in [EXPOSURE_VALUES, CATEGORIES, EXP_LONS, EXP_LATS]: assert len(const) == len( - VALUES + EXPOSURE_VALUES ), "VALUES, REGIONS, CATEGORIES, EXP_LONS, EXP_LATS should all have the same lengths." for const in [EVENT_IDS, EVENT_NAMES, DATES, FREQUENCY]: @@ -93,7 +94,7 @@ @pytest.fixture(scope="session") def exposure_values(): - return VALUES.copy() + return EXPOSURE_VALUES.copy() @pytest.fixture(scope="session") @@ -124,6 +125,7 @@ def _make_exposures( "geometry": exposure_geometry, }, crs=CRS_WGS84, + index=EXPOSURE_INDICES, ) if group_id is not None: gdf["group_id"] = group_id From 008d88984d8422b5b10102ca6ae72e5da6d8090b Mon Sep 17 00:00:00 2001 From: spjuhel Date: Mon, 26 Oct 2026 16:17:04 +0100 Subject: [PATCH 3/3] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b449f222..284d27408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Code freeze date: YYYY-MM-DD - `Hazard.from_raster_xarray` now returns a sparse matrix instead of a sparse array [#1261](https://github.com/CLIMADA-project/climada_python/pull/1261). - `ImpactCalc.impact` now raises a clear `ValueError` when the supplied `Hazard` contains no events, instead of failing later inside `np.array_split` with an obscure message [#814](https://github.com/CLIMADA-project/climada_python/issues/814). - Fix TCTracks.from_FAST duplicate loading from year loop [#1269](github.com/CLIMADA-project/climada_python/pull/1269) +- Fix a wrong computation of EAI in the `trajectory` module when the index of the `GeoDataFrame` of an Exposures object is not a 0 to n range. ### Deprecated - `Impact.calc_freq_curve()` should not be given the parameter `return_per`. Use the parameter `return_periods` in `Impact.calc_freq_curve().interpolate()` instead.