flood-adapt 0.3.8__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 -1536
  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 -1846
  9. flood_adapt/adapter/sfincs_offshore.py +193 -193
  10. flood_adapt/config/config.py +248 -290
  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 -688
  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 -89
  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 -544
  92. flood_adapt/workflows/floodmap.py +85 -85
  93. flood_adapt/workflows/impacts_integrator.py +85 -82
  94. flood_adapt/workflows/scenario_runner.py +70 -70
  95. {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
  96. {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -860
  97. flood_adapt-0.3.10.dist-info/RECORD +140 -0
  98. flood_adapt-0.3.8.dist-info/RECORD +0 -139
  99. {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
  100. {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
@@ -1,193 +1,193 @@
1
- import shutil
2
- from pathlib import Path
3
-
4
- import pandas as pd
5
-
6
- from flood_adapt.adapter.interface.offshore import IOffshoreSfincsHandler
7
- from flood_adapt.adapter.sfincs_adapter import SfincsAdapter
8
- from flood_adapt.misc.database_user import DatabaseUser
9
- from flood_adapt.misc.log import FloodAdaptLogging
10
- from flood_adapt.misc.path_builder import (
11
- ObjectDir,
12
- TopLevelDir,
13
- db_path,
14
- )
15
- from flood_adapt.objects.events.event_set import EventSet
16
- from flood_adapt.objects.events.events import Event, Mode
17
- from flood_adapt.objects.events.historical import HistoricalEvent
18
- from flood_adapt.objects.forcing.forcing import (
19
- ForcingSource,
20
- IWind,
21
- )
22
- from flood_adapt.objects.forcing.meteo_handler import MeteoHandler
23
- from flood_adapt.objects.forcing.wind import WindMeteo
24
- from flood_adapt.objects.scenarios.scenarios import Scenario
25
-
26
-
27
- class OffshoreSfincsHandler(IOffshoreSfincsHandler, DatabaseUser):
28
- logger = FloodAdaptLogging.getLogger("OffshoreSfincsAdapter")
29
- template_path: Path
30
-
31
- def __init__(self, scenario: Scenario, event: Event) -> None:
32
- self.template_path = (
33
- self.database.static.get_offshore_sfincs_model().get_model_root()
34
- )
35
- self.scenario = scenario
36
- if isinstance(event, EventSet):
37
- raise ValueError(
38
- "OffshoreSfincsHandler does not support EventSets. Provide the sub events directly "
39
- )
40
- self.event = event
41
-
42
- def get_resulting_waterlevels(self) -> pd.DataFrame:
43
- """Get the water levels from the offshore model.
44
-
45
- Note that the returned water levels are relative to the reference datum of the offshore model.
46
- To convert to a different datum, add the offshore reference datum height and subtract the desired reference datum height.
47
-
48
- Returns
49
- -------
50
- pd.DataFrame
51
- A DataFrame with the water levels for each boundary condition point. Relative to the reference datum of the offshore model.
52
-
53
- """
54
- path = self._get_simulation_path()
55
- if not self.requires_offshore_run(self.event):
56
- raise ValueError("Offshore model is not required for this event")
57
-
58
- self.run_offshore()
59
-
60
- with SfincsAdapter(model_root=path) as offshore_model:
61
- waterlevels = offshore_model.get_wl_df_from_offshore_his_results()
62
-
63
- return waterlevels
64
-
65
- @staticmethod
66
- def requires_offshore_run(event: Event) -> bool:
67
- return any(
68
- forcing.source in [ForcingSource.MODEL, ForcingSource.TRACK]
69
- for forcing in event.get_forcings()
70
- )
71
-
72
- def run_offshore(self):
73
- """Prepare the forcings of the historical event.
74
-
75
- If the forcings require it, this function will:
76
- - preprocess and run offshore model: prepare and run the offshore model to obtain water levels for the boundary condition of the nearshore model.
77
-
78
- """
79
- sim_path = self._get_simulation_path()
80
-
81
- sim_path.mkdir(parents=True, exist_ok=True)
82
- self._preprocess_sfincs_offshore()
83
- self._execute_sfincs_offshore(sim_path)
84
-
85
- def _preprocess_sfincs_offshore(self):
86
- """Preprocess offshore model to obtain water levels for boundary condition of the nearshore model.
87
-
88
- This function is reused for ForcingSources: MODEL & TRACK.
89
-
90
- Args:
91
- sim_path path to the root of the offshore model
92
- """
93
- self.logger.info(
94
- f"Preparing offshore model to generate waterlevels for `{self.scenario.name}`"
95
- )
96
- sim_path = self._get_simulation_path()
97
- # SfincsAdapter.write() doesnt write the bca file apparently so we need to copy the template
98
- if sim_path.exists():
99
- shutil.rmtree(sim_path)
100
- shutil.copytree(self.template_path, sim_path)
101
-
102
- with SfincsAdapter(model_root=sim_path) as _offshore_model:
103
- if _offshore_model.sfincs_completed(sim_path):
104
- _offshore_model.logger.info(
105
- f"Skip preprocessing offshore model as it has already been run for `{self.scenario.name}`."
106
- )
107
- return
108
- # Load objects, set root & write template model
109
- _offshore_model._load_scenario_objects(self.scenario, self.event)
110
- _offshore_model.write(path_out=sim_path)
111
- _offshore_model.set_timing(self.event.time)
112
-
113
- # Add water levels
114
- _offshore_model._add_bzs_from_bca(
115
- _offshore_model._event, _offshore_model._projection.physical_projection
116
- )
117
-
118
- # Add spw if applicable
119
- track_forcings = [
120
- f
121
- for f in _offshore_model._event.get_forcings()
122
- if f.source == ForcingSource.TRACK
123
- ]
124
- if track_forcings:
125
- for forcing in track_forcings:
126
- _offshore_model.add_forcing(forcing)
127
-
128
- # Add wind and if applicable pressure forcing from meteo data
129
- elif isinstance(_offshore_model._event, HistoricalEvent):
130
- wind_forcings = [
131
- f
132
- for f in _offshore_model._event.get_forcings()
133
- if isinstance(f, IWind)
134
- ]
135
-
136
- if wind_forcings:
137
- if len(wind_forcings) > 1:
138
- raise ValueError("Only one wind forcing is allowed")
139
- wind_forcing = wind_forcings[0]
140
-
141
- # Add wind forcing
142
- if wind_forcing not in track_forcings:
143
- _offshore_model.add_forcing(wind_forcing)
144
-
145
- # Add pressure forcing for the offshore model (this doesnt happen normally in _add_forcing_wind() for overland models)
146
- if isinstance(wind_forcing, WindMeteo):
147
- ds = MeteoHandler().read(_offshore_model._event.time)
148
- _offshore_model._add_pressure_forcing_from_grid(ds=ds)
149
-
150
- # write sfincs model in output destination
151
- _offshore_model.write(path_out=sim_path)
152
-
153
- def _execute_sfincs_offshore(self, sim_path: Path):
154
- self.logger.info(f"Running offshore model in {sim_path}")
155
- sim_path = self._get_simulation_path()
156
- with SfincsAdapter(model_root=sim_path) as _offshore_model:
157
- if _offshore_model.sfincs_completed(sim_path):
158
- self.logger.info(
159
- "Skip running offshore model as it has already been run."
160
- )
161
- return
162
- try:
163
- _offshore_model.execute(path=sim_path)
164
- except RuntimeError as e:
165
- raise RuntimeError(
166
- f"Failed to run offshore model for {self.scenario.name}"
167
- ) from e
168
-
169
- def _get_simulation_path(self) -> Path:
170
- main_event = self.database.events.get(self.scenario.event)
171
- if main_event.mode == Mode.risk:
172
- return (
173
- db_path(
174
- TopLevelDir.output,
175
- object_dir=ObjectDir.scenario,
176
- obj_name=self.scenario.name,
177
- )
178
- / "Flooding"
179
- / "simulations"
180
- / self.event.name
181
- / self.template_path.name
182
- )
183
- else:
184
- return (
185
- db_path(
186
- TopLevelDir.output,
187
- object_dir=ObjectDir.scenario,
188
- obj_name=self.scenario.name,
189
- )
190
- / "Flooding"
191
- / "simulations"
192
- / self.template_path.name
193
- )
1
+ import shutil
2
+ from pathlib import Path
3
+
4
+ import pandas as pd
5
+
6
+ from flood_adapt.adapter.interface.offshore import IOffshoreSfincsHandler
7
+ from flood_adapt.adapter.sfincs_adapter import SfincsAdapter
8
+ from flood_adapt.misc.database_user import DatabaseUser
9
+ from flood_adapt.misc.log import FloodAdaptLogging
10
+ from flood_adapt.misc.path_builder import (
11
+ ObjectDir,
12
+ TopLevelDir,
13
+ db_path,
14
+ )
15
+ from flood_adapt.objects.events.event_set import EventSet
16
+ from flood_adapt.objects.events.events import Event, Mode
17
+ from flood_adapt.objects.events.historical import HistoricalEvent
18
+ from flood_adapt.objects.forcing.forcing import (
19
+ ForcingSource,
20
+ IWind,
21
+ )
22
+ from flood_adapt.objects.forcing.meteo_handler import MeteoHandler
23
+ from flood_adapt.objects.forcing.wind import WindMeteo
24
+ from flood_adapt.objects.scenarios.scenarios import Scenario
25
+
26
+
27
+ class OffshoreSfincsHandler(IOffshoreSfincsHandler, DatabaseUser):
28
+ logger = FloodAdaptLogging.getLogger("OffshoreSfincsAdapter")
29
+ template_path: Path
30
+
31
+ def __init__(self, scenario: Scenario, event: Event) -> None:
32
+ self.template_path = (
33
+ self.database.static.get_offshore_sfincs_model().get_model_root()
34
+ )
35
+ self.scenario = scenario
36
+ if isinstance(event, EventSet):
37
+ raise ValueError(
38
+ "OffshoreSfincsHandler does not support EventSets. Provide the sub events directly "
39
+ )
40
+ self.event = event
41
+
42
+ def get_resulting_waterlevels(self) -> pd.DataFrame:
43
+ """Get the water levels from the offshore model.
44
+
45
+ Note that the returned water levels are relative to the reference datum of the offshore model.
46
+ To convert to a different datum, add the offshore reference datum height and subtract the desired reference datum height.
47
+
48
+ Returns
49
+ -------
50
+ pd.DataFrame
51
+ A DataFrame with the water levels for each boundary condition point. Relative to the reference datum of the offshore model.
52
+
53
+ """
54
+ path = self._get_simulation_path()
55
+ if not self.requires_offshore_run(self.event):
56
+ raise ValueError("Offshore model is not required for this event")
57
+
58
+ self.run_offshore()
59
+
60
+ with SfincsAdapter(model_root=path) as offshore_model:
61
+ waterlevels = offshore_model.get_wl_df_from_offshore_his_results()
62
+
63
+ return waterlevels
64
+
65
+ @staticmethod
66
+ def requires_offshore_run(event: Event) -> bool:
67
+ return any(
68
+ forcing.source in [ForcingSource.MODEL, ForcingSource.TRACK]
69
+ for forcing in event.get_forcings()
70
+ )
71
+
72
+ def run_offshore(self):
73
+ """Prepare the forcings of the historical event.
74
+
75
+ If the forcings require it, this function will:
76
+ - preprocess and run offshore model: prepare and run the offshore model to obtain water levels for the boundary condition of the nearshore model.
77
+
78
+ """
79
+ sim_path = self._get_simulation_path()
80
+
81
+ sim_path.mkdir(parents=True, exist_ok=True)
82
+ self._preprocess_sfincs_offshore()
83
+ self._execute_sfincs_offshore(sim_path)
84
+
85
+ def _preprocess_sfincs_offshore(self):
86
+ """Preprocess offshore model to obtain water levels for boundary condition of the nearshore model.
87
+
88
+ This function is reused for ForcingSources: MODEL & TRACK.
89
+
90
+ Args:
91
+ sim_path path to the root of the offshore model
92
+ """
93
+ self.logger.info(
94
+ f"Preparing offshore model to generate waterlevels for `{self.scenario.name}`"
95
+ )
96
+ sim_path = self._get_simulation_path()
97
+ # SfincsAdapter.write() doesnt write the bca file apparently so we need to copy the template
98
+ if sim_path.exists():
99
+ shutil.rmtree(sim_path)
100
+ shutil.copytree(self.template_path, sim_path)
101
+
102
+ with SfincsAdapter(model_root=sim_path) as _offshore_model:
103
+ if _offshore_model.sfincs_completed(sim_path):
104
+ _offshore_model.logger.info(
105
+ f"Skip preprocessing offshore model as it has already been run for `{self.scenario.name}`."
106
+ )
107
+ return
108
+ # Load objects, set root & write template model
109
+ _offshore_model._load_scenario_objects(self.scenario, self.event)
110
+ _offshore_model.write(path_out=sim_path)
111
+ _offshore_model.set_timing(self.event.time)
112
+
113
+ # Add water levels
114
+ _offshore_model._add_bzs_from_bca(
115
+ _offshore_model._event, _offshore_model._projection.physical_projection
116
+ )
117
+
118
+ # Add spw if applicable
119
+ track_forcings = [
120
+ f
121
+ for f in _offshore_model._event.get_forcings()
122
+ if f.source == ForcingSource.TRACK
123
+ ]
124
+ if track_forcings:
125
+ for forcing in track_forcings:
126
+ _offshore_model.add_forcing(forcing)
127
+
128
+ # Add wind and if applicable pressure forcing from meteo data
129
+ elif isinstance(_offshore_model._event, HistoricalEvent):
130
+ wind_forcings = [
131
+ f
132
+ for f in _offshore_model._event.get_forcings()
133
+ if isinstance(f, IWind)
134
+ ]
135
+
136
+ if wind_forcings:
137
+ if len(wind_forcings) > 1:
138
+ raise ValueError("Only one wind forcing is allowed")
139
+ wind_forcing = wind_forcings[0]
140
+
141
+ # Add wind forcing
142
+ if wind_forcing not in track_forcings:
143
+ _offshore_model.add_forcing(wind_forcing)
144
+
145
+ # Add pressure forcing for the offshore model (this doesnt happen normally in _add_forcing_wind() for overland models)
146
+ if isinstance(wind_forcing, WindMeteo):
147
+ ds = MeteoHandler().read(_offshore_model._event.time)
148
+ _offshore_model._add_pressure_forcing_from_grid(ds=ds)
149
+
150
+ # write sfincs model in output destination
151
+ _offshore_model.write(path_out=sim_path)
152
+
153
+ def _execute_sfincs_offshore(self, sim_path: Path):
154
+ self.logger.info(f"Running offshore model in {sim_path}")
155
+ sim_path = self._get_simulation_path()
156
+ with SfincsAdapter(model_root=sim_path) as _offshore_model:
157
+ if _offshore_model.sfincs_completed(sim_path):
158
+ self.logger.info(
159
+ "Skip running offshore model as it has already been run."
160
+ )
161
+ return
162
+ try:
163
+ _offshore_model.execute(path=sim_path)
164
+ except RuntimeError as e:
165
+ raise RuntimeError(
166
+ f"Failed to run offshore model for {self.scenario.name}"
167
+ ) from e
168
+
169
+ def _get_simulation_path(self) -> Path:
170
+ main_event = self.database.events.get(self.scenario.event)
171
+ if main_event.mode == Mode.risk:
172
+ return (
173
+ db_path(
174
+ TopLevelDir.output,
175
+ object_dir=ObjectDir.scenario,
176
+ obj_name=self.scenario.name,
177
+ )
178
+ / "Flooding"
179
+ / "simulations"
180
+ / self.event.name
181
+ / self.template_path.name
182
+ )
183
+ else:
184
+ return (
185
+ db_path(
186
+ TopLevelDir.output,
187
+ object_dir=ObjectDir.scenario,
188
+ obj_name=self.scenario.name,
189
+ )
190
+ / "Flooding"
191
+ / "simulations"
192
+ / self.template_path.name
193
+ )