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.
- flood_adapt/__init__.py +26 -22
- flood_adapt/adapter/__init__.py +9 -9
- flood_adapt/adapter/fiat_adapter.py +1541 -1541
- 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 -1848
- flood_adapt/adapter/sfincs_offshore.py +193 -193
- flood_adapt/config/config.py +248 -248
- 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 -684
- 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 -103
- flood_adapt/objects/scenarios/scenarios.py +22 -22
- flood_adapt/objects/strategies/strategies.py +89 -89
- flood_adapt/workflows/benefit_runner.py +579 -554
- flood_adapt/workflows/floodmap.py +85 -85
- flood_adapt/workflows/impacts_integrator.py +85 -85
- flood_adapt/workflows/scenario_runner.py +70 -70
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -865
- flood_adapt-0.3.10.dist-info/RECORD +140 -0
- flood_adapt-0.3.9.dist-info/RECORD +0 -139
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
flood_adapt/config/config.py
CHANGED
|
@@ -1,248 +1,248 @@
|
|
|
1
|
-
from os import environ, listdir
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
import tomli
|
|
6
|
-
import tomli_w
|
|
7
|
-
from pydantic import (
|
|
8
|
-
Field,
|
|
9
|
-
computed_field,
|
|
10
|
-
field_serializer,
|
|
11
|
-
model_validator,
|
|
12
|
-
)
|
|
13
|
-
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Settings(BaseSettings):
|
|
17
|
-
"""
|
|
18
|
-
The configuration settings for the FloodAdapt database and integrator.
|
|
19
|
-
|
|
20
|
-
Precedence is as follows: user arguments > environment variables > defaults in this class.
|
|
21
|
-
When loading is done, the settings are validated and the environment variables are updated with the loaded values.
|
|
22
|
-
|
|
23
|
-
If any required settings are missing or invalid, a ValidationError is raised.
|
|
24
|
-
|
|
25
|
-
Usage
|
|
26
|
-
-----
|
|
27
|
-
from flood_adapt import Settings
|
|
28
|
-
|
|
29
|
-
One of the following:
|
|
30
|
-
|
|
31
|
-
1) Load settings from environment variables, if no environment variables are set, use defaults defined in the class:
|
|
32
|
-
`settings = Settings()`
|
|
33
|
-
|
|
34
|
-
2) Load settings from a .toml file, overwriting any environment variables set:
|
|
35
|
-
`settings = Settings.read(toml_path: Path)`
|
|
36
|
-
|
|
37
|
-
3) Load settings from keyword arguments, overwriting any environment variables:
|
|
38
|
-
`settings = Settings(DATABASE_ROOT="path/to/database", DATABASE_NAME="database_name")`
|
|
39
|
-
|
|
40
|
-
Attributes
|
|
41
|
-
----------
|
|
42
|
-
database_name : str
|
|
43
|
-
The name of the database. Alias: `DATABASE_NAME` (environment variable).
|
|
44
|
-
database_root : Path
|
|
45
|
-
The root directory of the database. Alias: `DATABASE_ROOT` (environment variable).
|
|
46
|
-
delete_crashed_runs : bool
|
|
47
|
-
Whether to delete crashed/corrupted runs immediately after they are detected. Alias: `DELETE_CRASHED_RUNS` (environment variable).
|
|
48
|
-
validate_allowed_forcings : bool
|
|
49
|
-
Whether to validate the forcing types and sources against the allowed forcings in the event model. Alias: `VALIDATE_ALLOWED_FORCINGS` (environment variable).
|
|
50
|
-
validate_binaries : bool
|
|
51
|
-
Whether to validate the existence of the paths to the SFINCS and FIAT binaries. Alias: `VALIDATE_BINARIES` (environment variable).
|
|
52
|
-
sfincs_bin_path : Path
|
|
53
|
-
The path to the SFINCS binary. Alias: `SFINCS_BIN_PATH` (environment variable).
|
|
54
|
-
fiat_bin_path : Path
|
|
55
|
-
The path to the FIAT binary. Alias: `FIAT_BIN_PATH` (environment variable).
|
|
56
|
-
|
|
57
|
-
Properties
|
|
58
|
-
----------
|
|
59
|
-
database_path : Path
|
|
60
|
-
The full path to the database.
|
|
61
|
-
|
|
62
|
-
Raises
|
|
63
|
-
------
|
|
64
|
-
ValidationError
|
|
65
|
-
If required settings are missing or invalid.
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
model_config = SettingsConfigDict(env_ignore_empty=True, validate_default=True)
|
|
69
|
-
|
|
70
|
-
database_root: Path = Field(
|
|
71
|
-
alias="DATABASE_ROOT", # environment variable DATABASE_ROOT
|
|
72
|
-
default=Path(__file__).parents[3]
|
|
73
|
-
/ "Database", # If you clone FloodAdapt, default is to look for the Database next to the FloodAdapt folder
|
|
74
|
-
description="The root directory of the database that contains site(s). Usually the directory name is 'Database'. Default is to look for the Database in the same dir as the FloodAdapt cloned repo.",
|
|
75
|
-
)
|
|
76
|
-
database_name: str = Field(
|
|
77
|
-
alias="DATABASE_NAME", # environment variable DATABASE_NAME
|
|
78
|
-
default="",
|
|
79
|
-
description="The name of the database site, should be a folder inside the database root. The site must contain an 'input' and 'static' folder.",
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
delete_crashed_runs: bool = Field(
|
|
83
|
-
alias="DELETE_CRASHED_RUNS", # environment variable: DELETE_CRASHED_RUNS
|
|
84
|
-
default=False,
|
|
85
|
-
description="Whether to delete the output of crashed/corrupted runs. Be careful when setting this to False, as it may lead to a broken database that cannot be read in anymore.",
|
|
86
|
-
exclude=True,
|
|
87
|
-
)
|
|
88
|
-
validate_allowed_forcings: bool = Field(
|
|
89
|
-
alias="VALIDATE_ALLOWED_FORCINGS", # environment variable: VALIDATE_ALLOWED_FORCINGS
|
|
90
|
-
default=False,
|
|
91
|
-
description="Whether to validate the forcing types and sources against the allowed forcings in the event model.",
|
|
92
|
-
exclude=True,
|
|
93
|
-
)
|
|
94
|
-
validate_binaries: bool = Field(
|
|
95
|
-
alias="VALIDATE_BINARIES", # environment variable: VALIDATE_BINARIES
|
|
96
|
-
default=False,
|
|
97
|
-
description="Whether to validate the existence of the paths to the SFINCS and FIAT binaries.",
|
|
98
|
-
exclude=True,
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
sfincs_bin_path: Optional[Path] = Field(
|
|
102
|
-
default=None,
|
|
103
|
-
alias="SFINCS_BIN_PATH", # environment variable: SFINCS_BIN_PATH
|
|
104
|
-
description="The path of the sfincs binary.",
|
|
105
|
-
exclude=True,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
fiat_bin_path: Optional[Path] = Field(
|
|
109
|
-
default=None,
|
|
110
|
-
alias="FIAT_BIN_PATH", # environment variable: FIAT_BIN_PATH
|
|
111
|
-
description="The path of the fiat binary.",
|
|
112
|
-
exclude=True,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
@computed_field
|
|
116
|
-
@property
|
|
117
|
-
def database_path(self) -> Path:
|
|
118
|
-
return self.database_root / self.database_name
|
|
119
|
-
|
|
120
|
-
@model_validator(mode="after")
|
|
121
|
-
def validate_settings(self):
|
|
122
|
-
self._validate_database_path()
|
|
123
|
-
if self.validate_binaries:
|
|
124
|
-
self._validate_fiat_path()
|
|
125
|
-
self._validate_sfincs_path()
|
|
126
|
-
self._update_environment_variables()
|
|
127
|
-
return self
|
|
128
|
-
|
|
129
|
-
def _update_environment_variables(self):
|
|
130
|
-
environ["DATABASE_ROOT"] = str(self.database_root)
|
|
131
|
-
environ["DATABASE_NAME"] = self.database_name
|
|
132
|
-
|
|
133
|
-
if self.delete_crashed_runs:
|
|
134
|
-
environ["DELETE_CRASHED_RUNS"] = str(self.delete_crashed_runs)
|
|
135
|
-
else:
|
|
136
|
-
environ.pop("DELETE_CRASHED_RUNS", None)
|
|
137
|
-
|
|
138
|
-
if self.validate_allowed_forcings:
|
|
139
|
-
environ["VALIDATE_ALLOWED_FORCINGS"] = str(self.validate_allowed_forcings)
|
|
140
|
-
else:
|
|
141
|
-
environ.pop("VALIDATE_ALLOWED_FORCINGS", None)
|
|
142
|
-
|
|
143
|
-
if self.validate_binaries:
|
|
144
|
-
environ["VALIDATE_BINARIES"] = str(self.validate_binaries)
|
|
145
|
-
environ["SFINCS_BIN_PATH"] = str(self.sfincs_bin_path)
|
|
146
|
-
environ["FIAT_BIN_PATH"] = str(self.fiat_bin_path)
|
|
147
|
-
else:
|
|
148
|
-
environ.pop("VALIDATE_BINARIES", None)
|
|
149
|
-
|
|
150
|
-
return self
|
|
151
|
-
|
|
152
|
-
def _validate_database_path(self):
|
|
153
|
-
if not self.database_root.is_dir():
|
|
154
|
-
raise ValueError(f"Database root {self.database_root} does not exist.")
|
|
155
|
-
|
|
156
|
-
if self.database_name == "":
|
|
157
|
-
# If database_name is not given as arg or set in env, compute default as the first dir in database_root excluding 'system'
|
|
158
|
-
sites = [
|
|
159
|
-
d
|
|
160
|
-
for d in listdir(self.database_root)
|
|
161
|
-
if d != "system" and not d.startswith(".")
|
|
162
|
-
]
|
|
163
|
-
if not sites:
|
|
164
|
-
raise ValueError(f"No databases found in {self.database_root}.")
|
|
165
|
-
self.database_name = sites[0]
|
|
166
|
-
|
|
167
|
-
if not self.database_path.is_dir():
|
|
168
|
-
raise ValueError(
|
|
169
|
-
f"Database {self.database_name} at {self.database_root} does not exist. Full path: {self.database_path}"
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
if not (self.database_path / "input").is_dir():
|
|
173
|
-
raise ValueError(
|
|
174
|
-
f"Database {self.database_name} at {self.database_path} does not contain an input folder."
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
if not (self.database_path / "static").is_dir():
|
|
178
|
-
raise ValueError(
|
|
179
|
-
f"Database {self.database_name} at {self.database_path} does not contain a static folder."
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
return self
|
|
183
|
-
|
|
184
|
-
def _validate_sfincs_path(self):
|
|
185
|
-
if not self.sfincs_bin_path.exists():
|
|
186
|
-
raise ValueError(f"SFINCS binary {self.sfincs_bin_path} does not exist.")
|
|
187
|
-
return self
|
|
188
|
-
|
|
189
|
-
def _validate_fiat_path(self):
|
|
190
|
-
if not self.fiat_bin_path.exists():
|
|
191
|
-
raise ValueError(f"FIAT binary {self.fiat_bin_path} does not exist.")
|
|
192
|
-
return self
|
|
193
|
-
|
|
194
|
-
@field_serializer("database_root", "database_path")
|
|
195
|
-
def serialize_path(self, path: Path) -> str:
|
|
196
|
-
return str(path)
|
|
197
|
-
|
|
198
|
-
@staticmethod
|
|
199
|
-
def read(toml_path: Path) -> "Settings":
|
|
200
|
-
"""
|
|
201
|
-
Parse the configuration file and return the parsed settings.
|
|
202
|
-
|
|
203
|
-
Parameters
|
|
204
|
-
----------
|
|
205
|
-
toml_path : Path
|
|
206
|
-
The path to the configuration file.
|
|
207
|
-
|
|
208
|
-
Returns
|
|
209
|
-
-------
|
|
210
|
-
Settings
|
|
211
|
-
The parsed configuration settings.
|
|
212
|
-
|
|
213
|
-
Raises
|
|
214
|
-
------
|
|
215
|
-
ValidationError
|
|
216
|
-
If required configuration values are missing or if there is an error parsing the configuration file.
|
|
217
|
-
"""
|
|
218
|
-
with open(toml_path, "rb") as f:
|
|
219
|
-
settings = tomli.load(f)
|
|
220
|
-
|
|
221
|
-
return Settings(**settings)
|
|
222
|
-
|
|
223
|
-
def write(self, toml_path: Path) -> None:
|
|
224
|
-
"""
|
|
225
|
-
Write the configuration settings to a .toml file.
|
|
226
|
-
|
|
227
|
-
Parameters
|
|
228
|
-
----------
|
|
229
|
-
toml_path : Path
|
|
230
|
-
The path to the configuration file.
|
|
231
|
-
|
|
232
|
-
Returns
|
|
233
|
-
-------
|
|
234
|
-
None
|
|
235
|
-
|
|
236
|
-
"""
|
|
237
|
-
toml_path = Path(toml_path).resolve()
|
|
238
|
-
if not toml_path.parent.exists():
|
|
239
|
-
toml_path.parent.mkdir(parents=True, exist_ok=True)
|
|
240
|
-
|
|
241
|
-
with open(toml_path, "wb") as f:
|
|
242
|
-
tomli_w.dump(
|
|
243
|
-
self.model_dump(
|
|
244
|
-
by_alias=True,
|
|
245
|
-
exclude={"sfincs_bin_path", "fiat_bin_path", "database_path"},
|
|
246
|
-
),
|
|
247
|
-
f,
|
|
248
|
-
)
|
|
1
|
+
from os import environ, listdir
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import tomli
|
|
6
|
+
import tomli_w
|
|
7
|
+
from pydantic import (
|
|
8
|
+
Field,
|
|
9
|
+
computed_field,
|
|
10
|
+
field_serializer,
|
|
11
|
+
model_validator,
|
|
12
|
+
)
|
|
13
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Settings(BaseSettings):
|
|
17
|
+
"""
|
|
18
|
+
The configuration settings for the FloodAdapt database and integrator.
|
|
19
|
+
|
|
20
|
+
Precedence is as follows: user arguments > environment variables > defaults in this class.
|
|
21
|
+
When loading is done, the settings are validated and the environment variables are updated with the loaded values.
|
|
22
|
+
|
|
23
|
+
If any required settings are missing or invalid, a ValidationError is raised.
|
|
24
|
+
|
|
25
|
+
Usage
|
|
26
|
+
-----
|
|
27
|
+
from flood_adapt import Settings
|
|
28
|
+
|
|
29
|
+
One of the following:
|
|
30
|
+
|
|
31
|
+
1) Load settings from environment variables, if no environment variables are set, use defaults defined in the class:
|
|
32
|
+
`settings = Settings()`
|
|
33
|
+
|
|
34
|
+
2) Load settings from a .toml file, overwriting any environment variables set:
|
|
35
|
+
`settings = Settings.read(toml_path: Path)`
|
|
36
|
+
|
|
37
|
+
3) Load settings from keyword arguments, overwriting any environment variables:
|
|
38
|
+
`settings = Settings(DATABASE_ROOT="path/to/database", DATABASE_NAME="database_name")`
|
|
39
|
+
|
|
40
|
+
Attributes
|
|
41
|
+
----------
|
|
42
|
+
database_name : str
|
|
43
|
+
The name of the database. Alias: `DATABASE_NAME` (environment variable).
|
|
44
|
+
database_root : Path
|
|
45
|
+
The root directory of the database. Alias: `DATABASE_ROOT` (environment variable).
|
|
46
|
+
delete_crashed_runs : bool
|
|
47
|
+
Whether to delete crashed/corrupted runs immediately after they are detected. Alias: `DELETE_CRASHED_RUNS` (environment variable).
|
|
48
|
+
validate_allowed_forcings : bool
|
|
49
|
+
Whether to validate the forcing types and sources against the allowed forcings in the event model. Alias: `VALIDATE_ALLOWED_FORCINGS` (environment variable).
|
|
50
|
+
validate_binaries : bool
|
|
51
|
+
Whether to validate the existence of the paths to the SFINCS and FIAT binaries. Alias: `VALIDATE_BINARIES` (environment variable).
|
|
52
|
+
sfincs_bin_path : Path
|
|
53
|
+
The path to the SFINCS binary. Alias: `SFINCS_BIN_PATH` (environment variable).
|
|
54
|
+
fiat_bin_path : Path
|
|
55
|
+
The path to the FIAT binary. Alias: `FIAT_BIN_PATH` (environment variable).
|
|
56
|
+
|
|
57
|
+
Properties
|
|
58
|
+
----------
|
|
59
|
+
database_path : Path
|
|
60
|
+
The full path to the database.
|
|
61
|
+
|
|
62
|
+
Raises
|
|
63
|
+
------
|
|
64
|
+
ValidationError
|
|
65
|
+
If required settings are missing or invalid.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
model_config = SettingsConfigDict(env_ignore_empty=True, validate_default=True)
|
|
69
|
+
|
|
70
|
+
database_root: Path = Field(
|
|
71
|
+
alias="DATABASE_ROOT", # environment variable DATABASE_ROOT
|
|
72
|
+
default=Path(__file__).parents[3]
|
|
73
|
+
/ "Database", # If you clone FloodAdapt, default is to look for the Database next to the FloodAdapt folder
|
|
74
|
+
description="The root directory of the database that contains site(s). Usually the directory name is 'Database'. Default is to look for the Database in the same dir as the FloodAdapt cloned repo.",
|
|
75
|
+
)
|
|
76
|
+
database_name: str = Field(
|
|
77
|
+
alias="DATABASE_NAME", # environment variable DATABASE_NAME
|
|
78
|
+
default="",
|
|
79
|
+
description="The name of the database site, should be a folder inside the database root. The site must contain an 'input' and 'static' folder.",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
delete_crashed_runs: bool = Field(
|
|
83
|
+
alias="DELETE_CRASHED_RUNS", # environment variable: DELETE_CRASHED_RUNS
|
|
84
|
+
default=False,
|
|
85
|
+
description="Whether to delete the output of crashed/corrupted runs. Be careful when setting this to False, as it may lead to a broken database that cannot be read in anymore.",
|
|
86
|
+
exclude=True,
|
|
87
|
+
)
|
|
88
|
+
validate_allowed_forcings: bool = Field(
|
|
89
|
+
alias="VALIDATE_ALLOWED_FORCINGS", # environment variable: VALIDATE_ALLOWED_FORCINGS
|
|
90
|
+
default=False,
|
|
91
|
+
description="Whether to validate the forcing types and sources against the allowed forcings in the event model.",
|
|
92
|
+
exclude=True,
|
|
93
|
+
)
|
|
94
|
+
validate_binaries: bool = Field(
|
|
95
|
+
alias="VALIDATE_BINARIES", # environment variable: VALIDATE_BINARIES
|
|
96
|
+
default=False,
|
|
97
|
+
description="Whether to validate the existence of the paths to the SFINCS and FIAT binaries.",
|
|
98
|
+
exclude=True,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
sfincs_bin_path: Optional[Path] = Field(
|
|
102
|
+
default=None,
|
|
103
|
+
alias="SFINCS_BIN_PATH", # environment variable: SFINCS_BIN_PATH
|
|
104
|
+
description="The path of the sfincs binary.",
|
|
105
|
+
exclude=True,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
fiat_bin_path: Optional[Path] = Field(
|
|
109
|
+
default=None,
|
|
110
|
+
alias="FIAT_BIN_PATH", # environment variable: FIAT_BIN_PATH
|
|
111
|
+
description="The path of the fiat binary.",
|
|
112
|
+
exclude=True,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
@computed_field
|
|
116
|
+
@property
|
|
117
|
+
def database_path(self) -> Path:
|
|
118
|
+
return self.database_root / self.database_name
|
|
119
|
+
|
|
120
|
+
@model_validator(mode="after")
|
|
121
|
+
def validate_settings(self):
|
|
122
|
+
self._validate_database_path()
|
|
123
|
+
if self.validate_binaries:
|
|
124
|
+
self._validate_fiat_path()
|
|
125
|
+
self._validate_sfincs_path()
|
|
126
|
+
self._update_environment_variables()
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def _update_environment_variables(self):
|
|
130
|
+
environ["DATABASE_ROOT"] = str(self.database_root)
|
|
131
|
+
environ["DATABASE_NAME"] = self.database_name
|
|
132
|
+
|
|
133
|
+
if self.delete_crashed_runs:
|
|
134
|
+
environ["DELETE_CRASHED_RUNS"] = str(self.delete_crashed_runs)
|
|
135
|
+
else:
|
|
136
|
+
environ.pop("DELETE_CRASHED_RUNS", None)
|
|
137
|
+
|
|
138
|
+
if self.validate_allowed_forcings:
|
|
139
|
+
environ["VALIDATE_ALLOWED_FORCINGS"] = str(self.validate_allowed_forcings)
|
|
140
|
+
else:
|
|
141
|
+
environ.pop("VALIDATE_ALLOWED_FORCINGS", None)
|
|
142
|
+
|
|
143
|
+
if self.validate_binaries:
|
|
144
|
+
environ["VALIDATE_BINARIES"] = str(self.validate_binaries)
|
|
145
|
+
environ["SFINCS_BIN_PATH"] = str(self.sfincs_bin_path)
|
|
146
|
+
environ["FIAT_BIN_PATH"] = str(self.fiat_bin_path)
|
|
147
|
+
else:
|
|
148
|
+
environ.pop("VALIDATE_BINARIES", None)
|
|
149
|
+
|
|
150
|
+
return self
|
|
151
|
+
|
|
152
|
+
def _validate_database_path(self):
|
|
153
|
+
if not self.database_root.is_dir():
|
|
154
|
+
raise ValueError(f"Database root {self.database_root} does not exist.")
|
|
155
|
+
|
|
156
|
+
if self.database_name == "":
|
|
157
|
+
# If database_name is not given as arg or set in env, compute default as the first dir in database_root excluding 'system'
|
|
158
|
+
sites = [
|
|
159
|
+
d
|
|
160
|
+
for d in listdir(self.database_root)
|
|
161
|
+
if d != "system" and not d.startswith(".")
|
|
162
|
+
]
|
|
163
|
+
if not sites:
|
|
164
|
+
raise ValueError(f"No databases found in {self.database_root}.")
|
|
165
|
+
self.database_name = sites[0]
|
|
166
|
+
|
|
167
|
+
if not self.database_path.is_dir():
|
|
168
|
+
raise ValueError(
|
|
169
|
+
f"Database {self.database_name} at {self.database_root} does not exist. Full path: {self.database_path}"
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if not (self.database_path / "input").is_dir():
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f"Database {self.database_name} at {self.database_path} does not contain an input folder."
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if not (self.database_path / "static").is_dir():
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"Database {self.database_name} at {self.database_path} does not contain a static folder."
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
return self
|
|
183
|
+
|
|
184
|
+
def _validate_sfincs_path(self):
|
|
185
|
+
if not self.sfincs_bin_path.exists():
|
|
186
|
+
raise ValueError(f"SFINCS binary {self.sfincs_bin_path} does not exist.")
|
|
187
|
+
return self
|
|
188
|
+
|
|
189
|
+
def _validate_fiat_path(self):
|
|
190
|
+
if not self.fiat_bin_path.exists():
|
|
191
|
+
raise ValueError(f"FIAT binary {self.fiat_bin_path} does not exist.")
|
|
192
|
+
return self
|
|
193
|
+
|
|
194
|
+
@field_serializer("database_root", "database_path")
|
|
195
|
+
def serialize_path(self, path: Path) -> str:
|
|
196
|
+
return str(path)
|
|
197
|
+
|
|
198
|
+
@staticmethod
|
|
199
|
+
def read(toml_path: Path) -> "Settings":
|
|
200
|
+
"""
|
|
201
|
+
Parse the configuration file and return the parsed settings.
|
|
202
|
+
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
toml_path : Path
|
|
206
|
+
The path to the configuration file.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
Settings
|
|
211
|
+
The parsed configuration settings.
|
|
212
|
+
|
|
213
|
+
Raises
|
|
214
|
+
------
|
|
215
|
+
ValidationError
|
|
216
|
+
If required configuration values are missing or if there is an error parsing the configuration file.
|
|
217
|
+
"""
|
|
218
|
+
with open(toml_path, "rb") as f:
|
|
219
|
+
settings = tomli.load(f)
|
|
220
|
+
|
|
221
|
+
return Settings(**settings)
|
|
222
|
+
|
|
223
|
+
def write(self, toml_path: Path) -> None:
|
|
224
|
+
"""
|
|
225
|
+
Write the configuration settings to a .toml file.
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
toml_path : Path
|
|
230
|
+
The path to the configuration file.
|
|
231
|
+
|
|
232
|
+
Returns
|
|
233
|
+
-------
|
|
234
|
+
None
|
|
235
|
+
|
|
236
|
+
"""
|
|
237
|
+
toml_path = Path(toml_path).resolve()
|
|
238
|
+
if not toml_path.parent.exists():
|
|
239
|
+
toml_path.parent.mkdir(parents=True, exist_ok=True)
|
|
240
|
+
|
|
241
|
+
with open(toml_path, "wb") as f:
|
|
242
|
+
tomli_w.dump(
|
|
243
|
+
self.model_dump(
|
|
244
|
+
by_alias=True,
|
|
245
|
+
exclude={"sfincs_bin_path", "fiat_bin_path", "database_path"},
|
|
246
|
+
),
|
|
247
|
+
f,
|
|
248
|
+
)
|