flood-adapt 0.3.9__py3-none-any.whl → 0.3.10__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 (100) hide show
  1. flood_adapt/__init__.py +26 -22
  2. flood_adapt/adapter/__init__.py +9 -9
  3. flood_adapt/adapter/fiat_adapter.py +1541 -1541
  4. flood_adapt/adapter/interface/hazard_adapter.py +70 -70
  5. flood_adapt/adapter/interface/impact_adapter.py +36 -36
  6. flood_adapt/adapter/interface/model_adapter.py +89 -89
  7. flood_adapt/adapter/interface/offshore.py +19 -19
  8. flood_adapt/adapter/sfincs_adapter.py +1848 -1848
  9. flood_adapt/adapter/sfincs_offshore.py +193 -193
  10. flood_adapt/config/config.py +248 -248
  11. flood_adapt/config/fiat.py +219 -219
  12. flood_adapt/config/gui.py +331 -331
  13. flood_adapt/config/sfincs.py +481 -336
  14. flood_adapt/config/site.py +129 -129
  15. flood_adapt/database_builder/database_builder.py +2210 -2210
  16. flood_adapt/database_builder/templates/default_units/imperial.toml +9 -9
  17. flood_adapt/database_builder/templates/default_units/metric.toml +9 -9
  18. flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -10
  19. flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -90
  20. flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -57
  21. flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -121
  22. flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -65
  23. flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -45
  24. flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -126
  25. flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -60
  26. flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -121
  27. flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -65
  28. flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -45
  29. flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -4
  30. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -143
  31. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -153
  32. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -127
  33. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -57
  34. flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -4
  35. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -191
  36. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -153
  37. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -178
  38. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -57
  39. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -9
  40. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -65
  41. flood_adapt/database_builder/templates/output_layers/bin_colors.toml +5 -5
  42. flood_adapt/database_builder.py +16 -16
  43. flood_adapt/dbs_classes/__init__.py +21 -21
  44. flood_adapt/dbs_classes/database.py +495 -684
  45. flood_adapt/dbs_classes/dbs_benefit.py +77 -76
  46. flood_adapt/dbs_classes/dbs_event.py +61 -59
  47. flood_adapt/dbs_classes/dbs_measure.py +112 -111
  48. flood_adapt/dbs_classes/dbs_projection.py +34 -34
  49. flood_adapt/dbs_classes/dbs_scenario.py +137 -137
  50. flood_adapt/dbs_classes/dbs_static.py +274 -273
  51. flood_adapt/dbs_classes/dbs_strategy.py +130 -129
  52. flood_adapt/dbs_classes/dbs_template.py +279 -278
  53. flood_adapt/dbs_classes/interface/database.py +107 -139
  54. flood_adapt/dbs_classes/interface/element.py +121 -121
  55. flood_adapt/dbs_classes/interface/static.py +47 -47
  56. flood_adapt/flood_adapt.py +1207 -1178
  57. flood_adapt/misc/database_user.py +16 -16
  58. flood_adapt/misc/exceptions.py +22 -0
  59. flood_adapt/misc/log.py +183 -183
  60. flood_adapt/misc/path_builder.py +54 -54
  61. flood_adapt/misc/utils.py +185 -185
  62. flood_adapt/objects/__init__.py +82 -82
  63. flood_adapt/objects/benefits/benefits.py +61 -61
  64. flood_adapt/objects/events/event_factory.py +135 -135
  65. flood_adapt/objects/events/event_set.py +88 -84
  66. flood_adapt/objects/events/events.py +234 -234
  67. flood_adapt/objects/events/historical.py +58 -58
  68. flood_adapt/objects/events/hurricane.py +68 -67
  69. flood_adapt/objects/events/synthetic.py +46 -50
  70. flood_adapt/objects/forcing/__init__.py +92 -92
  71. flood_adapt/objects/forcing/csv.py +68 -68
  72. flood_adapt/objects/forcing/discharge.py +66 -66
  73. flood_adapt/objects/forcing/forcing.py +150 -150
  74. flood_adapt/objects/forcing/forcing_factory.py +182 -182
  75. flood_adapt/objects/forcing/meteo_handler.py +93 -93
  76. flood_adapt/objects/forcing/netcdf.py +40 -40
  77. flood_adapt/objects/forcing/plotting.py +453 -429
  78. flood_adapt/objects/forcing/rainfall.py +98 -98
  79. flood_adapt/objects/forcing/tide_gauge.py +191 -191
  80. flood_adapt/objects/forcing/time_frame.py +90 -90
  81. flood_adapt/objects/forcing/timeseries.py +564 -564
  82. flood_adapt/objects/forcing/unit_system.py +580 -580
  83. flood_adapt/objects/forcing/waterlevels.py +108 -108
  84. flood_adapt/objects/forcing/wind.py +124 -124
  85. flood_adapt/objects/measures/measure_factory.py +92 -92
  86. flood_adapt/objects/measures/measures.py +529 -529
  87. flood_adapt/objects/object_model.py +74 -68
  88. flood_adapt/objects/projections/projections.py +103 -103
  89. flood_adapt/objects/scenarios/scenarios.py +22 -22
  90. flood_adapt/objects/strategies/strategies.py +89 -89
  91. flood_adapt/workflows/benefit_runner.py +579 -554
  92. flood_adapt/workflows/floodmap.py +85 -85
  93. flood_adapt/workflows/impacts_integrator.py +85 -85
  94. flood_adapt/workflows/scenario_runner.py +70 -70
  95. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
  96. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -865
  97. flood_adapt-0.3.10.dist-info/RECORD +140 -0
  98. flood_adapt-0.3.9.dist-info/RECORD +0 -139
  99. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
  100. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
@@ -1,273 +1,274 @@
1
- from pathlib import Path
2
- from typing import Any, Callable, Tuple, Union
3
-
4
- import geopandas as gpd
5
- import pandas as pd
6
- from cht_cyclones.cyclone_track_database import CycloneTrackDatabase
7
-
8
- from flood_adapt.adapter.fiat_adapter import FiatAdapter
9
- from flood_adapt.adapter.sfincs_adapter import SfincsAdapter
10
- from flood_adapt.config.config import Settings
11
- from flood_adapt.dbs_classes.interface.database import IDatabase
12
- from flood_adapt.dbs_classes.interface.static import IDbsStatic
13
-
14
-
15
- def cache_method_wrapper(func: Callable) -> Callable:
16
- def wrapper(self, *args: Tuple[Any], **kwargs: dict[str, Any]) -> Any:
17
- if func.__name__ not in self._cached_data:
18
- self._cached_data[func.__name__] = {}
19
-
20
- args_key = (
21
- str(args) + str(sorted(kwargs.items())) if args or kwargs else "no_args"
22
- )
23
- if args_key in self._cached_data[func.__name__]:
24
- return self._cached_data[func.__name__][args_key]
25
-
26
- result = func(self, *args, **kwargs)
27
- self._cached_data[func.__name__][args_key] = result
28
-
29
- return result
30
-
31
- return wrapper
32
-
33
-
34
- class DbsStatic(IDbsStatic):
35
- _cached_data: dict[str, Any] = {}
36
- _database: IDatabase
37
-
38
- def __init__(self, database: IDatabase):
39
- """Initialize any necessary attributes."""
40
- self._database = database
41
-
42
- def load_static_data(self):
43
- """Read data into the cache.
44
-
45
- This is used to read data from the database and store it in the cache.
46
- """
47
- self.get_aggregation_areas()
48
- self.get_model_boundary()
49
- self.get_model_grid()
50
- self.get_obs_points()
51
- if self._database.site.sfincs.slr_scenarios is not None:
52
- self.get_slr_scn_names()
53
- self.get_buildings()
54
- self.get_property_types()
55
-
56
- @cache_method_wrapper
57
- def get_aggregation_areas(self) -> dict[str, gpd.GeoDataFrame]:
58
- """Get a list of the aggregation areas that are provided in the site configuration.
59
-
60
- These are expected to much the ones in the FIAT model.
61
-
62
- Returns
63
- -------
64
- list[gpd.GeoDataFrame]
65
- list of gpd.GeoDataFrames with the polygons defining the aggregation areas
66
- """
67
- aggregation_areas = {}
68
- for aggr_dict in self._database.site.fiat.config.aggregation:
69
- aggregation_areas[aggr_dict.name] = gpd.read_file(
70
- self._database.static_path / aggr_dict.file,
71
- engine="pyogrio",
72
- ).to_crs(4326)
73
- # Use always the same column name for name labels
74
- aggregation_areas[aggr_dict.name] = aggregation_areas[
75
- aggr_dict.name
76
- ].rename(columns={aggr_dict.field_name: "name"})
77
- # Make sure they are ordered alphabetically
78
- aggregation_areas[aggr_dict.name].sort_values(by="name").reset_index(
79
- drop=True
80
- )
81
- return aggregation_areas
82
-
83
- @cache_method_wrapper
84
- def get_model_boundary(self) -> gpd.GeoDataFrame:
85
- """Get the model boundary from the SFINCS model."""
86
- bnd = self.get_overland_sfincs_model().get_model_boundary()
87
- return bnd
88
-
89
- @cache_method_wrapper
90
- def get_model_grid(self):
91
- """Get the model grid from the SFINCS model.
92
-
93
- Returns
94
- -------
95
- QuadtreeGrid
96
- The model grid
97
- """
98
- grid = self.get_overland_sfincs_model().get_model_grid()
99
- return grid
100
-
101
- @cache_method_wrapper
102
- def get_obs_points(self) -> gpd.GeoDataFrame:
103
- """Get the observation points from the flood hazard model."""
104
- names = []
105
- descriptions = []
106
- lat = []
107
- lon = []
108
- if self._database.site.sfincs.obs_point is not None:
109
- obs_points = self._database.site.sfincs.obs_point
110
- for pt in obs_points:
111
- names.append(pt.name)
112
- descriptions.append(pt.description)
113
- lat.append(pt.lat)
114
- lon.append(pt.lon)
115
-
116
- # create gpd.GeoDataFrame from obs_points in site file
117
- df = pd.DataFrame({"name": names, "description": descriptions})
118
- # TODO: make crs flexible and add this as a parameter to site.toml?
119
- gdf = gpd.GeoDataFrame(
120
- df, geometry=gpd.points_from_xy(lon, lat), crs="EPSG:4326"
121
- )
122
- return gdf
123
-
124
- @cache_method_wrapper
125
- def get_static_map(self, path: Union[str, Path]) -> gpd.GeoDataFrame:
126
- """Get a map from the static folder.
127
-
128
- Parameters
129
- ----------
130
- path : Union[str, Path]
131
- Path to the map relative to the static folder
132
-
133
- Returns
134
- -------
135
- gpd.GeoDataFrame
136
- gpd.GeoDataFrame with the map in crs 4326
137
-
138
- Raises
139
- ------
140
- FileNotFoundError
141
- If the file is not found
142
- """
143
- # Read the map
144
- full_path = self._database.static_path / path
145
- if not full_path.is_file():
146
- raise FileNotFoundError(f"File {full_path} not found")
147
- return gpd.read_file(full_path, engine="pyogrio").to_crs(4326)
148
-
149
- @cache_method_wrapper
150
- def get_slr_scn_names(self) -> list:
151
- """Get the names of the sea level rise scenarios from the file provided.
152
-
153
- Returns
154
- -------
155
- list
156
- List of scenario names
157
- """
158
- input_file = self._database.static_path.joinpath(
159
- self._database.site.sfincs.slr_scenarios.file
160
- )
161
- df = pd.read_csv(input_file)
162
- names = df.columns[2:].to_list()
163
- return names
164
-
165
- @cache_method_wrapper
166
- def get_green_infra_table(self, measure_type: str) -> pd.DataFrame:
167
- """Return a table with different types of green infrastructure measures and their infiltration depths.
168
-
169
- This is read by a csv file in the database.
170
-
171
- Returns
172
- -------
173
- pd.DataFrame
174
- Table with values
175
- """
176
- # Read file from database
177
- df = pd.read_csv(
178
- self._database.static_path.joinpath(
179
- "green_infra_table", "green_infra_lookup_table.csv"
180
- )
181
- )
182
-
183
- # Get column with values
184
- val_name = "Infiltration depth"
185
- col_name = [name for name in df.columns if val_name in name][0]
186
- if not col_name:
187
- raise KeyError(f"A column with a name containing {val_name} was not found!")
188
-
189
- # Get list of types per measure
190
- df["types"] = [
191
- [x.strip() for x in row["types"].split(",")] for i, row in df.iterrows()
192
- ]
193
-
194
- # Show specific values based on measure type
195
- inds = [i for i, row in df.iterrows() if measure_type in row["types"]]
196
- df = df.drop(columns="types").iloc[inds, :]
197
-
198
- return df
199
-
200
- @cache_method_wrapper
201
- def get_buildings(self) -> gpd.GeoDataFrame:
202
- """Get the building footprints from the FIAT model.
203
-
204
- This should only be the buildings excluding any other types (e.g., roads)
205
- The parameters non_building_names in the site config is used for that.
206
-
207
- Returns
208
- -------
209
- gpd.GeoDataFrame
210
- building footprints with all the FIAT columns
211
- """
212
- return self.get_fiat_model().get_buildings()
213
-
214
- @cache_method_wrapper
215
- def get_property_types(self) -> list:
216
- """_summary_.
217
-
218
- Returns
219
- -------
220
- list
221
- _description_
222
- """
223
- return self.get_fiat_model().get_property_types()
224
-
225
- def get_overland_sfincs_model(self) -> SfincsAdapter:
226
- """Get the template offshore SFINCS model."""
227
- overland_path = (
228
- self._database.static_path
229
- / "templates"
230
- / self._database.site.sfincs.config.overland_model.name
231
- )
232
- with SfincsAdapter(model_root=overland_path) as overland_model:
233
- return overland_model
234
-
235
- def get_offshore_sfincs_model(self) -> SfincsAdapter:
236
- """Get the template overland Sfincs model."""
237
- if self._database.site.sfincs.config.offshore_model is None:
238
- raise ValueError("No offshore model defined in the site configuration.")
239
-
240
- offshore_path = (
241
- self._database.static_path
242
- / "templates"
243
- / self._database.site.sfincs.config.offshore_model.name
244
- )
245
- with SfincsAdapter(model_root=offshore_path) as offshore_model:
246
- return offshore_model
247
-
248
- def get_fiat_model(self) -> FiatAdapter:
249
- """Get the path to the FIAT model."""
250
- if self._database.site.fiat is None:
251
- raise ValueError("No FIAT model defined in the site configuration.")
252
- template_path = self._database.static_path / "templates" / "fiat"
253
- with FiatAdapter(
254
- model_root=template_path,
255
- config=self._database.site.fiat.config,
256
- exe_path=Settings().fiat_bin_path,
257
- delete_crashed_runs=Settings().delete_crashed_runs,
258
- config_base_path=self._database.static_path,
259
- ) as fm:
260
- return fm
261
-
262
- @cache_method_wrapper
263
- def get_cyclone_track_database(self) -> CycloneTrackDatabase:
264
- if self._database.site.sfincs.cyclone_track_database is None:
265
- raise ValueError(
266
- "No cyclone track database defined in the site configuration."
267
- )
268
- database_file = str(
269
- self._database.static_path
270
- / "cyclone_track_database"
271
- / self._database.site.sfincs.cyclone_track_database.file
272
- )
273
- return CycloneTrackDatabase("ibtracs", file_name=database_file)
1
+ from pathlib import Path
2
+ from typing import Any, Callable, Tuple, Union
3
+
4
+ import geopandas as gpd
5
+ import pandas as pd
6
+ from cht_cyclones.cyclone_track_database import CycloneTrackDatabase
7
+
8
+ from flood_adapt.adapter.fiat_adapter import FiatAdapter
9
+ from flood_adapt.adapter.sfincs_adapter import SfincsAdapter
10
+ from flood_adapt.config.config import Settings
11
+ from flood_adapt.dbs_classes.interface.database import IDatabase
12
+ from flood_adapt.dbs_classes.interface.static import IDbsStatic
13
+ from flood_adapt.misc.exceptions import DatabaseError
14
+
15
+
16
+ def cache_method_wrapper(func: Callable) -> Callable:
17
+ def wrapper(self, *args: Tuple[Any], **kwargs: dict[str, Any]) -> Any:
18
+ if func.__name__ not in self._cached_data:
19
+ self._cached_data[func.__name__] = {}
20
+
21
+ args_key = (
22
+ str(args) + str(sorted(kwargs.items())) if args or kwargs else "no_args"
23
+ )
24
+ if args_key in self._cached_data[func.__name__]:
25
+ return self._cached_data[func.__name__][args_key]
26
+
27
+ result = func(self, *args, **kwargs)
28
+ self._cached_data[func.__name__][args_key] = result
29
+
30
+ return result
31
+
32
+ return wrapper
33
+
34
+
35
+ class DbsStatic(IDbsStatic):
36
+ _cached_data: dict[str, Any] = {}
37
+ _database: IDatabase
38
+
39
+ def __init__(self, database: IDatabase):
40
+ """Initialize any necessary attributes."""
41
+ self._database = database
42
+
43
+ def load_static_data(self):
44
+ """Read data into the cache.
45
+
46
+ This is used to read data from the database and store it in the cache.
47
+ """
48
+ self.get_aggregation_areas()
49
+ self.get_model_boundary()
50
+ self.get_model_grid()
51
+ self.get_obs_points()
52
+ if self._database.site.sfincs.slr_scenarios is not None:
53
+ self.get_slr_scn_names()
54
+ self.get_buildings()
55
+ self.get_property_types()
56
+
57
+ @cache_method_wrapper
58
+ def get_aggregation_areas(self) -> dict[str, gpd.GeoDataFrame]:
59
+ """Get a list of the aggregation areas that are provided in the site configuration.
60
+
61
+ These are expected to much the ones in the FIAT model.
62
+
63
+ Returns
64
+ -------
65
+ list[gpd.GeoDataFrame]
66
+ list of gpd.GeoDataFrames with the polygons defining the aggregation areas
67
+ """
68
+ aggregation_areas = {}
69
+ for aggr_dict in self._database.site.fiat.config.aggregation:
70
+ aggregation_areas[aggr_dict.name] = gpd.read_file(
71
+ self._database.static_path / aggr_dict.file,
72
+ engine="pyogrio",
73
+ ).to_crs(4326)
74
+ # Use always the same column name for name labels
75
+ aggregation_areas[aggr_dict.name] = aggregation_areas[
76
+ aggr_dict.name
77
+ ].rename(columns={aggr_dict.field_name: "name"})
78
+ # Make sure they are ordered alphabetically
79
+ aggregation_areas[aggr_dict.name].sort_values(by="name").reset_index(
80
+ drop=True
81
+ )
82
+ return aggregation_areas
83
+
84
+ @cache_method_wrapper
85
+ def get_model_boundary(self) -> gpd.GeoDataFrame:
86
+ """Get the model boundary from the SFINCS model."""
87
+ bnd = self.get_overland_sfincs_model().get_model_boundary()
88
+ return bnd
89
+
90
+ @cache_method_wrapper
91
+ def get_model_grid(self):
92
+ """Get the model grid from the SFINCS model.
93
+
94
+ Returns
95
+ -------
96
+ QuadtreeGrid
97
+ The model grid
98
+ """
99
+ grid = self.get_overland_sfincs_model().get_model_grid()
100
+ return grid
101
+
102
+ @cache_method_wrapper
103
+ def get_obs_points(self) -> gpd.GeoDataFrame:
104
+ """Get the observation points from the flood hazard model."""
105
+ names = []
106
+ descriptions = []
107
+ lat = []
108
+ lon = []
109
+ if self._database.site.sfincs.obs_point is not None:
110
+ obs_points = self._database.site.sfincs.obs_point
111
+ for pt in obs_points:
112
+ names.append(pt.name)
113
+ descriptions.append(pt.description)
114
+ lat.append(pt.lat)
115
+ lon.append(pt.lon)
116
+
117
+ # create gpd.GeoDataFrame from obs_points in site file
118
+ df = pd.DataFrame({"name": names, "description": descriptions})
119
+ # TODO: make crs flexible and add this as a parameter to site.toml?
120
+ gdf = gpd.GeoDataFrame(
121
+ df, geometry=gpd.points_from_xy(lon, lat), crs="EPSG:4326"
122
+ )
123
+ return gdf
124
+
125
+ @cache_method_wrapper
126
+ def get_static_map(self, path: Union[str, Path]) -> gpd.GeoDataFrame:
127
+ """Get a map from the static folder.
128
+
129
+ Parameters
130
+ ----------
131
+ path : Union[str, Path]
132
+ Path to the map relative to the static folder
133
+
134
+ Returns
135
+ -------
136
+ gpd.GeoDataFrame
137
+ gpd.GeoDataFrame with the map in crs 4326
138
+
139
+ Raises
140
+ ------
141
+ DatabaseError
142
+ If the file is not found
143
+ """
144
+ # Read the map
145
+ full_path = self._database.static_path / path
146
+ if not full_path.is_file():
147
+ raise DatabaseError(f"File {full_path} not found")
148
+ return gpd.read_file(full_path, engine="pyogrio").to_crs(4326)
149
+
150
+ @cache_method_wrapper
151
+ def get_slr_scn_names(self) -> list:
152
+ """Get the names of the sea level rise scenarios from the file provided.
153
+
154
+ Returns
155
+ -------
156
+ list
157
+ List of scenario names
158
+ """
159
+ input_file = self._database.static_path.joinpath(
160
+ self._database.site.sfincs.slr_scenarios.file
161
+ )
162
+ df = pd.read_csv(input_file)
163
+ names = df.columns[2:].to_list()
164
+ return names
165
+
166
+ @cache_method_wrapper
167
+ def get_green_infra_table(self, measure_type: str) -> pd.DataFrame:
168
+ """Return a table with different types of green infrastructure measures and their infiltration depths.
169
+
170
+ This is read by a csv file in the database.
171
+
172
+ Returns
173
+ -------
174
+ pd.DataFrame
175
+ Table with values
176
+ """
177
+ # Read file from database
178
+ df = pd.read_csv(
179
+ self._database.static_path.joinpath(
180
+ "green_infra_table", "green_infra_lookup_table.csv"
181
+ )
182
+ )
183
+
184
+ # Get column with values
185
+ val_name = "Infiltration depth"
186
+ col_name = [name for name in df.columns if val_name in name][0]
187
+ if not col_name:
188
+ raise KeyError(f"A column with a name containing {val_name} was not found!")
189
+
190
+ # Get list of types per measure
191
+ df["types"] = [
192
+ [x.strip() for x in row["types"].split(",")] for i, row in df.iterrows()
193
+ ]
194
+
195
+ # Show specific values based on measure type
196
+ inds = [i for i, row in df.iterrows() if measure_type in row["types"]]
197
+ df = df.drop(columns="types").iloc[inds, :]
198
+
199
+ return df
200
+
201
+ @cache_method_wrapper
202
+ def get_buildings(self) -> gpd.GeoDataFrame:
203
+ """Get the building footprints from the FIAT model.
204
+
205
+ This should only be the buildings excluding any other types (e.g., roads)
206
+ The parameters non_building_names in the site config is used for that.
207
+
208
+ Returns
209
+ -------
210
+ gpd.GeoDataFrame
211
+ building footprints with all the FIAT columns
212
+ """
213
+ return self.get_fiat_model().get_buildings()
214
+
215
+ @cache_method_wrapper
216
+ def get_property_types(self) -> list:
217
+ """_summary_.
218
+
219
+ Returns
220
+ -------
221
+ list
222
+ _description_
223
+ """
224
+ return self.get_fiat_model().get_property_types()
225
+
226
+ def get_overland_sfincs_model(self) -> SfincsAdapter:
227
+ """Get the template offshore SFINCS model."""
228
+ overland_path = (
229
+ self._database.static_path
230
+ / "templates"
231
+ / self._database.site.sfincs.config.overland_model.name
232
+ )
233
+ with SfincsAdapter(model_root=overland_path) as overland_model:
234
+ return overland_model
235
+
236
+ def get_offshore_sfincs_model(self) -> SfincsAdapter:
237
+ """Get the template overland Sfincs model."""
238
+ if self._database.site.sfincs.config.offshore_model is None:
239
+ raise DatabaseError("No offshore model defined in the site configuration.")
240
+
241
+ offshore_path = (
242
+ self._database.static_path
243
+ / "templates"
244
+ / self._database.site.sfincs.config.offshore_model.name
245
+ )
246
+ with SfincsAdapter(model_root=offshore_path) as offshore_model:
247
+ return offshore_model
248
+
249
+ def get_fiat_model(self) -> FiatAdapter:
250
+ """Get the path to the FIAT model."""
251
+ if self._database.site.fiat is None:
252
+ raise DatabaseError("No FIAT model defined in the site configuration.")
253
+ template_path = self._database.static_path / "templates" / "fiat"
254
+ with FiatAdapter(
255
+ model_root=template_path,
256
+ config=self._database.site.fiat.config,
257
+ exe_path=Settings().fiat_bin_path,
258
+ delete_crashed_runs=Settings().delete_crashed_runs,
259
+ config_base_path=self._database.static_path,
260
+ ) as fm:
261
+ return fm
262
+
263
+ @cache_method_wrapper
264
+ def get_cyclone_track_database(self) -> CycloneTrackDatabase:
265
+ if self._database.site.sfincs.cyclone_track_database is None:
266
+ raise DatabaseError(
267
+ "No cyclone track database defined in the site configuration."
268
+ )
269
+ database_file = str(
270
+ self._database.static_path
271
+ / "cyclone_track_database"
272
+ / self._database.site.sfincs.cyclone_track_database.file
273
+ )
274
+ return CycloneTrackDatabase("ibtracs", file_name=database_file)