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.
- flood_adapt/__init__.py +26 -22
- flood_adapt/adapter/__init__.py +9 -9
- flood_adapt/adapter/fiat_adapter.py +1541 -1536
- flood_adapt/adapter/interface/hazard_adapter.py +70 -70
- flood_adapt/adapter/interface/impact_adapter.py +36 -36
- flood_adapt/adapter/interface/model_adapter.py +89 -89
- flood_adapt/adapter/interface/offshore.py +19 -19
- flood_adapt/adapter/sfincs_adapter.py +1848 -1846
- flood_adapt/adapter/sfincs_offshore.py +193 -193
- flood_adapt/config/config.py +248 -290
- flood_adapt/config/fiat.py +219 -219
- flood_adapt/config/gui.py +331 -331
- flood_adapt/config/sfincs.py +481 -336
- flood_adapt/config/site.py +129 -129
- flood_adapt/database_builder/database_builder.py +2210 -2210
- flood_adapt/database_builder/templates/default_units/imperial.toml +9 -9
- flood_adapt/database_builder/templates/default_units/metric.toml +9 -9
- flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -10
- flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -90
- flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -57
- flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -121
- flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -65
- flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -45
- flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -126
- flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -60
- flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -121
- flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -65
- flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -45
- flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -4
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -143
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -153
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -127
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -57
- flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -4
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -191
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -153
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -178
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -57
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -9
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -65
- flood_adapt/database_builder/templates/output_layers/bin_colors.toml +5 -5
- flood_adapt/database_builder.py +16 -16
- flood_adapt/dbs_classes/__init__.py +21 -21
- flood_adapt/dbs_classes/database.py +495 -688
- flood_adapt/dbs_classes/dbs_benefit.py +77 -76
- flood_adapt/dbs_classes/dbs_event.py +61 -59
- flood_adapt/dbs_classes/dbs_measure.py +112 -111
- flood_adapt/dbs_classes/dbs_projection.py +34 -34
- flood_adapt/dbs_classes/dbs_scenario.py +137 -137
- flood_adapt/dbs_classes/dbs_static.py +274 -273
- flood_adapt/dbs_classes/dbs_strategy.py +130 -129
- flood_adapt/dbs_classes/dbs_template.py +279 -278
- flood_adapt/dbs_classes/interface/database.py +107 -139
- flood_adapt/dbs_classes/interface/element.py +121 -121
- flood_adapt/dbs_classes/interface/static.py +47 -47
- flood_adapt/flood_adapt.py +1207 -1178
- flood_adapt/misc/database_user.py +16 -16
- flood_adapt/misc/exceptions.py +22 -0
- flood_adapt/misc/log.py +183 -183
- flood_adapt/misc/path_builder.py +54 -54
- flood_adapt/misc/utils.py +185 -185
- flood_adapt/objects/__init__.py +82 -82
- flood_adapt/objects/benefits/benefits.py +61 -61
- flood_adapt/objects/events/event_factory.py +135 -135
- flood_adapt/objects/events/event_set.py +88 -84
- flood_adapt/objects/events/events.py +234 -234
- flood_adapt/objects/events/historical.py +58 -58
- flood_adapt/objects/events/hurricane.py +68 -67
- flood_adapt/objects/events/synthetic.py +46 -50
- flood_adapt/objects/forcing/__init__.py +92 -92
- flood_adapt/objects/forcing/csv.py +68 -68
- flood_adapt/objects/forcing/discharge.py +66 -66
- flood_adapt/objects/forcing/forcing.py +150 -150
- flood_adapt/objects/forcing/forcing_factory.py +182 -182
- flood_adapt/objects/forcing/meteo_handler.py +93 -93
- flood_adapt/objects/forcing/netcdf.py +40 -40
- flood_adapt/objects/forcing/plotting.py +453 -429
- flood_adapt/objects/forcing/rainfall.py +98 -98
- flood_adapt/objects/forcing/tide_gauge.py +191 -191
- flood_adapt/objects/forcing/time_frame.py +90 -90
- flood_adapt/objects/forcing/timeseries.py +564 -564
- flood_adapt/objects/forcing/unit_system.py +580 -580
- flood_adapt/objects/forcing/waterlevels.py +108 -108
- flood_adapt/objects/forcing/wind.py +124 -124
- flood_adapt/objects/measures/measure_factory.py +92 -92
- flood_adapt/objects/measures/measures.py +529 -529
- flood_adapt/objects/object_model.py +74 -68
- flood_adapt/objects/projections/projections.py +103 -89
- flood_adapt/objects/scenarios/scenarios.py +22 -22
- flood_adapt/objects/strategies/strategies.py +89 -89
- flood_adapt/workflows/benefit_runner.py +579 -544
- flood_adapt/workflows/floodmap.py +85 -85
- flood_adapt/workflows/impacts_integrator.py +85 -82
- flood_adapt/workflows/scenario_runner.py +70 -70
- {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
- {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -860
- flood_adapt-0.3.10.dist-info/RECORD +140 -0
- flood_adapt-0.3.8.dist-info/RECORD +0 -139
- {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
- {flood_adapt-0.3.8.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
flood_adapt/config/sfincs.py
CHANGED
|
@@ -1,336 +1,481 @@
|
|
|
1
|
-
import math
|
|
2
|
-
from enum import Enum
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Optional, Union
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
file
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
The
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
The
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
The
|
|
84
|
-
|
|
85
|
-
The
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
""
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
reference
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
raise ValueError(f"Reference {self.reference}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
file: str
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
1
|
+
import math
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from plotly.express import line
|
|
9
|
+
from plotly.express.colors import sample_colorscale
|
|
10
|
+
from pydantic import AfterValidator, BaseModel, Field, model_validator
|
|
11
|
+
from tomli import load as load_toml
|
|
12
|
+
from typing_extensions import Annotated
|
|
13
|
+
|
|
14
|
+
from flood_adapt.objects.forcing import unit_system as us
|
|
15
|
+
from flood_adapt.objects.forcing.tide_gauge import TideGauge
|
|
16
|
+
from flood_adapt.objects.forcing.timeseries import Scstype
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def ensure_ascii(s: str):
|
|
20
|
+
assert s.isascii()
|
|
21
|
+
return s
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
AsciiStr = Annotated[str, AfterValidator(ensure_ascii)]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Cstype(str, Enum):
|
|
28
|
+
"""The accepted input for the variable cstype in Site."""
|
|
29
|
+
|
|
30
|
+
projected = "projected"
|
|
31
|
+
spherical = "spherical"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SCSModel(BaseModel):
|
|
35
|
+
"""Class describing the accepted input for the variable scs.
|
|
36
|
+
|
|
37
|
+
Includes the file with the non-dimensional SCS rainfall curves in the site folder and the SCS rainfall curve type.
|
|
38
|
+
|
|
39
|
+
Attributes
|
|
40
|
+
----------
|
|
41
|
+
file : str
|
|
42
|
+
The path to the SCS rainfall curves file.
|
|
43
|
+
type : Scstype
|
|
44
|
+
The type of the SCS rainfall curve.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
file: str
|
|
48
|
+
type: Scstype
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class RiverModel(BaseModel):
|
|
52
|
+
"""Model that describes the accepted input for the variable river in Site.
|
|
53
|
+
|
|
54
|
+
Attributes
|
|
55
|
+
----------
|
|
56
|
+
name : str
|
|
57
|
+
The name of the river.
|
|
58
|
+
description : Optional[str], default=None
|
|
59
|
+
description of the river.
|
|
60
|
+
mean_discharge : us.UnitfulDischarge
|
|
61
|
+
The mean discharge of the river.
|
|
62
|
+
x_coordinate : float
|
|
63
|
+
The x coordinate of the river.
|
|
64
|
+
y_coordinate : float
|
|
65
|
+
The y coordinate of the river.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
name: str
|
|
69
|
+
description: Optional[str] = None
|
|
70
|
+
mean_discharge: us.UnitfulDischarge
|
|
71
|
+
x_coordinate: float
|
|
72
|
+
y_coordinate: float
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ObsPointModel(BaseModel):
|
|
76
|
+
"""The accepted input for the variable obs_point in Site.
|
|
77
|
+
|
|
78
|
+
obs_points is used to define output locations in the hazard model, which will be plotted in the user interface.
|
|
79
|
+
|
|
80
|
+
Attributes
|
|
81
|
+
----------
|
|
82
|
+
name : Union[int, AsciiStr]
|
|
83
|
+
The name of the observation point.
|
|
84
|
+
description : Optional[str], default=""
|
|
85
|
+
The description of the observation point.
|
|
86
|
+
ID : Optional[int], default=None
|
|
87
|
+
The ID of the observation point.
|
|
88
|
+
file : Optional[str], default=None
|
|
89
|
+
The path to the observation point data file.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
name: Union[int, AsciiStr]
|
|
93
|
+
description: Optional[str] = ""
|
|
94
|
+
ID: Optional[int] = (
|
|
95
|
+
None # if the observation station is also a tide gauge, this ID should be the same as for obs_station
|
|
96
|
+
)
|
|
97
|
+
file: Optional[str] = None # for locally stored data
|
|
98
|
+
lat: float
|
|
99
|
+
lon: float
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class FloodFrequencyModel(BaseModel):
|
|
103
|
+
"""The accepted input for the variable flood_frequency in Site."""
|
|
104
|
+
|
|
105
|
+
flooding_threshold: us.UnitfulLength
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class DemModel(BaseModel):
|
|
109
|
+
"""The accepted input for the variable dem in Site.
|
|
110
|
+
|
|
111
|
+
Attributes
|
|
112
|
+
----------
|
|
113
|
+
filename : str
|
|
114
|
+
The path to the digital elevation model file.
|
|
115
|
+
units : us.UnitTypesLength
|
|
116
|
+
The units of the digital elevation model file.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
filename: str
|
|
120
|
+
units: us.UnitTypesLength
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class FloodmapType(str, Enum):
|
|
124
|
+
"""The accepted input for the variable floodmap in Site."""
|
|
125
|
+
|
|
126
|
+
water_level = "water_level"
|
|
127
|
+
water_depth = "water_depth"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class DatumModel(BaseModel):
|
|
131
|
+
"""
|
|
132
|
+
The accepted input for the variable datums in WaterlevelReferenceModel.
|
|
133
|
+
|
|
134
|
+
Attributes
|
|
135
|
+
----------
|
|
136
|
+
name : str
|
|
137
|
+
The name of the vertical reference model.
|
|
138
|
+
height : us.UnitfulLength
|
|
139
|
+
The height of the vertical reference model relative to the main reference.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
name: str
|
|
143
|
+
height: us.UnitfulLength
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class WaterlevelReferenceModel(BaseModel):
|
|
147
|
+
"""The accepted input for the variable water_level in Site.
|
|
148
|
+
|
|
149
|
+
Waterlevels timeseries are calculated from user input, assumed to be relative to the `reference` vertical reference model.
|
|
150
|
+
|
|
151
|
+
For plotting in the GUI, the `reference` vertical reference model is used as the main zero-reference, all values are relative to this.
|
|
152
|
+
All other vertical reference models are plotted as dashed lines.
|
|
153
|
+
|
|
154
|
+
Attributes
|
|
155
|
+
----------
|
|
156
|
+
reference : str
|
|
157
|
+
The name of the vertical reference model that is used as the main zero-reference.
|
|
158
|
+
datums : list[DatumModel]
|
|
159
|
+
The vertical reference models that are used to calculate the waterlevels timeseries.
|
|
160
|
+
The datums are used to calculate the waterlevels timeseries, which are relative to the `reference` vertical reference model.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
reference: str
|
|
164
|
+
datums: list[DatumModel] = Field(default_factory=list)
|
|
165
|
+
|
|
166
|
+
def get_datum(self, name: str) -> DatumModel:
|
|
167
|
+
for datum in self.datums:
|
|
168
|
+
if datum.name == name:
|
|
169
|
+
return datum
|
|
170
|
+
raise ValueError(f"Could not find datum with name {name}")
|
|
171
|
+
|
|
172
|
+
@model_validator(mode="after")
|
|
173
|
+
def main_reference_should_be_in_datums_and_eq_zero(self):
|
|
174
|
+
if self.reference not in [datum.name for datum in self.datums]:
|
|
175
|
+
raise ValueError(f"Reference {self.reference} not in {self.datums}")
|
|
176
|
+
if not math.isclose(
|
|
177
|
+
self.get_datum(self.reference).height.value, 0, abs_tol=1e-6
|
|
178
|
+
):
|
|
179
|
+
raise ValueError(f"Reference {self.reference} height is not zero")
|
|
180
|
+
return self
|
|
181
|
+
|
|
182
|
+
@model_validator(mode="after")
|
|
183
|
+
def all_datums_should_have_unique_names(self):
|
|
184
|
+
datum_names = [datum.name for datum in self.datums]
|
|
185
|
+
if len(set(datum_names)) != len(datum_names):
|
|
186
|
+
raise ValueError(f"Duplicate datum names found: {datum_names}")
|
|
187
|
+
return self
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class CycloneTrackDatabaseModel(BaseModel):
|
|
191
|
+
"""The accepted input for the variable cyclone_track_database in Site.
|
|
192
|
+
|
|
193
|
+
Attributes
|
|
194
|
+
----------
|
|
195
|
+
file : str
|
|
196
|
+
The path to the cyclone track database file.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
file: str
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class SlrScenariosModel(BaseModel):
|
|
203
|
+
"""The accepted input for the variable slr_scenarios.
|
|
204
|
+
|
|
205
|
+
Attributes
|
|
206
|
+
----------
|
|
207
|
+
file : str
|
|
208
|
+
The path to the sea level rise scenarios file.
|
|
209
|
+
relative_to_year : int
|
|
210
|
+
The year to which the sea level rise scenarios are relative.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
file: str
|
|
214
|
+
relative_to_year: int
|
|
215
|
+
|
|
216
|
+
def interp_slr(
|
|
217
|
+
self,
|
|
218
|
+
scenario: str,
|
|
219
|
+
year: float,
|
|
220
|
+
units: us.UnitTypesLength = us.UnitTypesLength.meters,
|
|
221
|
+
) -> float:
|
|
222
|
+
"""Interpolate SLR value and reference it to the SLR reference year from the site toml.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
csv_path : Path
|
|
227
|
+
Path to the slr.csv file containing the SLR scenarios.
|
|
228
|
+
scenario : str
|
|
229
|
+
SLR scenario name to use from the column names in self.file
|
|
230
|
+
year : float
|
|
231
|
+
year to evaluate
|
|
232
|
+
units : us.UnitTypesLength, default = us.UnitTypesLength.meters
|
|
233
|
+
The units to convert the SLR value to. Default is meters.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
float
|
|
238
|
+
The interpolated sea level rise value in the specified units, relative to the reference year.
|
|
239
|
+
|
|
240
|
+
Raises
|
|
241
|
+
------
|
|
242
|
+
ValueError
|
|
243
|
+
if the reference year is outside of the time range in the slr.csv file
|
|
244
|
+
ValueError
|
|
245
|
+
if the year to evaluate is outside of the time range in the slr.csv file
|
|
246
|
+
"""
|
|
247
|
+
df = pd.read_csv(self.file)
|
|
248
|
+
if year > df["year"].max() or year < df["year"].min():
|
|
249
|
+
raise ValueError(
|
|
250
|
+
"The selected year is outside the range of the available SLR scenarios"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
if (
|
|
254
|
+
self.relative_to_year > df["year"].max()
|
|
255
|
+
or self.relative_to_year < df["year"].min()
|
|
256
|
+
):
|
|
257
|
+
raise ValueError(
|
|
258
|
+
f"The reference year {self.relative_to_year} is outside the range of the available SLR scenarios"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
slr = np.interp(year, df["year"], df[scenario])
|
|
262
|
+
ref_slr = np.interp(self.relative_to_year, df["year"], df[scenario])
|
|
263
|
+
|
|
264
|
+
new_slr = us.UnitfulLength(
|
|
265
|
+
value=slr - ref_slr,
|
|
266
|
+
units=df["units"][0],
|
|
267
|
+
)
|
|
268
|
+
return np.round(new_slr.convert(units), decimals=2)
|
|
269
|
+
|
|
270
|
+
def plot_slr_scenarios(
|
|
271
|
+
self,
|
|
272
|
+
scenario_names: list[str],
|
|
273
|
+
output_loc: Path,
|
|
274
|
+
units: us.UnitTypesLength = us.UnitTypesLength.meters,
|
|
275
|
+
) -> str:
|
|
276
|
+
"""
|
|
277
|
+
Plot sea level rise scenarios.
|
|
278
|
+
|
|
279
|
+
Returns
|
|
280
|
+
-------
|
|
281
|
+
html_path : str
|
|
282
|
+
The path to the html plot of the sea level rise scenarios.
|
|
283
|
+
"""
|
|
284
|
+
df = pd.read_csv(self.file)
|
|
285
|
+
|
|
286
|
+
ncolors = len(df.columns) - 2
|
|
287
|
+
if "units" not in df.columns:
|
|
288
|
+
raise ValueError(f"Expected column `units` in {self.file}.")
|
|
289
|
+
|
|
290
|
+
_units = df["units"].iloc[0]
|
|
291
|
+
_units = us.UnitTypesLength(_units)
|
|
292
|
+
|
|
293
|
+
if "year" not in df.columns:
|
|
294
|
+
raise ValueError(f"Expected column `year` in {self.file}.")
|
|
295
|
+
|
|
296
|
+
if (
|
|
297
|
+
self.relative_to_year > df["year"].max()
|
|
298
|
+
or self.relative_to_year < df["year"].min()
|
|
299
|
+
):
|
|
300
|
+
raise ValueError(
|
|
301
|
+
f"The reference year {self.relative_to_year} is outside the range of the available SLR scenarios"
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
for scn in scenario_names:
|
|
305
|
+
ref_slr = np.interp(self.relative_to_year, df["year"], df[scn])
|
|
306
|
+
df[scn] -= ref_slr
|
|
307
|
+
|
|
308
|
+
df = df.drop(columns="units").melt(id_vars=["year"]).reset_index(drop=True)
|
|
309
|
+
# convert to units used in GUI
|
|
310
|
+
conversion_factor = us.UnitfulLength(value=1.0, units=_units).convert(units)
|
|
311
|
+
df.iloc[:, -1] = (conversion_factor * df.iloc[:, -1]).round(decimals=2)
|
|
312
|
+
|
|
313
|
+
# rename column names that will be shown in html
|
|
314
|
+
df = df.rename(
|
|
315
|
+
columns={
|
|
316
|
+
"variable": "Scenario",
|
|
317
|
+
"value": f"Sea level rise [{units.value}]",
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
colors = sample_colorscale(
|
|
322
|
+
"rainbow", [n / (ncolors - 1) for n in range(ncolors)]
|
|
323
|
+
)
|
|
324
|
+
fig = line(
|
|
325
|
+
df,
|
|
326
|
+
x="year",
|
|
327
|
+
y=f"Sea level rise [{units.value}]",
|
|
328
|
+
color="Scenario",
|
|
329
|
+
color_discrete_sequence=colors,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# fig.update_traces(marker={"line": {"color": "#000000", "width": 2}})
|
|
333
|
+
|
|
334
|
+
fig.update_layout(
|
|
335
|
+
autosize=False,
|
|
336
|
+
height=100 * 1.2,
|
|
337
|
+
width=280 * 1.3,
|
|
338
|
+
margin={"r": 0, "l": 0, "b": 0, "t": 0},
|
|
339
|
+
font={"size": 10, "color": "black", "family": "Arial"},
|
|
340
|
+
title_font={"size": 10, "color": "black", "family": "Arial"},
|
|
341
|
+
legend_font={"size": 10, "color": "black", "family": "Arial"},
|
|
342
|
+
legend_grouptitlefont={"size": 10, "color": "black", "family": "Arial"},
|
|
343
|
+
legend={"entrywidthmode": "fraction", "entrywidth": 0.2},
|
|
344
|
+
yaxis_title_font={"size": 10, "color": "black", "family": "Arial"},
|
|
345
|
+
xaxis_title=None,
|
|
346
|
+
xaxis_range=[self.relative_to_year, df["year"].max()],
|
|
347
|
+
legend_title=None,
|
|
348
|
+
# paper_bgcolor="#3A3A3A",
|
|
349
|
+
# plot_bgcolor="#131313",
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
# write html to results folder
|
|
353
|
+
output_loc.parent.mkdir(parents=True, exist_ok=True)
|
|
354
|
+
fig.write_html(output_loc)
|
|
355
|
+
return str(output_loc)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
class FloodModel(BaseModel):
|
|
359
|
+
"""The accepted input for the variable overland_model and offshore_model in Site.
|
|
360
|
+
|
|
361
|
+
Attributes
|
|
362
|
+
----------
|
|
363
|
+
name : str
|
|
364
|
+
The name of the directory in `static/templates/<directory>` that contains the template model files.
|
|
365
|
+
reference : str
|
|
366
|
+
The name of the vertical reference model that is used as the reference datum. Should be defined in water_level.datums.
|
|
367
|
+
vertical_offset : Optional[us.UnitfulLength], default = None
|
|
368
|
+
The vertical offset of the vertical reference model relative to the main reference.
|
|
369
|
+
Given that the height of the vertical reference model is often determined by external sources,
|
|
370
|
+
this vertical offset can be used to correct systematic over-/underestimation of a vertical reference model.
|
|
371
|
+
"""
|
|
372
|
+
|
|
373
|
+
name: str
|
|
374
|
+
reference: str
|
|
375
|
+
|
|
376
|
+
# this used to be water_level_offset from events
|
|
377
|
+
vertical_offset: Optional[us.UnitfulLength] = None
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class SfincsConfigModel(BaseModel):
|
|
381
|
+
"""The expected variables and data types of attributes of the SfincsConfig class.
|
|
382
|
+
|
|
383
|
+
Attributes
|
|
384
|
+
----------
|
|
385
|
+
csname : str
|
|
386
|
+
The name of the CS model.
|
|
387
|
+
cstype : Cstype
|
|
388
|
+
Cstype of the CS model. must be either "projected" or "spherical".
|
|
389
|
+
version : Optional[str], default = None
|
|
390
|
+
The version of the CS model. If None, the version is not specified.
|
|
391
|
+
offshore_model : Optional[FloodModel], default = None
|
|
392
|
+
The offshore model. If None, the offshore model is not specified.
|
|
393
|
+
overland_model : FloodModel
|
|
394
|
+
The overland model. This is the main model used for the simulation.
|
|
395
|
+
floodmap_units : us.UnitTypesLength
|
|
396
|
+
The units used for the output floodmap. Sfincs always produces in metric units, this is used to convert the floodmap to the correct units.
|
|
397
|
+
save_simulation : Optional[bool], default = False
|
|
398
|
+
Whether to keep or delete the simulation files after the simulation is finished and all output files are created.
|
|
399
|
+
If True, the simulation files are kept. If False, the simulation files are deleted.
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
csname: str
|
|
403
|
+
cstype: Cstype
|
|
404
|
+
version: Optional[str] = None
|
|
405
|
+
offshore_model: Optional[FloodModel] = None
|
|
406
|
+
overland_model: FloodModel
|
|
407
|
+
floodmap_units: us.UnitTypesLength
|
|
408
|
+
save_simulation: Optional[bool] = False
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
class SfincsModel(BaseModel):
|
|
412
|
+
"""The expected variables and data types of attributes of the Sfincs class.
|
|
413
|
+
|
|
414
|
+
Attributes
|
|
415
|
+
----------
|
|
416
|
+
config : SfincsConfigModel
|
|
417
|
+
The configuration of the Sfincs model.
|
|
418
|
+
water_level : WaterlevelReferenceModel
|
|
419
|
+
The collection of all datums and the main reference datum.
|
|
420
|
+
dem : DemModel
|
|
421
|
+
The digital elevation model.
|
|
422
|
+
flood_frequency : FloodFrequencyModel, default = FloodFrequencyModel()
|
|
423
|
+
The flood frequency model.
|
|
424
|
+
slr : SlrScenariosModel
|
|
425
|
+
Specification of the sea level rise scenarios.
|
|
426
|
+
cyclone_track_database : CycloneTrackDatabaseModel, optional, default = None
|
|
427
|
+
The cyclone track database model.
|
|
428
|
+
scs : SCSModel, optional, default = None
|
|
429
|
+
The SCS model.
|
|
430
|
+
tide_gauge : TideGauge, optional, default = None
|
|
431
|
+
The tide gauge model.
|
|
432
|
+
river : list[RiverModel], optional, default = None
|
|
433
|
+
The river model.
|
|
434
|
+
obs_point : list[ObsPointModel], optional, default = None
|
|
435
|
+
The observation point model.
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
config: SfincsConfigModel
|
|
439
|
+
water_level: WaterlevelReferenceModel
|
|
440
|
+
cyclone_track_database: Optional[CycloneTrackDatabaseModel] = None
|
|
441
|
+
slr_scenarios: Optional[SlrScenariosModel] = None
|
|
442
|
+
scs: Optional[SCSModel] = None # optional for the US to use SCS rainfall curves
|
|
443
|
+
dem: DemModel
|
|
444
|
+
|
|
445
|
+
flood_frequency: FloodFrequencyModel = FloodFrequencyModel(
|
|
446
|
+
flooding_threshold=us.UnitfulLength(value=0.0, units=us.UnitTypesLength.meters)
|
|
447
|
+
) # TODO we dont actually use this anywhere?
|
|
448
|
+
|
|
449
|
+
tide_gauge: Optional[TideGauge] = None
|
|
450
|
+
river: Optional[list[RiverModel]] = None
|
|
451
|
+
obs_point: Optional[list[ObsPointModel]] = None
|
|
452
|
+
|
|
453
|
+
@staticmethod
|
|
454
|
+
def read_toml(path: Path) -> "SfincsModel":
|
|
455
|
+
with open(path, mode="rb") as fp:
|
|
456
|
+
toml_contents = load_toml(fp)
|
|
457
|
+
|
|
458
|
+
return SfincsModel(**toml_contents)
|
|
459
|
+
|
|
460
|
+
@model_validator(mode="after")
|
|
461
|
+
def ensure_references_exist(self):
|
|
462
|
+
datum_names = [d.name for d in self.water_level.datums]
|
|
463
|
+
|
|
464
|
+
if self.config.overland_model.reference not in datum_names:
|
|
465
|
+
raise ValueError(
|
|
466
|
+
f"Could not find reference `{self.config.overland_model.reference}` in available datums: {datum_names}."
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
if self.config.offshore_model is not None:
|
|
470
|
+
if self.config.offshore_model.reference not in datum_names:
|
|
471
|
+
raise ValueError(
|
|
472
|
+
f"Could not find reference `{self.config.offshore_model.reference}` in available datums: {datum_names}."
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
if self.tide_gauge is not None:
|
|
476
|
+
if self.tide_gauge.reference not in datum_names:
|
|
477
|
+
raise ValueError(
|
|
478
|
+
f"Could not find reference `{self.tide_gauge.reference}` in available datums: {datum_names}."
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
return self
|