Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/622 adaptation calculate full link cost #623

Open
wants to merge 10 commits into
base: feat/595-adaptation-run-and-combine-losses-and-damages
Choose a base branch
from
10 changes: 5 additions & 5 deletions ra2ce/analysis/adaptation/adaptation.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def execute(self) -> GeoDataFrame:

def run_cost(self) -> GeoDataFrame:
"""
Calculate the unit cost for all adaptation options.
Calculate the link cost for all adaptation options.

Returns:
GeoDataFrame: The result of the cost calculation.
Expand All @@ -81,10 +81,10 @@ def run_cost(self) -> GeoDataFrame:
for (
_option,
_cost,
) in self.adaptation_collection.calculate_options_cost().items():
_cost_gdf[f"{_option.id}_cost"] = _cost

# TODO: calculate link cost instead of unit cost
) in self.adaptation_collection.calculate_options_unit_cost().items():
_cost_gdf[f"{_option.id}_cost"] = _cost_gdf.apply(
lambda x, cost=_cost: x["length"] * cost, axis=1
)

return _cost_gdf

Expand Down
2 changes: 1 addition & 1 deletion ra2ce/analysis/adaptation/adaptation_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def from_config(
analysis_config=analysis_config,
)

def calculate_cost(self, time_horizon: float, discount_rate: float) -> float:
def calculate_unit_cost(self, time_horizon: float, discount_rate: float) -> float:
"""
Calculate the net present value unit cost (per meter) of the adaptation option.
Expand Down
4 changes: 2 additions & 2 deletions ra2ce/analysis/adaptation/adaptation_option_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ def from_config(

return _collection

def calculate_options_cost(self) -> dict[AdaptationOption, float]:
def calculate_options_unit_cost(self) -> dict[AdaptationOption, float]:
"""
Calculate the unit cost for all adaptation options.
Returns:
dict[AdaptationOption, float]: The calculated cost for all adaptation options.
"""
return {
_option: _option.calculate_cost(
_option: _option.calculate_unit_cost(
self.time_horizon,
self.discount_rate,
)
Expand Down
2 changes: 1 addition & 1 deletion tests/analysis/adaptation/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class AdaptationOptionCases:
),
]
unit_cost: list[float] = [0.0, 2693.684211, 5231.908660]
total_cost: list[float] = [0.0, 633015.789583, 1229498.535112]
total_cost: list[float] = [0.0, 97411702.122141, 189201512.873560]
cases: list[tuple[AnalysisSectionAdaptationOption, float, float]] = list(
zip(config_cases, unit_cost, total_cost)
)
Expand Down
4 changes: 2 additions & 2 deletions tests/analysis/adaptation/test_adaptation_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_from_config_no_damages_losses_raises(self):
"adaptation_option",
AdaptationOptionCases.cases,
)
def test_calculate_option_cost_returns_float(
def test_calculate_unit_cost_returns_float(
self,
valid_adaptation_config: tuple[AnalysisInputWrapper, AnalysisConfigWrapper],
adaptation_option: tuple[AnalysisSectionAdaptation, float, float],
Expand All @@ -82,7 +82,7 @@ def test_calculate_option_cost_returns_float(
_discount_rate = valid_adaptation_config[1].config_data.adaptation.discount_rate

# 2. Run test.
_cost = _option.calculate_cost(_time_horizon, _discount_rate)
_cost = _option.calculate_unit_cost(_time_horizon, _discount_rate)

# 3. Verify expectations.
assert isinstance(_cost, float)
Expand Down
14 changes: 14 additions & 0 deletions tests/analysis/adaptation/test_adaptation_option_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,17 @@ def test_from_config_no_adaptation_raises(self):

# 3. Verify expectations.
assert _exc.match("No adaptation section found in the analysis config data.")

def test_calculate_options_unit_cost(
self,
valid_adaptation_config: tuple[AnalysisInputWrapper, AnalysisConfigWrapper],
):
# 1. Define test data.
_collection = AdaptationOptionCollection.from_config(valid_adaptation_config[1])

# 2. Run test.
_result = _collection.calculate_options_unit_cost()

# 3. Verify expectations.
assert isinstance(_result, dict)
assert all(_option in _result for _option in _collection.adaptation_options)
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from tests import acceptance_test_data


@pytest.fixture(name="valid_analysis_ini")
@pytest.fixture(name="valid_analysis_ini", scope="session")
def _get_valid_analysis_ini_fixture() -> Iterator[Path]:
_ini_file = acceptance_test_data.joinpath("analyses.ini")
assert _ini_file.exists()
Expand Down