flood-adapt 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. flood_adapt/__init__.py +22 -0
  2. flood_adapt/adapter/__init__.py +9 -0
  3. flood_adapt/adapter/fiat_adapter.py +1502 -0
  4. flood_adapt/adapter/interface/__init__.py +0 -0
  5. flood_adapt/adapter/interface/hazard_adapter.py +70 -0
  6. flood_adapt/adapter/interface/impact_adapter.py +36 -0
  7. flood_adapt/adapter/interface/model_adapter.py +89 -0
  8. flood_adapt/adapter/interface/offshore.py +19 -0
  9. flood_adapt/adapter/sfincs_adapter.py +1857 -0
  10. flood_adapt/adapter/sfincs_offshore.py +193 -0
  11. flood_adapt/config/__init__.py +0 -0
  12. flood_adapt/config/config.py +245 -0
  13. flood_adapt/config/fiat.py +219 -0
  14. flood_adapt/config/gui.py +224 -0
  15. flood_adapt/config/sfincs.py +336 -0
  16. flood_adapt/config/site.py +124 -0
  17. flood_adapt/database_builder/__init__.py +0 -0
  18. flood_adapt/database_builder/database_builder.py +2175 -0
  19. flood_adapt/database_builder/templates/default_units/imperial.toml +9 -0
  20. flood_adapt/database_builder/templates/default_units/metric.toml +9 -0
  21. flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -0
  22. flood_adapt/database_builder/templates/icons/black_down_48x48.png +0 -0
  23. flood_adapt/database_builder/templates/icons/black_left_48x48.png +0 -0
  24. flood_adapt/database_builder/templates/icons/black_right_48x48.png +0 -0
  25. flood_adapt/database_builder/templates/icons/black_up_48x48.png +0 -0
  26. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_down.png +0 -0
  27. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_left.png +0 -0
  28. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_right.png +0 -0
  29. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_up.png +0 -0
  30. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_down.png +0 -0
  31. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_left.png +0 -0
  32. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_right.png +0 -0
  33. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_up.png +0 -0
  34. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_left.png +0 -0
  35. flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_right.png +0 -0
  36. flood_adapt/database_builder/templates/icons/white_down_48x48.png +0 -0
  37. flood_adapt/database_builder/templates/icons/white_left_48x48.png +0 -0
  38. flood_adapt/database_builder/templates/icons/white_right_48x48.png +0 -0
  39. flood_adapt/database_builder/templates/icons/white_up_48x48.png +0 -0
  40. flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -0
  41. flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -0
  42. flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -0
  43. flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -0
  44. flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -0
  45. flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -0
  46. flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -0
  47. flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -0
  48. flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -0
  49. flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -0
  50. flood_adapt/database_builder/templates/infographics/images/ambulance.png +0 -0
  51. flood_adapt/database_builder/templates/infographics/images/car.png +0 -0
  52. flood_adapt/database_builder/templates/infographics/images/cart.png +0 -0
  53. flood_adapt/database_builder/templates/infographics/images/firetruck.png +0 -0
  54. flood_adapt/database_builder/templates/infographics/images/hospital.png +0 -0
  55. flood_adapt/database_builder/templates/infographics/images/house.png +0 -0
  56. flood_adapt/database_builder/templates/infographics/images/info.png +0 -0
  57. flood_adapt/database_builder/templates/infographics/images/money.png +0 -0
  58. flood_adapt/database_builder/templates/infographics/images/person.png +0 -0
  59. flood_adapt/database_builder/templates/infographics/images/school.png +0 -0
  60. flood_adapt/database_builder/templates/infographics/images/truck.png +0 -0
  61. flood_adapt/database_builder/templates/infographics/images/walking_person.png +0 -0
  62. flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -0
  63. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -0
  64. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -0
  65. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -0
  66. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -0
  67. flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -0
  68. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -0
  69. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -0
  70. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -0
  71. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -0
  72. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -0
  73. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -0
  74. flood_adapt/database_builder/templates/mapbox_layers/bin_colors.toml +5 -0
  75. flood_adapt/database_builder.py +16 -0
  76. flood_adapt/dbs_classes/__init__.py +21 -0
  77. flood_adapt/dbs_classes/database.py +716 -0
  78. flood_adapt/dbs_classes/dbs_benefit.py +97 -0
  79. flood_adapt/dbs_classes/dbs_event.py +91 -0
  80. flood_adapt/dbs_classes/dbs_measure.py +103 -0
  81. flood_adapt/dbs_classes/dbs_projection.py +52 -0
  82. flood_adapt/dbs_classes/dbs_scenario.py +150 -0
  83. flood_adapt/dbs_classes/dbs_static.py +261 -0
  84. flood_adapt/dbs_classes/dbs_strategy.py +147 -0
  85. flood_adapt/dbs_classes/dbs_template.py +302 -0
  86. flood_adapt/dbs_classes/interface/database.py +147 -0
  87. flood_adapt/dbs_classes/interface/element.py +137 -0
  88. flood_adapt/dbs_classes/interface/static.py +47 -0
  89. flood_adapt/flood_adapt.py +1371 -0
  90. flood_adapt/misc/__init__.py +0 -0
  91. flood_adapt/misc/database_user.py +16 -0
  92. flood_adapt/misc/log.py +183 -0
  93. flood_adapt/misc/path_builder.py +54 -0
  94. flood_adapt/misc/utils.py +185 -0
  95. flood_adapt/objects/__init__.py +59 -0
  96. flood_adapt/objects/benefits/__init__.py +0 -0
  97. flood_adapt/objects/benefits/benefits.py +61 -0
  98. flood_adapt/objects/events/__init__.py +0 -0
  99. flood_adapt/objects/events/event_factory.py +135 -0
  100. flood_adapt/objects/events/event_set.py +84 -0
  101. flood_adapt/objects/events/events.py +221 -0
  102. flood_adapt/objects/events/historical.py +55 -0
  103. flood_adapt/objects/events/hurricane.py +64 -0
  104. flood_adapt/objects/events/synthetic.py +48 -0
  105. flood_adapt/objects/forcing/__init__.py +0 -0
  106. flood_adapt/objects/forcing/csv.py +68 -0
  107. flood_adapt/objects/forcing/discharge.py +66 -0
  108. flood_adapt/objects/forcing/forcing.py +142 -0
  109. flood_adapt/objects/forcing/forcing_factory.py +182 -0
  110. flood_adapt/objects/forcing/meteo_handler.py +93 -0
  111. flood_adapt/objects/forcing/netcdf.py +40 -0
  112. flood_adapt/objects/forcing/plotting.py +428 -0
  113. flood_adapt/objects/forcing/rainfall.py +98 -0
  114. flood_adapt/objects/forcing/tide_gauge.py +191 -0
  115. flood_adapt/objects/forcing/time_frame.py +77 -0
  116. flood_adapt/objects/forcing/timeseries.py +552 -0
  117. flood_adapt/objects/forcing/unit_system.py +580 -0
  118. flood_adapt/objects/forcing/waterlevels.py +108 -0
  119. flood_adapt/objects/forcing/wind.py +124 -0
  120. flood_adapt/objects/measures/__init__.py +0 -0
  121. flood_adapt/objects/measures/measure_factory.py +92 -0
  122. flood_adapt/objects/measures/measures.py +506 -0
  123. flood_adapt/objects/object_model.py +68 -0
  124. flood_adapt/objects/projections/__init__.py +0 -0
  125. flood_adapt/objects/projections/projections.py +89 -0
  126. flood_adapt/objects/scenarios/__init__.py +0 -0
  127. flood_adapt/objects/scenarios/scenarios.py +22 -0
  128. flood_adapt/objects/strategies/__init__.py +0 -0
  129. flood_adapt/objects/strategies/strategies.py +68 -0
  130. flood_adapt/workflows/__init__.py +0 -0
  131. flood_adapt/workflows/benefit_runner.py +541 -0
  132. flood_adapt/workflows/floodmap.py +85 -0
  133. flood_adapt/workflows/impacts_integrator.py +82 -0
  134. flood_adapt/workflows/scenario_runner.py +69 -0
  135. flood_adapt-0.3.0.dist-info/LICENSE +21 -0
  136. flood_adapt-0.3.0.dist-info/METADATA +183 -0
  137. flood_adapt-0.3.0.dist-info/RECORD +139 -0
  138. flood_adapt-0.3.0.dist-info/WHEEL +5 -0
  139. flood_adapt-0.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,302 @@
1
+ import shutil
2
+ from datetime import datetime
3
+ from pathlib import Path
4
+ from typing import Any, TypeVar
5
+
6
+ import tomli_w
7
+
8
+ from flood_adapt.dbs_classes.interface.database import IDatabase
9
+ from flood_adapt.dbs_classes.interface.element import AbstractDatabaseElement
10
+ from flood_adapt.objects.object_model import Object
11
+
12
+ T_OBJECTMODEL = TypeVar("T_OBJECTMODEL", bound=Object)
13
+
14
+
15
+ class DbsTemplate(AbstractDatabaseElement[T_OBJECTMODEL]):
16
+ display_name: str
17
+ dir_name: str
18
+ _object_class: type[T_OBJECTMODEL]
19
+
20
+ def __init__(self, database: IDatabase):
21
+ """Initialize any necessary attributes."""
22
+ self._database = database
23
+ self.input_path = database.input_path / self.dir_name
24
+ self.output_path = database.output_path / self.dir_name
25
+ self.standard_objects = []
26
+
27
+ def get(self, name: str) -> T_OBJECTMODEL:
28
+ """Return an object of the type of the database with the given name.
29
+
30
+ Parameters
31
+ ----------
32
+ name : str
33
+ name of the object to be returned
34
+
35
+ Returns
36
+ -------
37
+ Object
38
+ object of the type of the specified object model
39
+ """
40
+ # Make the full path to the object
41
+ full_path = self.input_path / name / f"{name}.toml"
42
+
43
+ # Check if the object exists
44
+ if not Path(full_path).is_file():
45
+ raise ValueError(f"{self.display_name}: '{name}' does not exist.")
46
+
47
+ # Load and return the object
48
+ return self._object_class.load_file(full_path)
49
+
50
+ def list_objects(self) -> dict[str, list[Any]]:
51
+ """Return a dictionary with info on the objects that currently exist in the database.
52
+
53
+ Returns
54
+ -------
55
+ dict[str, list[Any]]
56
+ A dictionary that contains the keys: `name`, 'path', 'last_modification_date', 'description', 'objects'
57
+ Each key has a list of the corresponding values, where the index of the values corresponds to the same object.
58
+ """
59
+ # Check if all objects exist
60
+ object_list = self._get_object_list()
61
+
62
+ # Load all objects
63
+ objects = [self._object_class.load_file(path) for path in object_list["path"]]
64
+
65
+ # From the loaded objects, get the name and description and add them to the object_list
66
+ object_list["name"] = [obj.name for obj in objects]
67
+ object_list["description"] = [obj.description for obj in objects]
68
+ object_list["objects"] = objects
69
+ return object_list
70
+
71
+ def copy(self, old_name: str, new_name: str, new_description: str):
72
+ """Copy (duplicate) an existing object, and give it a new name.
73
+
74
+ Parameters
75
+ ----------
76
+ old_name : str
77
+ name of the existing measure
78
+ new_name : str
79
+ name of the new measure
80
+ new_description : str
81
+ description of the new measure
82
+ """
83
+ copy_object = self.get(old_name)
84
+ copy_object.name = new_name
85
+ copy_object.description = new_description
86
+
87
+ # After changing the name and description, re-trigger the validators
88
+ copy_object.model_validate(copy_object)
89
+
90
+ # Checking whether the new name is already in use
91
+ self._validate_to_save(copy_object, overwrite=False)
92
+
93
+ # Write only the toml file
94
+ toml_path = self.input_path / new_name / f"{new_name}.toml"
95
+ toml_path.parent.mkdir(parents=True)
96
+ with open(toml_path, "wb") as f:
97
+ tomli_w.dump(copy_object.model_dump(exclude_none=True), f)
98
+
99
+ # Then copy all the accompanied files
100
+ src = self.input_path / old_name
101
+ dest = self.input_path / new_name
102
+
103
+ EXCLUDE = [".spw", ".toml"]
104
+ for file in src.glob("*"):
105
+ if file.suffix in EXCLUDE:
106
+ continue
107
+ if file.is_dir():
108
+ shutil.copytree(file, dest / file.name, dirs_exist_ok=True)
109
+ else:
110
+ shutil.copy2(file, dest / file.name)
111
+
112
+ def save(
113
+ self,
114
+ object_model: T_OBJECTMODEL,
115
+ overwrite: bool = False,
116
+ ):
117
+ """Save an object in the database and all associated files.
118
+
119
+ This saves the toml file and any additional files attached to the object.
120
+
121
+ Parameters
122
+ ----------
123
+ object_model : Object
124
+ object to be saved in the database
125
+ overwrite : bool, optional
126
+ whether to overwrite the object if it already exists in the
127
+ database, by default False
128
+
129
+ Raises
130
+ ------
131
+ ValueError
132
+ Raise error if name is already in use.
133
+ """
134
+ self._validate_to_save(object_model, overwrite=overwrite)
135
+
136
+ # If the folder doesnt exist yet, make the folder and save the object
137
+ if not (self.input_path / object_model.name).exists():
138
+ (self.input_path / object_model.name).mkdir()
139
+
140
+ # Save the object and any additional files
141
+ object_model.save(
142
+ self.input_path / object_model.name / f"{object_model.name}.toml",
143
+ )
144
+
145
+ def edit(self, object_model: T_OBJECTMODEL):
146
+ """Edit an already existing object in the database.
147
+
148
+ Parameters
149
+ ----------
150
+ object_model : Object
151
+ object to be edited in the database
152
+
153
+ Raises
154
+ ------
155
+ ValueError
156
+ Raise error if name is already in use.
157
+ """
158
+ # Check if the object exists
159
+ if object_model.name not in self.list_objects()["name"]:
160
+ raise ValueError(
161
+ f"{self.display_name}: '{object_model.name}' does not exist. You cannot edit an {self.display_name.lower()} that does not exist."
162
+ )
163
+
164
+ # Check if it is possible to delete the object by saving with overwrite. This then
165
+ # also covers checking whether the object is a standard object, is already used in
166
+ # a higher level object. If any of these are the case, it cannot be deleted.
167
+ self.save(object_model, overwrite=True)
168
+
169
+ def delete(self, name: str, toml_only: bool = False):
170
+ """Delete an already existing object in the database.
171
+
172
+ Parameters
173
+ ----------
174
+ name : str
175
+ name of the object to be deleted
176
+ toml_only : bool, optional
177
+ whether to only delete the toml file or the entire folder. If the folder is empty after deleting the toml,
178
+ it will always be deleted. By default False
179
+
180
+ Raises
181
+ ------
182
+ ValueError
183
+ Raise error if object to be deleted is already in use.
184
+ """
185
+ # Check if the object is a standard object. If it is, raise an error
186
+ if self._check_standard_objects(name):
187
+ raise ValueError(
188
+ f"'{name}' cannot be deleted/modified since it is a standard {self.display_name}."
189
+ )
190
+
191
+ # Check if object is used in a higher level object. If it is, raise an error
192
+ if used_in := self.check_higher_level_usage(name):
193
+ raise ValueError(
194
+ f"{self.display_name}: '{name}' cannot be deleted/modified since it is already used in: {', '.join(used_in)}"
195
+ )
196
+
197
+ # Once all checks are passed, delete the object
198
+ toml_path = self.input_path / name / f"{name}.toml"
199
+ if toml_only:
200
+ # Only delete the toml file
201
+ toml_path.unlink(missing_ok=True)
202
+ # If the folder is empty, delete the folder
203
+ if not list(toml_path.parent.iterdir()):
204
+ toml_path.parent.rmdir()
205
+ else:
206
+ # Delete the entire folder
207
+ shutil.rmtree(toml_path.parent, ignore_errors=True)
208
+ if (self.output_path / name).exists():
209
+ shutil.rmtree(self.output_path / name, ignore_errors=True)
210
+
211
+ def _check_standard_objects(self, name: str) -> bool:
212
+ """Check if an object is a standard object.
213
+
214
+ Parameters
215
+ ----------
216
+ name : str
217
+ name of the object to be checked
218
+
219
+ Returns
220
+ -------
221
+ bool
222
+ True if the object is a standard object, False otherwise
223
+ """
224
+ # If this function is not implemented for the object type, it cannot be a standard object.
225
+ # By default, it is not a standard object.
226
+ return False
227
+
228
+ def check_higher_level_usage(self, name: str) -> list[str]:
229
+ """Check if an object is used in a higher level object.
230
+
231
+ Parameters
232
+ ----------
233
+ name : str
234
+ name of the object to be checked
235
+
236
+ Returns
237
+ -------
238
+ list[str]
239
+ list of higher level objects that use the object
240
+ """
241
+ # If this function is not implemented for the object type, it cannot be used in a higher
242
+ # level object. By default, return an empty list
243
+ return []
244
+
245
+ def _get_object_list(self) -> dict[str, list[Any]]:
246
+ """Get a dictionary with all the toml paths and last modification dates that exist in the database of the given object_type.
247
+
248
+ Returns
249
+ -------
250
+ dict[str, Any]
251
+ A dictionary that contains the keys: `name` to 'path' and 'last_modification_date'
252
+ Each key has a list of the corresponding values, where the index of the values corresponds to the same object.
253
+ """
254
+ # If the toml doesnt exist, we might be in the middle of saving a new object or could be a broken object.
255
+ # In any case, we should not list it in the database
256
+ directories = [
257
+ dir
258
+ for dir in self.input_path.iterdir()
259
+ if (dir / f"{dir.name}.toml").is_file()
260
+ ]
261
+ paths = [Path(dir / f"{dir.name}.toml") for dir in directories]
262
+ names = [dir.name for dir in directories]
263
+ last_modification_date = [
264
+ datetime.fromtimestamp(file.stat().st_mtime) for file in paths
265
+ ]
266
+
267
+ objects = {
268
+ "name": names,
269
+ "path": paths,
270
+ "last_modification_date": last_modification_date,
271
+ }
272
+
273
+ return objects
274
+
275
+ def _validate_to_save(self, object_model: T_OBJECTMODEL, overwrite: bool) -> None:
276
+ """Validate if the object can be saved.
277
+
278
+ Parameters
279
+ ----------
280
+ object_model : Object
281
+ object to be validated
282
+
283
+ Raises
284
+ ------
285
+ ValueError
286
+ Raise error if name is already in use.
287
+ """
288
+ # Check if the object exists
289
+ if object_model.name in self.list_objects()["name"]:
290
+ raise ValueError(
291
+ f"{self.display_name}: '{object_model.name}' already exists. Choose a different name."
292
+ )
293
+ object_exists = object_model.name in self.list_objects()["name"]
294
+
295
+ # If you want to overwrite the object, and the object already exists, first delete it. If it exists and you
296
+ # don't want to overwrite, raise an error.
297
+ if overwrite and object_exists:
298
+ self.delete(object_model.name, toml_only=True)
299
+ elif not overwrite and object_exists:
300
+ raise ValueError(
301
+ f"'{object_model.name}' name is already used by another {self.display_name.lower()}. Choose a different name"
302
+ )
@@ -0,0 +1,147 @@
1
+ import os
2
+ from abc import ABC, abstractmethod
3
+ from pathlib import Path
4
+ from typing import Any, Optional, Union
5
+
6
+ import geopandas as gpd
7
+ import numpy as np
8
+ import pandas as pd
9
+ from cht_cyclones.tropical_cyclone import TropicalCyclone
10
+
11
+ from flood_adapt.config.site import Site
12
+ from flood_adapt.dbs_classes.interface.element import AbstractDatabaseElement
13
+ from flood_adapt.dbs_classes.interface.static import IDbsStatic
14
+ from flood_adapt.objects.benefits.benefits import Benefit
15
+ from flood_adapt.objects.events.events import Event
16
+
17
+
18
+ class IDatabase(ABC):
19
+ base_path: Path
20
+ input_path: Path
21
+ output_path: Path
22
+ static_path: Path
23
+
24
+ @property
25
+ @abstractmethod
26
+ def site(self) -> Site: ...
27
+
28
+ @property
29
+ @abstractmethod
30
+ def static(self) -> IDbsStatic: ...
31
+
32
+ @property
33
+ @abstractmethod
34
+ def events(self) -> AbstractDatabaseElement: ...
35
+
36
+ @property
37
+ @abstractmethod
38
+ def scenarios(self) -> AbstractDatabaseElement: ...
39
+
40
+ @property
41
+ @abstractmethod
42
+ def strategies(self) -> AbstractDatabaseElement: ...
43
+
44
+ @property
45
+ @abstractmethod
46
+ def measures(self) -> AbstractDatabaseElement: ...
47
+
48
+ @property
49
+ @abstractmethod
50
+ def projections(self) -> AbstractDatabaseElement: ...
51
+
52
+ @property
53
+ @abstractmethod
54
+ def benefits(self) -> AbstractDatabaseElement: ...
55
+
56
+ @abstractmethod
57
+ def __init__(
58
+ self, database_path: Union[str, os.PathLike], site_name: str
59
+ ) -> None: ...
60
+
61
+ @abstractmethod
62
+ def interp_slr(self, slr_scenario: str, year: float) -> float:
63
+ pass
64
+
65
+ @abstractmethod
66
+ def plot_slr_scenarios(self) -> str:
67
+ pass
68
+
69
+ @abstractmethod
70
+ def write_to_csv(self, name: str, event: Event, df: pd.DataFrame) -> None:
71
+ pass
72
+
73
+ @abstractmethod
74
+ def write_cyc(self, event: Event, track: TropicalCyclone) -> None:
75
+ pass
76
+
77
+ @abstractmethod
78
+ def check_benefit_scenarios(self, benefit: Benefit) -> pd.DataFrame:
79
+ pass
80
+
81
+ @abstractmethod
82
+ def create_benefit_scenarios(self, benefit: Benefit) -> None:
83
+ pass
84
+
85
+ @abstractmethod
86
+ def run_benefit(self, benefit_name: Union[str, list[str]]) -> None:
87
+ pass
88
+
89
+ @abstractmethod
90
+ def update(self) -> None:
91
+ pass
92
+
93
+ @abstractmethod
94
+ def get_outputs(self) -> dict[str, Any]:
95
+ pass
96
+
97
+ @abstractmethod
98
+ def get_topobathy_path(self) -> str:
99
+ pass
100
+
101
+ @abstractmethod
102
+ def get_index_path(self) -> str:
103
+ pass
104
+
105
+ @abstractmethod
106
+ def get_depth_conversion(self) -> float:
107
+ pass
108
+
109
+ @abstractmethod
110
+ def get_max_water_level(
111
+ self, scenario_name: str, return_period: Optional[int] = None
112
+ ) -> np.ndarray:
113
+ pass
114
+
115
+ @abstractmethod
116
+ def get_building_footprints(self, scenario_name: str) -> gpd.GeoDataFrame:
117
+ pass
118
+
119
+ @abstractmethod
120
+ def get_roads(self, scenario_name: str) -> gpd.GeoDataFrame:
121
+ pass
122
+
123
+ @abstractmethod
124
+ def get_aggregation(self, scenario_name: str) -> dict[str, gpd.GeoDataFrame]:
125
+ pass
126
+
127
+ @abstractmethod
128
+ def get_aggregation_benefits(
129
+ self, benefit_name: str
130
+ ) -> dict[str, gpd.GeoDataFrame]:
131
+ pass
132
+
133
+ @abstractmethod
134
+ def get_object_list(self, object_type: str) -> dict[str, Any]:
135
+ pass
136
+
137
+ @abstractmethod
138
+ def has_run_hazard(self, scenario_name: str) -> None:
139
+ pass
140
+
141
+ @abstractmethod
142
+ def run_scenario(self, scenario_name: Union[str, list[str]]) -> None:
143
+ pass
144
+
145
+ @abstractmethod
146
+ def cleanup(self) -> None:
147
+ pass
@@ -0,0 +1,137 @@
1
+ from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
+ from typing import Any, Generic, TypeVar
4
+
5
+ from flood_adapt.objects.object_model import Object
6
+
7
+ T_OBJECT_MODEL = TypeVar("T_OBJECT_MODEL", bound=Object)
8
+
9
+
10
+ class AbstractDatabaseElement(ABC, Generic[T_OBJECT_MODEL]):
11
+ input_path: Path
12
+ output_path: Path
13
+
14
+ @abstractmethod
15
+ def __init__(self):
16
+ """Abstract class for database elements."""
17
+ pass
18
+
19
+ @abstractmethod
20
+ def get(self, name: str) -> T_OBJECT_MODEL:
21
+ """Return the object of the type of the database with the given name.
22
+
23
+ Parameters
24
+ ----------
25
+ name : str
26
+ name of the object to be returned
27
+
28
+ Returns
29
+ -------
30
+ IObject
31
+ object of the type of the specified object model
32
+ """
33
+ pass
34
+
35
+ @abstractmethod
36
+ def list_objects(self) -> dict[str, list[Any]]:
37
+ """Return a dictionary with info on the objects that currently exist in the database.
38
+
39
+ Returns
40
+ -------
41
+ dict[str, Any]
42
+ Includes 'name', 'description', 'path' and 'last_modification_date' info, as well as the objects themselves
43
+ """
44
+ pass
45
+
46
+ @abstractmethod
47
+ def copy(self, old_name: str, new_name: str, new_description: str):
48
+ """Copy (duplicate) an existing object, and give it a new name.
49
+
50
+ Parameters
51
+ ----------
52
+ old_name : str
53
+ name of the existing measure
54
+ new_name : str
55
+ name of the new measure
56
+ new_description : str
57
+ description of the new measure
58
+ """
59
+ pass
60
+
61
+ @abstractmethod
62
+ def save(
63
+ self,
64
+ object_model: T_OBJECT_MODEL,
65
+ overwrite: bool = False,
66
+ ):
67
+ """Save an object in the database.
68
+
69
+ This only saves the toml file. If the object also contains a geojson file, this should be saved separately.
70
+
71
+ Parameters
72
+ ----------
73
+ object_model : Object
74
+ object to be saved in the database
75
+ overwrite : bool, optional
76
+ whether to overwrite the object if it already exists in the
77
+ database, by default False
78
+ toml_only : bool, optional
79
+ whether to only save the toml file or all associated data. By default, save everything
80
+
81
+ Raises
82
+ ------
83
+ ValueError
84
+ Raise error if name is already in use.
85
+ """
86
+ pass
87
+
88
+ @abstractmethod
89
+ def edit(self, object_model: T_OBJECT_MODEL):
90
+ """Edits an already existing object in the database.
91
+
92
+ Parameters
93
+ ----------
94
+ object : IObject
95
+ object to be edited in the database
96
+
97
+ Raises
98
+ ------
99
+ ValueError
100
+ Raise error if name is already in use.
101
+ """
102
+ pass
103
+
104
+ @abstractmethod
105
+ def delete(self, name: str, toml_only: bool = False):
106
+ """Delete an already existing object in the database.
107
+
108
+ Parameters
109
+ ----------
110
+ name : str
111
+ name of the object to be deleted
112
+ toml_only : bool, optional
113
+ whether to only delete the toml file or the entire folder. If the folder is empty after deleting the toml,
114
+ it will always be deleted. By default False
115
+
116
+ Raises
117
+ ------
118
+ ValueError
119
+ Raise error if object to be deleted is already in use.
120
+ """
121
+ pass
122
+
123
+ @abstractmethod
124
+ def check_higher_level_usage(self, name: str) -> list[str]:
125
+ """Check if an object is used in a higher level object.
126
+
127
+ Parameters
128
+ ----------
129
+ name : str
130
+ name of the object to be checked
131
+
132
+ Returns
133
+ -------
134
+ list[str]
135
+ list of higher level objects that use the object
136
+ """
137
+ pass
@@ -0,0 +1,47 @@
1
+ from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
+ from typing import Union
4
+
5
+ import geopandas as gpd
6
+ import pandas as pd
7
+ from cht_cyclones.cyclone_track_database import CycloneTrackDatabase
8
+
9
+ from flood_adapt.adapter.sfincs_adapter import SfincsAdapter
10
+
11
+
12
+ class IDbsStatic(ABC):
13
+ @abstractmethod
14
+ def get_aggregation_areas(self) -> dict: ...
15
+
16
+ @abstractmethod
17
+ def get_model_boundary(self) -> gpd.GeoDataFrame: ...
18
+
19
+ @abstractmethod
20
+ def get_model_grid(self): ...
21
+
22
+ @abstractmethod
23
+ def get_obs_points(self) -> gpd.GeoDataFrame: ...
24
+
25
+ @abstractmethod
26
+ def get_static_map(self, path: Union[str, Path]) -> gpd.GeoDataFrame: ...
27
+
28
+ @abstractmethod
29
+ def get_slr_scn_names(self) -> list: ...
30
+
31
+ @abstractmethod
32
+ def get_green_infra_table(self, measure_type: str) -> pd.DataFrame: ...
33
+
34
+ @abstractmethod
35
+ def get_buildings(self) -> gpd.GeoDataFrame: ...
36
+
37
+ @abstractmethod
38
+ def get_property_types(self) -> list: ...
39
+
40
+ @abstractmethod
41
+ def get_overland_sfincs_model(self) -> SfincsAdapter: ...
42
+
43
+ @abstractmethod
44
+ def get_offshore_sfincs_model(self) -> SfincsAdapter: ...
45
+
46
+ @abstractmethod
47
+ def get_cyclone_track_database(self) -> CycloneTrackDatabase: ...