-
Notifications
You must be signed in to change notification settings - Fork 0
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
Tipping points #446
base: main
Are you sure you want to change the base?
Tipping points #446
Changes from all commits
5ceb865
b014275
da9249d
6dfae92
45ab27a
4d307a4
cf8d0c8
1e91d40
fd50713
34f4034
c2f1bfa
26ffea2
8a1a748
3ab3964
b44fba8
2ff6088
1f8f97c
9ce90fb
f028b87
e2f102c
15f63a7
fa09dbf
f108e9a
a4f8860
8bc416c
c1524ed
8f57e19
2a620bd
7f2b41d
0a398de
0522ab2
28df051
c7e59bc
4cec8c8
49477fb
bb29294
914708f
509f586
0d87a9b
beeb7d3
29a0eec
a65eccd
5394985
4767068
ad8cd88
971d7f6
a1d6f57
dacdb31
3360678
8170ddd
c6c53f6
a7b16b0
279ee5f
f638cde
231f84a
69a7ae0
4e35370
bc414fc
d9506c6
86821f4
81ecfcd
76b59f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from typing import Any | ||
|
||
from flood_adapt.dbs_controller import Database | ||
from flood_adapt.object_model.interface.tipping_points import ITipPoint | ||
from flood_adapt.object_model.tipping_point import TippingPoint | ||
|
||
|
||
def get_tipping_points() -> dict[str, Any]: | ||
# sorting and filtering either with PyQt table or in the API | ||
return Database().tipping_points.list_objects() | ||
|
||
|
||
def get_tipping_point(name: str) -> ITipPoint: | ||
return Database().tipping_points.get(name) | ||
|
||
|
||
def create_tipping_point(attrs: dict[str, Any]) -> ITipPoint: | ||
return TippingPoint.load_dict(attrs) | ||
|
||
|
||
def save_tipping_point(tipping_point: ITipPoint) -> None: | ||
Database().tipping_points.save(tipping_point) | ||
|
||
|
||
def edit_tipping_point(tipping_point: ITipPoint) -> None: | ||
Database().tipping_points.edit(tipping_point) | ||
|
||
|
||
def delete_tipping_point(name: str) -> None: | ||
Database().tipping_points.delete(name) | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed with Luuk that for now we run the TP functions directly from the API |
||
def create_tipping_point_scenarios(name: str) -> None: | ||
Database().tipping_points.get(name).create_tp_scenarios() | ||
|
||
|
||
def run_tipping_point(name: str) -> None: | ||
Database().tipping_points.get(name).run_tp_scenarios() | ||
|
||
|
||
def check_scenario_has_run(name: str) -> None: | ||
scenario_ran = Database().tipping_points.get(name).check_scenario_has_run() | ||
return scenario_ran |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import shutil | ||
|
||
from flood_adapt.dbs_classes.dbs_template import DbsTemplate | ||
from flood_adapt.object_model.interface.tipping_points import ITipPoint | ||
from flood_adapt.object_model.tipping_point import TippingPoint | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I based on the other codes and have not added other functionalities. Maybe we need to add the plots here? |
||
class DbsTippingPoint(DbsTemplate): | ||
_type = "tipping_point" | ||
_folder_name = "tipping_points" | ||
_object_model_class = TippingPoint | ||
|
||
def save(self, tipping_point: ITipPoint, overwrite: bool = False): | ||
"""Save a tipping point object in the database. | ||
|
||
Parameters | ||
---------- | ||
tipping_point : ITipPoint | ||
object of tipping point type | ||
overwrite : bool, optional | ||
whether to overwrite existing tipping point with same name, by default False | ||
|
||
Raises | ||
------ | ||
ValueError | ||
Raise error if name is already in use. Names of tipping points should be unique. | ||
""" | ||
# Save the tipping point | ||
super().save(tipping_point, overwrite=overwrite) | ||
|
||
def delete(self, name: str, toml_only: bool = False): | ||
"""Delete an already existing tipping point in the database. | ||
|
||
Parameters | ||
---------- | ||
name : str | ||
name of the tipping point | ||
toml_only : bool, optional | ||
whether to only delete the toml file or the entire folder. If the folder is empty after deleting the toml, | ||
it will always be deleted. By default False | ||
""" | ||
# First delete the tipping point | ||
super().delete(name, toml_only=toml_only) | ||
|
||
# Delete output if edited | ||
output_path = ( | ||
self._database.tipping_points.get_database_path(get_input_path=False) / name | ||
) | ||
|
||
if output_path.exists(): | ||
shutil.rmtree(output_path) | ||
|
||
def edit(self, tipping_point: ITipPoint): | ||
"""Edit an already existing tipping point in the database. | ||
|
||
Parameters | ||
---------- | ||
tipping_point : ITipPoint | ||
object of tipping point type | ||
""" | ||
# Edit the tipping point | ||
super().edit(tipping_point) | ||
|
||
# Delete output if edited | ||
output_path = ( | ||
self._database.tipping_points.get_database_path(get_input_path=False) | ||
/ tipping_point.attrs.name | ||
) | ||
|
||
if output_path.exists(): | ||
shutil.rmtree(output_path) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import os | ||
from abc import ABC, abstractmethod | ||
from enum import Enum | ||
from typing import Any, Optional, Union | ||
|
||
import pandas as pd | ||
from pydantic import BaseModel | ||
|
||
|
||
class TippingPointMetrics(str, Enum): | ||
"""class describing the accepted input for the variable metric_type in TippingPoint.""" | ||
|
||
# based on what I have found in floodadapt - but can be changed | ||
FloodedAll = "FloodedAll" | ||
FloodedLowVulnerability = "FloodedLowVulnerability" | ||
FloodedHighVulnerability = "FloodedHighVulnerability" | ||
TotalDamageEvent = "TotalDamageEvent" | ||
TotalResDamageEvent = "TotalResDamageEvent" | ||
ResidentialMinorCount = "ResidentialMinorCount" | ||
ResidentialMajorCount = "ResidentialMajorCount" | ||
ResidentialDestroyedCount = "ResidentialDestroyedCount" | ||
CommercialCount = "CommercialCount" | ||
CommercialMinorCount = "CommercialMinorCount" | ||
CommercialMajorCount = "CommercialMajorCount" | ||
CommercialDestroyedCount = "CommercialDestroyedCount" | ||
HealthCount = "HealthCount" | ||
HealthMinorCount = "HealthMinorCount" | ||
HealthMajorCount = "HealthMajorCount" | ||
HealthDestroyedCount = "HealthDestroyedCount" | ||
SchoolsCount = "SchoolsCount" | ||
SchoolsMinorCount = "SchoolsMinorCount" | ||
SchoolsMajorCount = "SchoolsMajorCount" | ||
SchoolsDestroyedCount = "SchoolsDestroyedCount" | ||
EmergencyCount = "EmergencyCount" | ||
EmergencyMinorCount = "EmergencyMinorCount" | ||
EmergencyMajorCount = "EmergencyMajorCount" | ||
EmergencyDestroyedCount = "EmergencyDestroyedCount" | ||
DisplacedLowVulnerability = "DisplacedLowVulnerability" | ||
DisplacedHighVulnerability = "DisplacedHighVulnerability" | ||
SlightlyFloodedRoads = "SlightlyFloodedRoads" | ||
MinorFloodedRoads = "MinorFloodedRoads" | ||
MajorFloodedRoads = "MajorFloodedRoads" | ||
FullyFloodedRoads = "FullyFloodedRoads" | ||
|
||
|
||
class TippingPointStatus(str, Enum): | ||
"""class describing the accepted input for the variable metric_type in TippingPoint.""" | ||
|
||
reached = "reached" | ||
not_reached = "not_reached" | ||
completed = "completed" | ||
|
||
|
||
class TippingPointOperator(str, Enum): | ||
"""class describing the accepted input for the variable operator in TippingPoint.""" | ||
|
||
greater = "greater" | ||
less = "less" | ||
|
||
|
||
class TippingPointModel(BaseModel): | ||
"""BaseModel describing the expected variables and data types of a Tipping Point analysis object.""" | ||
|
||
name: str | ||
description: Optional[str] = "" | ||
strategy: str | ||
event_set: str | ||
projection: str | ||
sealevelrise: list[float] # could be a numpy array too | ||
tipping_point_metric: list[tuple[TippingPointMetrics, float, TippingPointOperator]] | ||
status: TippingPointStatus = TippingPointStatus.not_reached | ||
scenarios: list[str] = [] | ||
|
||
|
||
class ITipPoint(ABC): | ||
attrs: TippingPointModel | ||
database_input_path: Union[str, os.PathLike] | ||
results_path: Union[str, os.PathLike] | ||
scenarios: pd.DataFrame | ||
has_run: bool = False | ||
|
||
@staticmethod | ||
@abstractmethod | ||
def load_file(filepath: Union[str, os.PathLike]): | ||
"""Get Tipping Point attributes from toml file.""" | ||
... | ||
|
||
@staticmethod # copping from benefits.py | ||
@abstractmethod | ||
def load_dict(data: dict[str, Any]): | ||
"""Get Tipping Point attributes from an object, e.g. when initialized from GUI.""" | ||
... | ||
|
||
@abstractmethod | ||
def save(self, filepath: Union[str, os.PathLike]): | ||
"""Save Tipping Point attributes to a toml file.""" | ||
... | ||
|
||
@abstractmethod | ||
def check_scenarios_exist(self) -> pd.DataFrame: | ||
"""Check which scenarios are needed for this tipping point calculation and if they have already been created.""" | ||
... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All based on the existing code, changing paths and variables.