From 9bbe1e3c8c9b51890d6bfff7c53b1929adbe02d3 Mon Sep 17 00:00:00 2001 From: John Vouvakis Manousakis Date: Sat, 18 May 2024 11:51:19 -0700 Subject: [PATCH] Properly handle the case of no losses when aggregating. Loss model: make `aggregate_losses` return a DataFrame with zeros. --- pelicun/model/loss_model.py | 19 ++++++++++--------- pelicun/tests/model/test_loss_model.py | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/pelicun/model/loss_model.py b/pelicun/model/loss_model.py index d055210e7..1fe54229d 100644 --- a/pelicun/model/loss_model.py +++ b/pelicun/model/loss_model.py @@ -537,25 +537,26 @@ def aggregate_losses(self): for model in self._loss_models if model.sample is not None ] - if not samples: - self.log.msg("There are no losses.") - return None - - sample = pd.concat(samples, axis=1) - - # group results by DV type and location - aggregated = sample.groupby(level=['dv', 'loc'], axis=1).sum() # Note: The `Time` DV receives special treatment. - # create the summary DF columns = [ f'repair_{x.lower()}' for x in self.decision_variables if x != 'Time' ] if 'Time' in self.decision_variables: columns.extend(('repair_time-sequential', 'repair_time-parallel')) + + if not samples: + self.log.msg("There are no losses.") + df_agg = pd.DataFrame(0.00, index=[0], columns=columns) + return df_agg + + sample = pd.concat(samples, axis=1) df_agg = pd.DataFrame(index=sample.index, columns=columns) + # group results by DV type and location + aggregated = sample.groupby(level=['dv', 'loc'], axis=1).sum() + for decision_variable in self.decision_variables: # Time .. diff --git a/pelicun/tests/model/test_loss_model.py b/pelicun/tests/model/test_loss_model.py index 6f985094c..068cf3427 100644 --- a/pelicun/tests/model/test_loss_model.py +++ b/pelicun/tests/model/test_loss_model.py @@ -255,6 +255,25 @@ def test__ensure_loss_parameter_availability(self, assessment_instance): "[('consequence_E', 'DecisionVariableXYZ')]" ) in str(record[0].message) + def test_aggregate_losses_when_no_loss(self, assessment_instance): + + # tests that aggregate losses works when there is no loss. + loss_model = LossModel(assessment_instance) + df_agg = loss_model.aggregate_losses() + pd.testing.assert_frame_equal( + df_agg, + pd.DataFrame( + { + 'repair_carbon': 0.0, + 'repair_cost': 0.00, + 'repair_energy': 0.00, + 'repair_time-sequential': 0.00, + 'repair_time-parallel': 0.00, + }, + index=[0], + ), + ) + class TestRepairModel_Base(TestPelicunModel): def test___init__(self, assessment_instance):