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.
- flood_adapt/__init__.py +22 -0
- flood_adapt/adapter/__init__.py +9 -0
- flood_adapt/adapter/fiat_adapter.py +1502 -0
- flood_adapt/adapter/interface/__init__.py +0 -0
- flood_adapt/adapter/interface/hazard_adapter.py +70 -0
- flood_adapt/adapter/interface/impact_adapter.py +36 -0
- flood_adapt/adapter/interface/model_adapter.py +89 -0
- flood_adapt/adapter/interface/offshore.py +19 -0
- flood_adapt/adapter/sfincs_adapter.py +1857 -0
- flood_adapt/adapter/sfincs_offshore.py +193 -0
- flood_adapt/config/__init__.py +0 -0
- flood_adapt/config/config.py +245 -0
- flood_adapt/config/fiat.py +219 -0
- flood_adapt/config/gui.py +224 -0
- flood_adapt/config/sfincs.py +336 -0
- flood_adapt/config/site.py +124 -0
- flood_adapt/database_builder/__init__.py +0 -0
- flood_adapt/database_builder/database_builder.py +2175 -0
- flood_adapt/database_builder/templates/default_units/imperial.toml +9 -0
- flood_adapt/database_builder/templates/default_units/metric.toml +9 -0
- flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -0
- flood_adapt/database_builder/templates/icons/black_down_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/black_left_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/black_right_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/black_up_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_down.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_left.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_right.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_up.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_down.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_left.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_right.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_up.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_left.png +0 -0
- flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_right.png +0 -0
- flood_adapt/database_builder/templates/icons/white_down_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/white_left_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/white_right_48x48.png +0 -0
- flood_adapt/database_builder/templates/icons/white_up_48x48.png +0 -0
- flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -0
- flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -0
- flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -0
- flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -0
- flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -0
- flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -0
- flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -0
- flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -0
- flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -0
- flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -0
- flood_adapt/database_builder/templates/infographics/images/ambulance.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/car.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/cart.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/firetruck.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/hospital.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/house.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/info.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/money.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/person.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/school.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/truck.png +0 -0
- flood_adapt/database_builder/templates/infographics/images/walking_person.png +0 -0
- flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -0
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -0
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -0
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -0
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -0
- flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -0
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -0
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -0
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -0
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -0
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -0
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -0
- flood_adapt/database_builder/templates/mapbox_layers/bin_colors.toml +5 -0
- flood_adapt/database_builder.py +16 -0
- flood_adapt/dbs_classes/__init__.py +21 -0
- flood_adapt/dbs_classes/database.py +716 -0
- flood_adapt/dbs_classes/dbs_benefit.py +97 -0
- flood_adapt/dbs_classes/dbs_event.py +91 -0
- flood_adapt/dbs_classes/dbs_measure.py +103 -0
- flood_adapt/dbs_classes/dbs_projection.py +52 -0
- flood_adapt/dbs_classes/dbs_scenario.py +150 -0
- flood_adapt/dbs_classes/dbs_static.py +261 -0
- flood_adapt/dbs_classes/dbs_strategy.py +147 -0
- flood_adapt/dbs_classes/dbs_template.py +302 -0
- flood_adapt/dbs_classes/interface/database.py +147 -0
- flood_adapt/dbs_classes/interface/element.py +137 -0
- flood_adapt/dbs_classes/interface/static.py +47 -0
- flood_adapt/flood_adapt.py +1371 -0
- flood_adapt/misc/__init__.py +0 -0
- flood_adapt/misc/database_user.py +16 -0
- flood_adapt/misc/log.py +183 -0
- flood_adapt/misc/path_builder.py +54 -0
- flood_adapt/misc/utils.py +185 -0
- flood_adapt/objects/__init__.py +59 -0
- flood_adapt/objects/benefits/__init__.py +0 -0
- flood_adapt/objects/benefits/benefits.py +61 -0
- flood_adapt/objects/events/__init__.py +0 -0
- flood_adapt/objects/events/event_factory.py +135 -0
- flood_adapt/objects/events/event_set.py +84 -0
- flood_adapt/objects/events/events.py +221 -0
- flood_adapt/objects/events/historical.py +55 -0
- flood_adapt/objects/events/hurricane.py +64 -0
- flood_adapt/objects/events/synthetic.py +48 -0
- flood_adapt/objects/forcing/__init__.py +0 -0
- flood_adapt/objects/forcing/csv.py +68 -0
- flood_adapt/objects/forcing/discharge.py +66 -0
- flood_adapt/objects/forcing/forcing.py +142 -0
- flood_adapt/objects/forcing/forcing_factory.py +182 -0
- flood_adapt/objects/forcing/meteo_handler.py +93 -0
- flood_adapt/objects/forcing/netcdf.py +40 -0
- flood_adapt/objects/forcing/plotting.py +428 -0
- flood_adapt/objects/forcing/rainfall.py +98 -0
- flood_adapt/objects/forcing/tide_gauge.py +191 -0
- flood_adapt/objects/forcing/time_frame.py +77 -0
- flood_adapt/objects/forcing/timeseries.py +552 -0
- flood_adapt/objects/forcing/unit_system.py +580 -0
- flood_adapt/objects/forcing/waterlevels.py +108 -0
- flood_adapt/objects/forcing/wind.py +124 -0
- flood_adapt/objects/measures/__init__.py +0 -0
- flood_adapt/objects/measures/measure_factory.py +92 -0
- flood_adapt/objects/measures/measures.py +506 -0
- flood_adapt/objects/object_model.py +68 -0
- flood_adapt/objects/projections/__init__.py +0 -0
- flood_adapt/objects/projections/projections.py +89 -0
- flood_adapt/objects/scenarios/__init__.py +0 -0
- flood_adapt/objects/scenarios/scenarios.py +22 -0
- flood_adapt/objects/strategies/__init__.py +0 -0
- flood_adapt/objects/strategies/strategies.py +68 -0
- flood_adapt/workflows/__init__.py +0 -0
- flood_adapt/workflows/benefit_runner.py +541 -0
- flood_adapt/workflows/floodmap.py +85 -0
- flood_adapt/workflows/impacts_integrator.py +82 -0
- flood_adapt/workflows/scenario_runner.py +69 -0
- flood_adapt-0.3.0.dist-info/LICENSE +21 -0
- flood_adapt-0.3.0.dist-info/METADATA +183 -0
- flood_adapt-0.3.0.dist-info/RECORD +139 -0
- flood_adapt-0.3.0.dist-info/WHEEL +5 -0
- flood_adapt-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from tomli import load as load_toml
|
|
6
|
+
|
|
7
|
+
from flood_adapt.config.fiat import DamageType
|
|
8
|
+
from flood_adapt.objects.forcing import unit_system as us
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MapboxLayersModel(BaseModel):
|
|
12
|
+
"""The configuration of the mapbox layers in the gui.
|
|
13
|
+
|
|
14
|
+
Attributes
|
|
15
|
+
----------
|
|
16
|
+
buildings_min_zoom_level : int
|
|
17
|
+
The minimum zoom level for the buildings layer.
|
|
18
|
+
flood_map_depth_min : float
|
|
19
|
+
The minimum depth for the flood map layer.
|
|
20
|
+
flood_map_zbmax : float
|
|
21
|
+
The maximum depth for the flood map layer.
|
|
22
|
+
flood_map_bins : list[float]
|
|
23
|
+
The bins for the flood map layer.
|
|
24
|
+
flood_map_colors : list[str]
|
|
25
|
+
The colors for the flood map layer.
|
|
26
|
+
aggregation_dmg_bins : list[float]
|
|
27
|
+
The bins for the aggregation damage layer.
|
|
28
|
+
aggregation_dmg_colors : list[str]
|
|
29
|
+
The colors for the aggregation damage layer.
|
|
30
|
+
footprints_dmg_type : DamageType
|
|
31
|
+
The type of damage for the footprints layer.
|
|
32
|
+
footprints_dmg_bins : list[float]
|
|
33
|
+
The bins for the footprints layer.
|
|
34
|
+
footprints_dmg_colors : list[str]
|
|
35
|
+
The colors for the footprints layer.
|
|
36
|
+
svi_bins : Optional[list[float]]
|
|
37
|
+
The bins for the SVI layer.
|
|
38
|
+
svi_colors : Optional[list[str]]
|
|
39
|
+
The colors for the SVI layer.
|
|
40
|
+
benefits_bins : list[float]
|
|
41
|
+
The bins for the benefits layer.
|
|
42
|
+
benefits_colors : list[str]
|
|
43
|
+
The colors for the benefits layer.
|
|
44
|
+
benefits_threshold : Optional[float], default=None
|
|
45
|
+
The threshold for the benefits layer.
|
|
46
|
+
damage_decimals : Optional[int], default=0
|
|
47
|
+
The number of decimals for the damage layer.
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
buildings_min_zoom_level: int = 13
|
|
52
|
+
flood_map_depth_min: float
|
|
53
|
+
flood_map_zbmax: float
|
|
54
|
+
flood_map_bins: list[float]
|
|
55
|
+
flood_map_colors: list[str]
|
|
56
|
+
aggregation_dmg_bins: list[float]
|
|
57
|
+
aggregation_dmg_colors: list[str]
|
|
58
|
+
footprints_dmg_type: DamageType = DamageType.absolute
|
|
59
|
+
footprints_dmg_bins: list[float]
|
|
60
|
+
footprints_dmg_colors: list[str]
|
|
61
|
+
svi_bins: Optional[list[float]] = Field(default_factory=list)
|
|
62
|
+
svi_colors: Optional[list[str]] = Field(default_factory=list)
|
|
63
|
+
benefits_bins: list[float]
|
|
64
|
+
benefits_colors: list[str]
|
|
65
|
+
benefits_threshold: Optional[float] = None
|
|
66
|
+
damage_decimals: Optional[int] = 0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class VisualizationLayersModel(BaseModel):
|
|
70
|
+
"""The configuration of the layers you might want to visualize in the gui.
|
|
71
|
+
|
|
72
|
+
Attributes
|
|
73
|
+
----------
|
|
74
|
+
default_bin_number : int
|
|
75
|
+
The default number of bins for the visualization layers.
|
|
76
|
+
default_colors : list[str]
|
|
77
|
+
The default colors for the visualization layers.
|
|
78
|
+
layer_names : list[str]
|
|
79
|
+
The names of the layers to visualize.
|
|
80
|
+
layer_long_names : list[str]
|
|
81
|
+
The long names of the layers to visualize.
|
|
82
|
+
layer_paths : list[str]
|
|
83
|
+
The paths to the layers to visualize.
|
|
84
|
+
field_names : list[str]
|
|
85
|
+
The field names of the layers to visualize.
|
|
86
|
+
bins : Optional[list[list[float]]]
|
|
87
|
+
The bins for the layers to visualize.
|
|
88
|
+
colors : Optional[list[list[str]]]
|
|
89
|
+
The colors for the layers to visualize.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
# TODO add check for default_bin_number and default_colors to have the same length
|
|
93
|
+
default_bin_number: int
|
|
94
|
+
default_colors: list[str]
|
|
95
|
+
layer_names: list[str] = Field(default_factory=list)
|
|
96
|
+
layer_long_names: list[str] = Field(default_factory=list)
|
|
97
|
+
layer_paths: list[str] = Field(default_factory=list)
|
|
98
|
+
field_names: list[str] = Field(default_factory=list)
|
|
99
|
+
bins: Optional[list[list[float]]] = Field(default_factory=list)
|
|
100
|
+
colors: Optional[list[list[str]]] = Field(default_factory=list)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class GuiUnitModel(BaseModel):
|
|
104
|
+
"""The unit system used in the GUI.
|
|
105
|
+
|
|
106
|
+
Attributes
|
|
107
|
+
----------
|
|
108
|
+
default_length_units : us.UnitTypesLength
|
|
109
|
+
The length units used in the GUI.
|
|
110
|
+
default_distance_units : us.UnitTypesLength
|
|
111
|
+
The distance units used in the GUI.
|
|
112
|
+
default_area_units : us.UnitTypesArea
|
|
113
|
+
The area units used in the GUI.
|
|
114
|
+
default_volume_units : us.UnitTypesVolume
|
|
115
|
+
The volume units used in the GUI.
|
|
116
|
+
default_velocity_units : us.UnitTypesVelocity
|
|
117
|
+
The velocity units used in the GUI.
|
|
118
|
+
default_direction_units : us.UnitTypesDirection
|
|
119
|
+
The direction units used in the GUI.
|
|
120
|
+
default_discharge_units : us.UnitTypesDischarge
|
|
121
|
+
The discharge units used in the GUI.
|
|
122
|
+
default_intensity_units : us.UnitTypesIntensity
|
|
123
|
+
The intensity units used in the GUI.
|
|
124
|
+
default_cumulative_units : us.UnitTypesLength
|
|
125
|
+
The cumulative units used in the GUI.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
default_length_units: us.UnitTypesLength
|
|
129
|
+
default_distance_units: us.UnitTypesLength
|
|
130
|
+
default_area_units: us.UnitTypesArea
|
|
131
|
+
default_volume_units: us.UnitTypesVolume
|
|
132
|
+
default_velocity_units: us.UnitTypesVelocity
|
|
133
|
+
default_direction_units: us.UnitTypesDirection
|
|
134
|
+
default_discharge_units: us.UnitTypesDischarge
|
|
135
|
+
default_intensity_units: us.UnitTypesIntensity
|
|
136
|
+
default_cumulative_units: us.UnitTypesLength
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def imperial() -> "GuiUnitModel":
|
|
140
|
+
return GuiUnitModel(
|
|
141
|
+
default_length_units=us.UnitTypesLength.feet,
|
|
142
|
+
default_distance_units=us.UnitTypesLength.miles,
|
|
143
|
+
default_area_units=us.UnitTypesArea.sf,
|
|
144
|
+
default_volume_units=us.UnitTypesVolume.cf,
|
|
145
|
+
default_velocity_units=us.UnitTypesVelocity.mph,
|
|
146
|
+
default_direction_units=us.UnitTypesDirection.degrees,
|
|
147
|
+
default_discharge_units=us.UnitTypesDischarge.cfs,
|
|
148
|
+
default_intensity_units=us.UnitTypesIntensity.inch_hr,
|
|
149
|
+
default_cumulative_units=us.UnitTypesLength.inch,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def metric() -> "GuiUnitModel":
|
|
154
|
+
return GuiUnitModel(
|
|
155
|
+
default_length_units=us.UnitTypesLength.meters,
|
|
156
|
+
default_distance_units=us.UnitTypesLength.meters,
|
|
157
|
+
default_area_units=us.UnitTypesArea.m2,
|
|
158
|
+
default_volume_units=us.UnitTypesVolume.m3,
|
|
159
|
+
default_velocity_units=us.UnitTypesVelocity.mps,
|
|
160
|
+
default_direction_units=us.UnitTypesDirection.degrees,
|
|
161
|
+
default_discharge_units=us.UnitTypesDischarge.cms,
|
|
162
|
+
default_intensity_units=us.UnitTypesIntensity.mm_hr,
|
|
163
|
+
default_cumulative_units=us.UnitTypesLength.millimeters,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class SyntheticTideModel(BaseModel):
|
|
168
|
+
"""Configuration for the synthetic tide.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
harmonic_amplitude : us.UnitfulLength
|
|
173
|
+
The amplitude of the tide harmonic relative to the datum.
|
|
174
|
+
datum : str
|
|
175
|
+
The datum to which the harmonic amplitude is relative.
|
|
176
|
+
Should be a datum defined in `site.sfincs.waterlevels.datums`
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
harmonic_amplitude: us.UnitfulLength
|
|
180
|
+
datum: str
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class PlottingModel(BaseModel):
|
|
184
|
+
"""
|
|
185
|
+
The configuration of the plotting in the gui.
|
|
186
|
+
|
|
187
|
+
Attributes
|
|
188
|
+
----------
|
|
189
|
+
excluded_datums : list[str]
|
|
190
|
+
A list of datums that will be excluded from the forcing plot in event windows.
|
|
191
|
+
synthetic_tide : SyntheticTideModel
|
|
192
|
+
The configuration of the synthetic tide.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
synthetic_tide: SyntheticTideModel
|
|
196
|
+
excluded_datums: list[str] = Field(default_factory=list)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class GuiModel(BaseModel):
|
|
200
|
+
"""The accepted input for the variable gui in Site.
|
|
201
|
+
|
|
202
|
+
Attributes
|
|
203
|
+
----------
|
|
204
|
+
units : GuiUnitModel
|
|
205
|
+
The unit system used in the GUI.
|
|
206
|
+
mapbox_layers : MapboxLayersModel
|
|
207
|
+
The configuration of the mapbox layers in the GUI.
|
|
208
|
+
visualization_layers : VisualizationLayersModel
|
|
209
|
+
The configuration of the visualization layers in the GUI.
|
|
210
|
+
plotting : PlottingModel
|
|
211
|
+
The configuration for creating hazard forcing plots.
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
units: GuiUnitModel
|
|
215
|
+
mapbox_layers: MapboxLayersModel
|
|
216
|
+
visualization_layers: VisualizationLayersModel
|
|
217
|
+
plotting: PlottingModel
|
|
218
|
+
|
|
219
|
+
@staticmethod
|
|
220
|
+
def read_toml(path: Path) -> "GuiModel":
|
|
221
|
+
with open(path, mode="rb") as fp:
|
|
222
|
+
toml_contents = load_toml(fp)
|
|
223
|
+
|
|
224
|
+
return GuiModel(**toml_contents)
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import AfterValidator, BaseModel, Field, model_validator
|
|
7
|
+
from tomli import load as load_toml
|
|
8
|
+
from typing_extensions import Annotated
|
|
9
|
+
|
|
10
|
+
from flood_adapt.objects.forcing import unit_system as us
|
|
11
|
+
from flood_adapt.objects.forcing.tide_gauge import TideGauge
|
|
12
|
+
from flood_adapt.objects.forcing.timeseries import Scstype
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def ensure_ascii(s: str):
|
|
16
|
+
assert s.isascii()
|
|
17
|
+
return s
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
AsciiStr = Annotated[str, AfterValidator(ensure_ascii)]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Cstype(str, Enum):
|
|
24
|
+
"""The accepted input for the variable cstype in Site."""
|
|
25
|
+
|
|
26
|
+
projected = "projected"
|
|
27
|
+
spherical = "spherical"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SCSModel(BaseModel):
|
|
31
|
+
"""Class describing the accepted input for the variable scs.
|
|
32
|
+
|
|
33
|
+
Includes the file with the non-dimensional SCS rainfall curves in the site folder and the SCS rainfall curve type.
|
|
34
|
+
|
|
35
|
+
Attributes
|
|
36
|
+
----------
|
|
37
|
+
file : str
|
|
38
|
+
The path to the SCS rainfall curves file.
|
|
39
|
+
type : Scstype
|
|
40
|
+
The type of the SCS rainfall curve.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
file: str
|
|
44
|
+
type: Scstype
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class RiverModel(BaseModel):
|
|
48
|
+
"""Model that describes the accepted input for the variable river in Site.
|
|
49
|
+
|
|
50
|
+
Attributes
|
|
51
|
+
----------
|
|
52
|
+
name : str
|
|
53
|
+
The name of the river.
|
|
54
|
+
description : Optional[str], default=None
|
|
55
|
+
description of the river.
|
|
56
|
+
mean_discharge : us.UnitfulDischarge
|
|
57
|
+
The mean discharge of the river.
|
|
58
|
+
x_coordinate : float
|
|
59
|
+
The x coordinate of the river.
|
|
60
|
+
y_coordinate : float
|
|
61
|
+
The y coordinate of the river.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
name: str
|
|
65
|
+
description: Optional[str] = None
|
|
66
|
+
mean_discharge: us.UnitfulDischarge
|
|
67
|
+
x_coordinate: float
|
|
68
|
+
y_coordinate: float
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ObsPointModel(BaseModel):
|
|
72
|
+
"""The accepted input for the variable obs_point in Site.
|
|
73
|
+
|
|
74
|
+
obs_points is used to define output locations in the hazard model, which will be plotted in the user interface.
|
|
75
|
+
|
|
76
|
+
Attributes
|
|
77
|
+
----------
|
|
78
|
+
name : Union[int, AsciiStr]
|
|
79
|
+
The name of the observation point.
|
|
80
|
+
description : Optional[str], default=""
|
|
81
|
+
The description of the observation point.
|
|
82
|
+
ID : Optional[int], default=None
|
|
83
|
+
The ID of the observation point.
|
|
84
|
+
file : Optional[str], default=None
|
|
85
|
+
The path to the observation point data file.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
name: Union[int, AsciiStr]
|
|
89
|
+
description: Optional[str] = ""
|
|
90
|
+
ID: Optional[int] = (
|
|
91
|
+
None # if the observation station is also a tide gauge, this ID should be the same as for obs_station
|
|
92
|
+
)
|
|
93
|
+
file: Optional[str] = None # for locally stored data
|
|
94
|
+
lat: float
|
|
95
|
+
lon: float
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class FloodFrequencyModel(BaseModel):
|
|
99
|
+
"""The accepted input for the variable flood_frequency in Site."""
|
|
100
|
+
|
|
101
|
+
flooding_threshold: us.UnitfulLength
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class DemModel(BaseModel):
|
|
105
|
+
"""The accepted input for the variable dem in Site.
|
|
106
|
+
|
|
107
|
+
Attributes
|
|
108
|
+
----------
|
|
109
|
+
filename : str
|
|
110
|
+
The path to the digital elevation model file.
|
|
111
|
+
units : us.UnitTypesLength
|
|
112
|
+
The units of the digital elevation model file.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
filename: str
|
|
116
|
+
units: us.UnitTypesLength
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class FloodmapType(str, Enum):
|
|
120
|
+
"""The accepted input for the variable floodmap in Site."""
|
|
121
|
+
|
|
122
|
+
water_level = "water_level"
|
|
123
|
+
water_depth = "water_depth"
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class DatumModel(BaseModel):
|
|
127
|
+
"""
|
|
128
|
+
The accepted input for the variable datums in WaterlevelReferenceModel.
|
|
129
|
+
|
|
130
|
+
Attributes
|
|
131
|
+
----------
|
|
132
|
+
name : str
|
|
133
|
+
The name of the vertical reference model.
|
|
134
|
+
height : us.UnitfulLength
|
|
135
|
+
The height of the vertical reference model relative to the main reference.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
name: str
|
|
139
|
+
height: us.UnitfulLength
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class WaterlevelReferenceModel(BaseModel):
|
|
143
|
+
"""The accepted input for the variable water_level in Site.
|
|
144
|
+
|
|
145
|
+
Waterlevels timeseries are calculated from user input, assumed to be relative to the `reference` vertical reference model.
|
|
146
|
+
|
|
147
|
+
For plotting in the GUI, the `reference` vertical reference model is used as the main zero-reference, all values are relative to this.
|
|
148
|
+
All other vertical reference models are plotted as dashed lines.
|
|
149
|
+
|
|
150
|
+
Attributes
|
|
151
|
+
----------
|
|
152
|
+
reference : str
|
|
153
|
+
The name of the vertical reference model that is used as the main zero-reference.
|
|
154
|
+
datums : list[DatumModel]
|
|
155
|
+
The vertical reference models that are used to calculate the waterlevels timeseries.
|
|
156
|
+
The datums are used to calculate the waterlevels timeseries, which are relative to the `reference` vertical reference model.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
reference: str
|
|
160
|
+
datums: list[DatumModel] = Field(default_factory=list)
|
|
161
|
+
|
|
162
|
+
def get_datum(self, name: str) -> DatumModel:
|
|
163
|
+
for datum in self.datums:
|
|
164
|
+
if datum.name == name:
|
|
165
|
+
return datum
|
|
166
|
+
raise ValueError(f"Could not find datum with name {name}")
|
|
167
|
+
|
|
168
|
+
@model_validator(mode="after")
|
|
169
|
+
def main_reference_should_be_in_datums_and_eq_zero(self):
|
|
170
|
+
if self.reference not in [datum.name for datum in self.datums]:
|
|
171
|
+
raise ValueError(f"Reference {self.reference} not in {self.datums}")
|
|
172
|
+
if not math.isclose(
|
|
173
|
+
self.get_datum(self.reference).height.value, 0, abs_tol=1e-6
|
|
174
|
+
):
|
|
175
|
+
raise ValueError(f"Reference {self.reference} height is not zero")
|
|
176
|
+
return self
|
|
177
|
+
|
|
178
|
+
@model_validator(mode="after")
|
|
179
|
+
def all_datums_should_have_unique_names(self):
|
|
180
|
+
datum_names = [datum.name for datum in self.datums]
|
|
181
|
+
if len(set(datum_names)) != len(datum_names):
|
|
182
|
+
raise ValueError(f"Duplicate datum names found: {datum_names}")
|
|
183
|
+
return self
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class CycloneTrackDatabaseModel(BaseModel):
|
|
187
|
+
"""The accepted input for the variable cyclone_track_database in Site.
|
|
188
|
+
|
|
189
|
+
Attributes
|
|
190
|
+
----------
|
|
191
|
+
file : str
|
|
192
|
+
The path to the cyclone track database file.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
file: str
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class SlrScenariosModel(BaseModel):
|
|
199
|
+
"""The accepted input for the variable slr_scenarios.
|
|
200
|
+
|
|
201
|
+
Attributes
|
|
202
|
+
----------
|
|
203
|
+
file : str
|
|
204
|
+
The path to the sea level rise scenarios file.
|
|
205
|
+
relative_to_year : int
|
|
206
|
+
The year to which the sea level rise scenarios are relative.
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
file: str
|
|
210
|
+
relative_to_year: int
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class FloodModel(BaseModel):
|
|
214
|
+
"""The accepted input for the variable overland_model and offshore_model in Site.
|
|
215
|
+
|
|
216
|
+
Attributes
|
|
217
|
+
----------
|
|
218
|
+
name : str
|
|
219
|
+
The name of the directory in `static/templates/<directory>` that contains the template model files.
|
|
220
|
+
reference : str
|
|
221
|
+
The name of the vertical reference model that is used as the reference datum. Should be defined in water_level.datums.
|
|
222
|
+
vertical_offset : Optional[us.UnitfulLength], default = None
|
|
223
|
+
The vertical offset of the vertical reference model relative to the main reference.
|
|
224
|
+
Given that the height of the vertical reference model is often determined by external sources,
|
|
225
|
+
this vertical offset can be used to correct systematic over-/underestimation of a vertical reference model.
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
name: str
|
|
229
|
+
reference: str
|
|
230
|
+
|
|
231
|
+
# this used to be water_level_offset from events
|
|
232
|
+
vertical_offset: Optional[us.UnitfulLength] = None
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class SfincsConfigModel(BaseModel):
|
|
236
|
+
"""The expected variables and data types of attributes of the SfincsConfig class.
|
|
237
|
+
|
|
238
|
+
Attributes
|
|
239
|
+
----------
|
|
240
|
+
csname : str
|
|
241
|
+
The name of the CS model.
|
|
242
|
+
cstype : Cstype
|
|
243
|
+
Cstype of the CS model. must be either "projected" or "spherical".
|
|
244
|
+
version : Optional[str], default = None
|
|
245
|
+
The version of the CS model. If None, the version is not specified.
|
|
246
|
+
offshore_model : Optional[FloodModel], default = None
|
|
247
|
+
The offshore model. If None, the offshore model is not specified.
|
|
248
|
+
overland_model : FloodModel
|
|
249
|
+
The overland model. This is the main model used for the simulation.
|
|
250
|
+
floodmap_units : us.UnitTypesLength
|
|
251
|
+
The units used for the output floodmap. Sfincs always produces in metric units, this is used to convert the floodmap to the correct units.
|
|
252
|
+
save_simulation : Optional[bool], default = False
|
|
253
|
+
Whether to keep or delete the simulation files after the simulation is finished and all output files are created.
|
|
254
|
+
If True, the simulation files are kept. If False, the simulation files are deleted.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
csname: str
|
|
258
|
+
cstype: Cstype
|
|
259
|
+
version: Optional[str] = None
|
|
260
|
+
offshore_model: Optional[FloodModel] = None
|
|
261
|
+
overland_model: FloodModel
|
|
262
|
+
floodmap_units: us.UnitTypesLength
|
|
263
|
+
save_simulation: Optional[bool] = False
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class SfincsModel(BaseModel):
|
|
267
|
+
"""The expected variables and data types of attributes of the Sfincs class.
|
|
268
|
+
|
|
269
|
+
Attributes
|
|
270
|
+
----------
|
|
271
|
+
config : SfincsConfigModel
|
|
272
|
+
The configuration of the Sfincs model.
|
|
273
|
+
water_level : WaterlevelReferenceModel
|
|
274
|
+
The collection of all datums and the main reference datum.
|
|
275
|
+
dem : DemModel
|
|
276
|
+
The digital elevation model.
|
|
277
|
+
flood_frequency : FloodFrequencyModel, default = FloodFrequencyModel()
|
|
278
|
+
The flood frequency model.
|
|
279
|
+
slr : SlrScenariosModel
|
|
280
|
+
Specification of the sea level rise scenarios.
|
|
281
|
+
cyclone_track_database : CycloneTrackDatabaseModel, optional, default = None
|
|
282
|
+
The cyclone track database model.
|
|
283
|
+
scs : SCSModel, optional, default = None
|
|
284
|
+
The SCS model.
|
|
285
|
+
tide_gauge : TideGauge, optional, default = None
|
|
286
|
+
The tide gauge model.
|
|
287
|
+
river : list[RiverModel], optional, default = None
|
|
288
|
+
The river model.
|
|
289
|
+
obs_point : list[ObsPointModel], optional, default = None
|
|
290
|
+
The observation point model.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
config: SfincsConfigModel
|
|
294
|
+
water_level: WaterlevelReferenceModel
|
|
295
|
+
cyclone_track_database: Optional[CycloneTrackDatabaseModel] = None
|
|
296
|
+
slr_scenarios: Optional[SlrScenariosModel] = None
|
|
297
|
+
scs: Optional[SCSModel] = None # optional for the US to use SCS rainfall curves
|
|
298
|
+
dem: DemModel
|
|
299
|
+
|
|
300
|
+
flood_frequency: FloodFrequencyModel = FloodFrequencyModel(
|
|
301
|
+
flooding_threshold=us.UnitfulLength(value=0.0, units=us.UnitTypesLength.meters)
|
|
302
|
+
) # TODO we dont actually use this anywhere?
|
|
303
|
+
|
|
304
|
+
tide_gauge: Optional[TideGauge] = None
|
|
305
|
+
river: Optional[list[RiverModel]] = None
|
|
306
|
+
obs_point: Optional[list[ObsPointModel]] = None
|
|
307
|
+
|
|
308
|
+
@staticmethod
|
|
309
|
+
def read_toml(path: Path) -> "SfincsModel":
|
|
310
|
+
with open(path, mode="rb") as fp:
|
|
311
|
+
toml_contents = load_toml(fp)
|
|
312
|
+
|
|
313
|
+
return SfincsModel(**toml_contents)
|
|
314
|
+
|
|
315
|
+
@model_validator(mode="after")
|
|
316
|
+
def ensure_references_exist(self):
|
|
317
|
+
datum_names = [d.name for d in self.water_level.datums]
|
|
318
|
+
|
|
319
|
+
if self.config.overland_model.reference not in datum_names:
|
|
320
|
+
raise ValueError(
|
|
321
|
+
f"Could not find reference `{self.config.overland_model.reference}` in available datums: {datum_names}."
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
if self.config.offshore_model is not None:
|
|
325
|
+
if self.config.offshore_model.reference not in datum_names:
|
|
326
|
+
raise ValueError(
|
|
327
|
+
f"Could not find reference `{self.config.offshore_model.reference}` in available datums: {datum_names}."
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
if self.tide_gauge is not None:
|
|
331
|
+
if self.tide_gauge.reference not in datum_names:
|
|
332
|
+
raise ValueError(
|
|
333
|
+
f"Could not find reference `{self.tide_gauge.reference}` in available datums: {datum_names}."
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
return self
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Literal, Union
|
|
4
|
+
|
|
5
|
+
import tomli
|
|
6
|
+
import tomli_w
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
from flood_adapt.config.fiat import FiatModel
|
|
10
|
+
from flood_adapt.config.gui import GuiModel
|
|
11
|
+
from flood_adapt.config.sfincs import SfincsModel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StandardObjectModel(BaseModel):
|
|
15
|
+
"""The accepted input for the variable standard_object in Site."""
|
|
16
|
+
|
|
17
|
+
events: list[str] = Field(default_factory=list)
|
|
18
|
+
projections: list[str] = Field(default_factory=list)
|
|
19
|
+
strategies: list[str] = Field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Site(BaseModel):
|
|
23
|
+
"""The expected variables and data types of attributes of the Site class.
|
|
24
|
+
|
|
25
|
+
Attributes
|
|
26
|
+
----------
|
|
27
|
+
name : str
|
|
28
|
+
Name of the site.
|
|
29
|
+
description : str, default=""
|
|
30
|
+
Description of the site.
|
|
31
|
+
lat : float
|
|
32
|
+
Latitude of the site.
|
|
33
|
+
lon : float
|
|
34
|
+
Longitude of the site.
|
|
35
|
+
standard_objects : StandardObjectModel, default=StandardObjectModel()
|
|
36
|
+
Standard objects of the site.
|
|
37
|
+
gui : GuiModel
|
|
38
|
+
GUI model of the site.
|
|
39
|
+
sfincs : SfincsModel
|
|
40
|
+
SFincs model of the site.
|
|
41
|
+
fiat : FiatModel
|
|
42
|
+
Fiat model of the site.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
name: str
|
|
46
|
+
description: str = ""
|
|
47
|
+
lat: float
|
|
48
|
+
lon: float
|
|
49
|
+
standard_objects: StandardObjectModel = StandardObjectModel()
|
|
50
|
+
|
|
51
|
+
gui: GuiModel
|
|
52
|
+
sfincs: SfincsModel
|
|
53
|
+
fiat: FiatModel
|
|
54
|
+
|
|
55
|
+
def save(
|
|
56
|
+
self,
|
|
57
|
+
filepath: Union[str, os.PathLike],
|
|
58
|
+
sfincs: str = "sfincs.toml",
|
|
59
|
+
fiat: str = "fiat.toml",
|
|
60
|
+
gui: str = "gui.toml",
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Write toml file from model object."""
|
|
63
|
+
parent_folder = Path(filepath).parent
|
|
64
|
+
config_dict = {
|
|
65
|
+
"name": self.name,
|
|
66
|
+
"description": self.description,
|
|
67
|
+
"lat": self.lat,
|
|
68
|
+
"lon": self.lon,
|
|
69
|
+
"components": {},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if self.sfincs is not None:
|
|
73
|
+
config_dict["components"]["sfincs"] = sfincs
|
|
74
|
+
with open(parent_folder / sfincs, "wb") as f:
|
|
75
|
+
tomli_w.dump(self.sfincs.model_dump(exclude_none=True), f)
|
|
76
|
+
|
|
77
|
+
if self.fiat is not None:
|
|
78
|
+
config_dict["components"]["fiat"] = fiat
|
|
79
|
+
with open(parent_folder / fiat, "wb") as f:
|
|
80
|
+
tomli_w.dump(self.fiat.model_dump(exclude_none=True), f)
|
|
81
|
+
|
|
82
|
+
if self.gui is not None:
|
|
83
|
+
config_dict["components"]["gui"] = gui
|
|
84
|
+
with open(parent_folder / gui, "wb") as f:
|
|
85
|
+
tomli_w.dump(self.gui.model_dump(exclude_none=True), f)
|
|
86
|
+
|
|
87
|
+
with open(filepath, "wb") as f:
|
|
88
|
+
tomli_w.dump(config_dict, f)
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def load_file(filepath: Union[str, os.PathLike]) -> "Site":
|
|
92
|
+
"""Create Site from toml file."""
|
|
93
|
+
return SiteBuilder.load_file(Path(filepath))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class SiteBuilder(BaseModel):
|
|
97
|
+
"""Pydantic model that reads the site configuration file and builds the site model.
|
|
98
|
+
|
|
99
|
+
Note that the components are not required, as the site may not have all of them.
|
|
100
|
+
Second, note that the components are assumed to be the file names of the component configs, located in the same directory as the site configuration file.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
name: str
|
|
104
|
+
description: str = ""
|
|
105
|
+
lat: float
|
|
106
|
+
lon: float
|
|
107
|
+
components: dict[Literal["sfincs", "fiat", "gui"], str]
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def load_file(file_path: Path) -> "Site":
|
|
111
|
+
with open(file_path, "rb") as f:
|
|
112
|
+
model_dict = tomli.load(f)
|
|
113
|
+
|
|
114
|
+
toml_dir = file_path.parent
|
|
115
|
+
if (sfincs_config := model_dict["components"].get("sfincs")) is not None:
|
|
116
|
+
model_dict["sfincs"] = SfincsModel.read_toml(toml_dir / sfincs_config)
|
|
117
|
+
|
|
118
|
+
if (gui_config := model_dict["components"].get("gui")) is not None:
|
|
119
|
+
model_dict["gui"] = GuiModel.read_toml(toml_dir / gui_config)
|
|
120
|
+
|
|
121
|
+
if (fiat_config := model_dict["components"].get("fiat")) is not None:
|
|
122
|
+
model_dict["fiat"] = FiatModel.read_toml(toml_dir / fiat_config)
|
|
123
|
+
|
|
124
|
+
return Site(**model_dict)
|
|
File without changes
|