flood-adapt 0.3.15__py3-none-any.whl → 1.0.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 +1 -1
- flood_adapt/adapter/fiat_adapter.py +2 -1
- flood_adapt/adapter/sfincs_adapter.py +10 -2
- flood_adapt/adapter/sfincs_offshore.py +5 -1
- flood_adapt/config/__init__.py +92 -0
- flood_adapt/config/fiat.py +9 -131
- flood_adapt/config/gui.py +1 -1
- flood_adapt/config/hazard.py +366 -0
- flood_adapt/config/impacts.py +140 -0
- flood_adapt/config/sfincs.py +14 -371
- flood_adapt/database_builder/database_builder.py +14 -10
- flood_adapt/dbs_classes/database.py +1 -1
- flood_adapt/objects/__init__.py +2 -2
- flood_adapt/objects/forcing/forcing.py +1 -1
- flood_adapt/objects/forcing/meteo_handler.py +5 -10
- flood_adapt/objects/measures/measures.py +1 -1
- flood_adapt/workflows/floodmap.py +1 -1
- {flood_adapt-0.3.15.dist-info → flood_adapt-1.0.0.dist-info}/METADATA +1 -1
- {flood_adapt-0.3.15.dist-info → flood_adapt-1.0.0.dist-info}/RECORD +22 -20
- {flood_adapt-0.3.15.dist-info → flood_adapt-1.0.0.dist-info}/LICENSE +0 -0
- {flood_adapt-0.3.15.dist-info → flood_adapt-1.0.0.dist-info}/WHEEL +0 -0
- {flood_adapt-0.3.15.dist-info → flood_adapt-1.0.0.dist-info}/top_level.txt +0 -0
flood_adapt/__init__.py
CHANGED
|
@@ -23,6 +23,7 @@ from hydromt_fiat.fiat import FiatModel
|
|
|
23
23
|
|
|
24
24
|
from flood_adapt.adapter.interface.impact_adapter import IImpactAdapter
|
|
25
25
|
from flood_adapt.config.fiat import FiatConfigModel
|
|
26
|
+
from flood_adapt.config.impacts import FloodmapType
|
|
26
27
|
from flood_adapt.misc.log import FloodAdaptLogging
|
|
27
28
|
from flood_adapt.misc.path_builder import (
|
|
28
29
|
ObjectDir,
|
|
@@ -39,7 +40,7 @@ from flood_adapt.objects.measures.measures import (
|
|
|
39
40
|
)
|
|
40
41
|
from flood_adapt.objects.projections.projections import Projection
|
|
41
42
|
from flood_adapt.objects.scenarios.scenarios import Scenario
|
|
42
|
-
from flood_adapt.workflows.floodmap import FloodMap
|
|
43
|
+
from flood_adapt.workflows.floodmap import FloodMap
|
|
43
44
|
from flood_adapt.workflows.impacts_integrator import Impacts
|
|
44
45
|
|
|
45
46
|
# Define naming structure for saved files
|
|
@@ -934,7 +934,11 @@ class SfincsAdapter(IHazardAdapter):
|
|
|
934
934
|
timeseries=tmp_path, magnitude=None, direction=None
|
|
935
935
|
)
|
|
936
936
|
elif isinstance(wind, WindMeteo):
|
|
937
|
-
ds = MeteoHandler(
|
|
937
|
+
ds = MeteoHandler(
|
|
938
|
+
dir=self.database.static_path / "meteo",
|
|
939
|
+
lat=self.database.site.lat,
|
|
940
|
+
lon=self.database.site.lon,
|
|
941
|
+
).read(time_frame)
|
|
938
942
|
# data already in metric units so no conversion needed
|
|
939
943
|
|
|
940
944
|
# HydroMT function: set wind forcing from grid
|
|
@@ -1018,7 +1022,11 @@ class SfincsAdapter(IHazardAdapter):
|
|
|
1018
1022
|
|
|
1019
1023
|
self._model.setup_precip_forcing(timeseries=tmp_path)
|
|
1020
1024
|
elif isinstance(rainfall, RainfallMeteo):
|
|
1021
|
-
ds = MeteoHandler(
|
|
1025
|
+
ds = MeteoHandler(
|
|
1026
|
+
dir=self.database.static_path / "meteo",
|
|
1027
|
+
lat=self.database.site.lat,
|
|
1028
|
+
lon=self.database.site.lon,
|
|
1029
|
+
).read(time_frame)
|
|
1022
1030
|
# MeteoHandler always return metric so no conversion needed
|
|
1023
1031
|
self._model.setup_precip_forcing_from_grid(precip=ds, aggregate=False)
|
|
1024
1032
|
elif isinstance(rainfall, RainfallTrack):
|
|
@@ -138,7 +138,11 @@ class OffshoreSfincsHandler(IOffshoreSfincsHandler, DatabaseUser):
|
|
|
138
138
|
|
|
139
139
|
# Add pressure forcing for the offshore model (this doesnt happen normally in _add_forcing_wind() for overland models)
|
|
140
140
|
if isinstance(wind_forcing, WindMeteo):
|
|
141
|
-
ds = MeteoHandler(
|
|
141
|
+
ds = MeteoHandler(
|
|
142
|
+
dir=self.database.static_path / "meteo",
|
|
143
|
+
lat=self.database.site.lat,
|
|
144
|
+
lon=self.database.site.lon,
|
|
145
|
+
).read(_offshore_model._event.time)
|
|
142
146
|
_offshore_model._add_pressure_forcing_from_grid(ds=ds)
|
|
143
147
|
|
|
144
148
|
# write sfincs model in output destination
|
flood_adapt/config/__init__.py
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from flood_adapt.config.config import Settings
|
|
2
|
+
from flood_adapt.config.fiat import (
|
|
3
|
+
FiatConfigModel,
|
|
4
|
+
FiatModel,
|
|
5
|
+
)
|
|
6
|
+
from flood_adapt.config.gui import (
|
|
7
|
+
AggregationDmgLayer,
|
|
8
|
+
BenefitsLayer,
|
|
9
|
+
FloodMapLayer,
|
|
10
|
+
FootprintsDmgLayer,
|
|
11
|
+
GuiModel,
|
|
12
|
+
GuiUnitModel,
|
|
13
|
+
Layer,
|
|
14
|
+
OutputLayers,
|
|
15
|
+
PlottingModel,
|
|
16
|
+
VisualizationLayer,
|
|
17
|
+
VisualizationLayers,
|
|
18
|
+
)
|
|
19
|
+
from flood_adapt.config.hazard import (
|
|
20
|
+
AsciiStr,
|
|
21
|
+
Cstype,
|
|
22
|
+
CycloneTrackDatabaseModel,
|
|
23
|
+
DatumModel,
|
|
24
|
+
DemModel,
|
|
25
|
+
FloodFrequencyModel,
|
|
26
|
+
FloodModel,
|
|
27
|
+
ObsPointModel,
|
|
28
|
+
RiverModel,
|
|
29
|
+
SCSModel,
|
|
30
|
+
Scstype,
|
|
31
|
+
SlrScenariosModel,
|
|
32
|
+
WaterlevelReferenceModel,
|
|
33
|
+
)
|
|
34
|
+
from flood_adapt.config.impacts import (
|
|
35
|
+
AggregationModel,
|
|
36
|
+
BenefitsModel,
|
|
37
|
+
EquityModel,
|
|
38
|
+
FloodmapType,
|
|
39
|
+
NoFootprintsModel,
|
|
40
|
+
RiskModel,
|
|
41
|
+
)
|
|
42
|
+
from flood_adapt.config.sfincs import (
|
|
43
|
+
SfincsConfigModel,
|
|
44
|
+
SfincsModel,
|
|
45
|
+
)
|
|
46
|
+
from flood_adapt.config.site import Site, SiteBuilder, StandardObjectModel
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
# GUI
|
|
50
|
+
"GuiModel",
|
|
51
|
+
"GuiUnitModel",
|
|
52
|
+
"PlottingModel",
|
|
53
|
+
"Layer",
|
|
54
|
+
"OutputLayers",
|
|
55
|
+
"BenefitsLayer",
|
|
56
|
+
"FloodMapLayer",
|
|
57
|
+
"FootprintsDmgLayer",
|
|
58
|
+
"VisualizationLayer",
|
|
59
|
+
"VisualizationLayers",
|
|
60
|
+
"AggregationDmgLayer",
|
|
61
|
+
# FIAT
|
|
62
|
+
"FiatModel",
|
|
63
|
+
"FiatConfigModel",
|
|
64
|
+
"FloodmapType",
|
|
65
|
+
"NoFootprintsModel",
|
|
66
|
+
"RiskModel",
|
|
67
|
+
"EquityModel",
|
|
68
|
+
"BenefitsModel",
|
|
69
|
+
"AggregationModel",
|
|
70
|
+
# Config
|
|
71
|
+
"Settings",
|
|
72
|
+
# Sfincs
|
|
73
|
+
"SfincsModel",
|
|
74
|
+
"SfincsConfigModel",
|
|
75
|
+
"SCSModel",
|
|
76
|
+
"Scstype",
|
|
77
|
+
"Cstype",
|
|
78
|
+
"DemModel",
|
|
79
|
+
"DatumModel",
|
|
80
|
+
"FloodModel",
|
|
81
|
+
"RiverModel",
|
|
82
|
+
"ObsPointModel",
|
|
83
|
+
"SlrScenariosModel",
|
|
84
|
+
"FloodFrequencyModel",
|
|
85
|
+
"WaterlevelReferenceModel",
|
|
86
|
+
"CycloneTrackDatabaseModel",
|
|
87
|
+
"AsciiStr",
|
|
88
|
+
# Site
|
|
89
|
+
"Site",
|
|
90
|
+
"SiteBuilder",
|
|
91
|
+
"StandardObjectModel",
|
|
92
|
+
]
|
flood_adapt/config/fiat.py
CHANGED
|
@@ -1,140 +1,18 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from pydantic import BaseModel
|
|
6
5
|
from tomli import load as load_toml
|
|
7
6
|
|
|
8
|
-
from flood_adapt.config.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
The current year used in benefits calculations.
|
|
18
|
-
current_projection : str
|
|
19
|
-
The current projection used in benefits calculations.
|
|
20
|
-
baseline_strategy : str
|
|
21
|
-
The baseline strategy used in benefits calculations.
|
|
22
|
-
event_set : str
|
|
23
|
-
The event set used in benefits calculations.
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
current_year: int
|
|
27
|
-
current_projection: str
|
|
28
|
-
baseline_strategy: str
|
|
29
|
-
event_set: str
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class EquityModel(BaseModel):
|
|
33
|
-
"""
|
|
34
|
-
The accepted input for the variable equity in Site.
|
|
35
|
-
|
|
36
|
-
Attributes
|
|
37
|
-
----------
|
|
38
|
-
census_data : str
|
|
39
|
-
TODO
|
|
40
|
-
percapitaincome_label : Optional[str], default="PerCapitaIncome"
|
|
41
|
-
TODO
|
|
42
|
-
totalpopulation_label : Optional[str], default="TotalPopulation"
|
|
43
|
-
TODO
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
census_data: str
|
|
47
|
-
percapitaincome_label: Optional[str] = "PerCapitaIncome"
|
|
48
|
-
totalpopulation_label: Optional[str] = "TotalPopulation"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class AggregationModel(BaseModel):
|
|
52
|
-
"""The accepted input for the variable aggregation in Site.
|
|
53
|
-
|
|
54
|
-
Attributes
|
|
55
|
-
----------
|
|
56
|
-
name : str
|
|
57
|
-
TODO
|
|
58
|
-
file : str
|
|
59
|
-
TODO
|
|
60
|
-
field_name : str
|
|
61
|
-
TODO
|
|
62
|
-
equity : Optional[EquityModel], default=None
|
|
63
|
-
TODO
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
name: str
|
|
67
|
-
file: str
|
|
68
|
-
field_name: str
|
|
69
|
-
equity: Optional[EquityModel] = None
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class BFEModel(BaseModel):
|
|
73
|
-
"""The accepted input for the variable bfe in Site.
|
|
74
|
-
|
|
75
|
-
Attributes
|
|
76
|
-
----------
|
|
77
|
-
geom : str
|
|
78
|
-
TODO
|
|
79
|
-
table : Optional[str], default=None
|
|
80
|
-
TODO
|
|
81
|
-
field_name : str
|
|
82
|
-
TODO
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
geom: str
|
|
86
|
-
table: Optional[str] = None
|
|
87
|
-
field_name: str
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class SVIModel(BaseModel):
|
|
91
|
-
"""The accepted input for the variable svi in Site.
|
|
92
|
-
|
|
93
|
-
Attributes
|
|
94
|
-
----------
|
|
95
|
-
geom : str
|
|
96
|
-
TODO
|
|
97
|
-
field_name : str
|
|
98
|
-
TODO
|
|
99
|
-
"""
|
|
100
|
-
|
|
101
|
-
geom: str
|
|
102
|
-
field_name: str
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class NoFootprintsModel(BaseModel):
|
|
106
|
-
"""
|
|
107
|
-
The configuration on the how to show objects with no footprints.
|
|
108
|
-
|
|
109
|
-
Attributes
|
|
110
|
-
----------
|
|
111
|
-
shape : Optional[str], default="triangle"
|
|
112
|
-
The shape of the object with no footprints.
|
|
113
|
-
diameter_meters : Optional[float], default=10
|
|
114
|
-
The diameter of the object with no footprints in meters.
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
shape: Optional[str] = "triangle"
|
|
118
|
-
diameter_meters: Optional[float] = 10
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
class RiskModel(BaseModel):
|
|
122
|
-
"""The accepted input for the variable risk in Site.
|
|
123
|
-
|
|
124
|
-
Attributes
|
|
125
|
-
----------
|
|
126
|
-
return_periods : list[int]
|
|
127
|
-
The return periods for the risk model.
|
|
128
|
-
"""
|
|
129
|
-
|
|
130
|
-
return_periods: list = [1, 2, 5, 10, 25, 50, 100]
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
class DamageType(str, Enum):
|
|
134
|
-
"""The accepted input for the variable footprints_dmg_type."""
|
|
135
|
-
|
|
136
|
-
absolute = "absolute"
|
|
137
|
-
relative = "relative"
|
|
7
|
+
from flood_adapt.config.impacts import (
|
|
8
|
+
AggregationModel,
|
|
9
|
+
BenefitsModel,
|
|
10
|
+
BFEModel,
|
|
11
|
+
FloodmapType,
|
|
12
|
+
NoFootprintsModel,
|
|
13
|
+
RiskModel,
|
|
14
|
+
SVIModel,
|
|
15
|
+
)
|
|
138
16
|
|
|
139
17
|
|
|
140
18
|
class FiatConfigModel(BaseModel):
|
flood_adapt/config/gui.py
CHANGED
|
@@ -0,0 +1,366 @@
|
|
|
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 typing_extensions import Annotated
|
|
12
|
+
|
|
13
|
+
from flood_adapt.objects.forcing import unit_system as us
|
|
14
|
+
from flood_adapt.objects.forcing.timeseries import Scstype
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def ensure_ascii(s: str):
|
|
18
|
+
assert s.isascii()
|
|
19
|
+
return s
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
AsciiStr = Annotated[str, AfterValidator(ensure_ascii)]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Cstype(str, Enum):
|
|
26
|
+
"""The accepted input for the variable cstype in Site."""
|
|
27
|
+
|
|
28
|
+
projected = "projected"
|
|
29
|
+
spherical = "spherical"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SCSModel(BaseModel):
|
|
33
|
+
"""Class describing the accepted input for the variable scs.
|
|
34
|
+
|
|
35
|
+
Includes the file with the non-dimensional SCS rainfall curves in the site folder and the SCS rainfall curve type.
|
|
36
|
+
|
|
37
|
+
Attributes
|
|
38
|
+
----------
|
|
39
|
+
file : str
|
|
40
|
+
The path to the SCS rainfall curves file.
|
|
41
|
+
type : Scstype
|
|
42
|
+
The type of the SCS rainfall curve.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
file: str
|
|
46
|
+
type: Scstype
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class RiverModel(BaseModel):
|
|
50
|
+
"""Model that describes the accepted input for the variable river in Site.
|
|
51
|
+
|
|
52
|
+
Attributes
|
|
53
|
+
----------
|
|
54
|
+
name : str
|
|
55
|
+
The name of the river.
|
|
56
|
+
description : Optional[str], default=None
|
|
57
|
+
description of the river.
|
|
58
|
+
mean_discharge : us.UnitfulDischarge
|
|
59
|
+
The mean discharge of the river.
|
|
60
|
+
x_coordinate : float
|
|
61
|
+
The x coordinate of the river.
|
|
62
|
+
y_coordinate : float
|
|
63
|
+
The y coordinate of the river.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
name: str
|
|
67
|
+
description: Optional[str] = None
|
|
68
|
+
mean_discharge: us.UnitfulDischarge
|
|
69
|
+
x_coordinate: float
|
|
70
|
+
y_coordinate: float
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ObsPointModel(BaseModel):
|
|
74
|
+
"""The accepted input for the variable obs_point in Site.
|
|
75
|
+
|
|
76
|
+
obs_points is used to define output locations in the hazard model, which will be plotted in the user interface.
|
|
77
|
+
|
|
78
|
+
Attributes
|
|
79
|
+
----------
|
|
80
|
+
name : Union[int, AsciiStr]
|
|
81
|
+
The name of the observation point.
|
|
82
|
+
description : Optional[str], default=""
|
|
83
|
+
The description of the observation point.
|
|
84
|
+
ID : Optional[int], default=None
|
|
85
|
+
The ID of the observation point.
|
|
86
|
+
file : Optional[str], default=None
|
|
87
|
+
The path to the observation point data file.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
name: Union[int, AsciiStr]
|
|
91
|
+
description: Optional[str] = ""
|
|
92
|
+
ID: Optional[int] = (
|
|
93
|
+
None # if the observation station is also a tide gauge, this ID should be the same as for obs_station
|
|
94
|
+
)
|
|
95
|
+
file: Optional[str] = None # for locally stored data
|
|
96
|
+
lat: float
|
|
97
|
+
lon: float
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class FloodFrequencyModel(BaseModel):
|
|
101
|
+
"""The accepted input for the variable flood_frequency in Site."""
|
|
102
|
+
|
|
103
|
+
flooding_threshold: us.UnitfulLength
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class DemModel(BaseModel):
|
|
107
|
+
"""The accepted input for the variable dem in Site.
|
|
108
|
+
|
|
109
|
+
Attributes
|
|
110
|
+
----------
|
|
111
|
+
filename : str
|
|
112
|
+
The path to the digital elevation model file.
|
|
113
|
+
units : us.UnitTypesLength
|
|
114
|
+
The units of the digital elevation model file.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
filename: str
|
|
118
|
+
units: us.UnitTypesLength
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class DatumModel(BaseModel):
|
|
122
|
+
"""
|
|
123
|
+
The accepted input for the variable datums in WaterlevelReferenceModel.
|
|
124
|
+
|
|
125
|
+
Attributes
|
|
126
|
+
----------
|
|
127
|
+
name : str
|
|
128
|
+
The name of the vertical reference model.
|
|
129
|
+
height : us.UnitfulLength
|
|
130
|
+
The height of the vertical reference model relative to the main reference.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
name: str
|
|
134
|
+
height: us.UnitfulLength
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class WaterlevelReferenceModel(BaseModel):
|
|
138
|
+
"""The accepted input for the variable water_level in Site.
|
|
139
|
+
|
|
140
|
+
Waterlevels timeseries are calculated from user input, assumed to be relative to the `reference` vertical reference model.
|
|
141
|
+
|
|
142
|
+
For plotting in the GUI, the `reference` vertical reference model is used as the main zero-reference, all values are relative to this.
|
|
143
|
+
All other vertical reference models are plotted as dashed lines.
|
|
144
|
+
|
|
145
|
+
Attributes
|
|
146
|
+
----------
|
|
147
|
+
reference : str
|
|
148
|
+
The name of the vertical reference model that is used as the main zero-reference.
|
|
149
|
+
datums : list[DatumModel]
|
|
150
|
+
The vertical reference models that are used to calculate the waterlevels timeseries.
|
|
151
|
+
The datums are used to calculate the waterlevels timeseries, which are relative to the `reference` vertical reference model.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
reference: str
|
|
155
|
+
datums: list[DatumModel] = Field(default_factory=list)
|
|
156
|
+
|
|
157
|
+
def get_datum(self, name: str) -> DatumModel:
|
|
158
|
+
for datum in self.datums:
|
|
159
|
+
if datum.name == name:
|
|
160
|
+
return datum
|
|
161
|
+
raise ValueError(f"Could not find datum with name {name}")
|
|
162
|
+
|
|
163
|
+
@model_validator(mode="after")
|
|
164
|
+
def main_reference_should_be_in_datums_and_eq_zero(self):
|
|
165
|
+
if self.reference not in [datum.name for datum in self.datums]:
|
|
166
|
+
raise ValueError(f"Reference {self.reference} not in {self.datums}")
|
|
167
|
+
if not math.isclose(
|
|
168
|
+
self.get_datum(self.reference).height.value, 0, abs_tol=1e-6
|
|
169
|
+
):
|
|
170
|
+
raise ValueError(f"Reference {self.reference} height is not zero")
|
|
171
|
+
return self
|
|
172
|
+
|
|
173
|
+
@model_validator(mode="after")
|
|
174
|
+
def all_datums_should_have_unique_names(self):
|
|
175
|
+
datum_names = [datum.name for datum in self.datums]
|
|
176
|
+
if len(set(datum_names)) != len(datum_names):
|
|
177
|
+
raise ValueError(f"Duplicate datum names found: {datum_names}")
|
|
178
|
+
return self
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class CycloneTrackDatabaseModel(BaseModel):
|
|
182
|
+
"""The accepted input for the variable cyclone_track_database in Site.
|
|
183
|
+
|
|
184
|
+
Attributes
|
|
185
|
+
----------
|
|
186
|
+
file : str
|
|
187
|
+
The path to the cyclone track database file.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
file: str
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class SlrScenariosModel(BaseModel):
|
|
194
|
+
"""The accepted input for the variable slr_scenarios.
|
|
195
|
+
|
|
196
|
+
Attributes
|
|
197
|
+
----------
|
|
198
|
+
file : str
|
|
199
|
+
The path to the sea level rise scenarios file.
|
|
200
|
+
relative_to_year : int
|
|
201
|
+
The year to which the sea level rise scenarios are relative.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
file: str
|
|
205
|
+
relative_to_year: int
|
|
206
|
+
|
|
207
|
+
def interp_slr(
|
|
208
|
+
self,
|
|
209
|
+
scenario: str,
|
|
210
|
+
year: float,
|
|
211
|
+
units: us.UnitTypesLength = us.UnitTypesLength.meters,
|
|
212
|
+
) -> float:
|
|
213
|
+
"""Interpolate SLR value and reference it to the SLR reference year from the site toml.
|
|
214
|
+
|
|
215
|
+
Parameters
|
|
216
|
+
----------
|
|
217
|
+
scenario : str
|
|
218
|
+
SLR scenario name to use from the column names in self.file
|
|
219
|
+
year : float
|
|
220
|
+
year to evaluate
|
|
221
|
+
units : us.UnitTypesLength, default = us.UnitTypesLength.meters
|
|
222
|
+
The units to convert the SLR value to. Default is meters.
|
|
223
|
+
|
|
224
|
+
Returns
|
|
225
|
+
-------
|
|
226
|
+
float
|
|
227
|
+
The interpolated sea level rise value in the specified units, relative to the reference year.
|
|
228
|
+
|
|
229
|
+
Raises
|
|
230
|
+
------
|
|
231
|
+
ValueError
|
|
232
|
+
if the reference year is outside of the time range in the slr.csv file
|
|
233
|
+
ValueError
|
|
234
|
+
if the year to evaluate is outside of the time range in the slr.csv file
|
|
235
|
+
"""
|
|
236
|
+
df = pd.read_csv(self.file)
|
|
237
|
+
if year > df["year"].max() or year < df["year"].min():
|
|
238
|
+
raise ValueError(
|
|
239
|
+
"The selected year is outside the range of the available SLR scenarios"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
if (
|
|
243
|
+
self.relative_to_year > df["year"].max()
|
|
244
|
+
or self.relative_to_year < df["year"].min()
|
|
245
|
+
):
|
|
246
|
+
raise ValueError(
|
|
247
|
+
f"The reference year {self.relative_to_year} is outside the range of the available SLR scenarios"
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
slr = np.interp(year, df["year"], df[scenario])
|
|
251
|
+
ref_slr = np.interp(self.relative_to_year, df["year"], df[scenario])
|
|
252
|
+
|
|
253
|
+
new_slr = us.UnitfulLength(
|
|
254
|
+
value=slr - ref_slr,
|
|
255
|
+
units=df["units"][0],
|
|
256
|
+
)
|
|
257
|
+
return np.round(new_slr.convert(units), decimals=2)
|
|
258
|
+
|
|
259
|
+
def plot_slr_scenarios(
|
|
260
|
+
self,
|
|
261
|
+
scenario_names: list[str],
|
|
262
|
+
output_loc: Path,
|
|
263
|
+
units: us.UnitTypesLength = us.UnitTypesLength.meters,
|
|
264
|
+
) -> str:
|
|
265
|
+
"""
|
|
266
|
+
Plot sea level rise scenarios.
|
|
267
|
+
|
|
268
|
+
Returns
|
|
269
|
+
-------
|
|
270
|
+
html_path : str
|
|
271
|
+
The path to the html plot of the sea level rise scenarios.
|
|
272
|
+
"""
|
|
273
|
+
df = pd.read_csv(self.file)
|
|
274
|
+
|
|
275
|
+
ncolors = len(df.columns) - 2
|
|
276
|
+
if "units" not in df.columns:
|
|
277
|
+
raise ValueError(f"Expected column `units` in {self.file}.")
|
|
278
|
+
|
|
279
|
+
_units = df["units"].iloc[0]
|
|
280
|
+
_units = us.UnitTypesLength(_units)
|
|
281
|
+
|
|
282
|
+
if "year" not in df.columns:
|
|
283
|
+
raise ValueError(f"Expected column `year` in {self.file}.")
|
|
284
|
+
|
|
285
|
+
if (
|
|
286
|
+
self.relative_to_year > df["year"].max()
|
|
287
|
+
or self.relative_to_year < df["year"].min()
|
|
288
|
+
):
|
|
289
|
+
raise ValueError(
|
|
290
|
+
f"The reference year {self.relative_to_year} is outside the range of the available SLR scenarios"
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
for scn in scenario_names:
|
|
294
|
+
ref_slr = np.interp(self.relative_to_year, df["year"], df[scn])
|
|
295
|
+
df[scn] -= ref_slr
|
|
296
|
+
|
|
297
|
+
df = df.drop(columns="units").melt(id_vars=["year"]).reset_index(drop=True)
|
|
298
|
+
# convert to units used in GUI
|
|
299
|
+
conversion_factor = us.UnitfulLength(value=1.0, units=_units).convert(units)
|
|
300
|
+
df.iloc[:, -1] = (conversion_factor * df.iloc[:, -1]).round(decimals=2)
|
|
301
|
+
|
|
302
|
+
# rename column names that will be shown in html
|
|
303
|
+
df = df.rename(
|
|
304
|
+
columns={
|
|
305
|
+
"variable": "Scenario",
|
|
306
|
+
"value": f"Sea level rise [{units.value}]",
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
colors = sample_colorscale(
|
|
311
|
+
"rainbow", [n / (ncolors - 1) for n in range(ncolors)]
|
|
312
|
+
)
|
|
313
|
+
fig = line(
|
|
314
|
+
df,
|
|
315
|
+
x="year",
|
|
316
|
+
y=f"Sea level rise [{units.value}]",
|
|
317
|
+
color="Scenario",
|
|
318
|
+
color_discrete_sequence=colors,
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# fig.update_traces(marker={"line": {"color": "#000000", "width": 2}})
|
|
322
|
+
|
|
323
|
+
fig.update_layout(
|
|
324
|
+
autosize=False,
|
|
325
|
+
height=100 * 1.2,
|
|
326
|
+
width=280 * 1.3,
|
|
327
|
+
margin={"r": 0, "l": 0, "b": 0, "t": 0},
|
|
328
|
+
font={"size": 10, "color": "black", "family": "Arial"},
|
|
329
|
+
title_font={"size": 10, "color": "black", "family": "Arial"},
|
|
330
|
+
legend_font={"size": 10, "color": "black", "family": "Arial"},
|
|
331
|
+
legend_grouptitlefont={"size": 10, "color": "black", "family": "Arial"},
|
|
332
|
+
legend={"entrywidthmode": "fraction", "entrywidth": 0.2},
|
|
333
|
+
yaxis_title_font={"size": 10, "color": "black", "family": "Arial"},
|
|
334
|
+
xaxis_title=None,
|
|
335
|
+
xaxis_range=[self.relative_to_year, df["year"].max()],
|
|
336
|
+
legend_title=None,
|
|
337
|
+
# paper_bgcolor="#3A3A3A",
|
|
338
|
+
# plot_bgcolor="#131313",
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# write html to results folder
|
|
342
|
+
output_loc.parent.mkdir(parents=True, exist_ok=True)
|
|
343
|
+
fig.write_html(output_loc)
|
|
344
|
+
return str(output_loc)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
class FloodModel(BaseModel):
|
|
348
|
+
"""The accepted input for the variable overland_model and offshore_model in Site.
|
|
349
|
+
|
|
350
|
+
Attributes
|
|
351
|
+
----------
|
|
352
|
+
name : str
|
|
353
|
+
The name of the directory in `static/templates/<directory>` that contains the template model files.
|
|
354
|
+
reference : str
|
|
355
|
+
The name of the vertical reference model that is used as the reference datum. Should be defined in water_level.datums.
|
|
356
|
+
vertical_offset : Optional[us.UnitfulLength], default = None
|
|
357
|
+
The vertical offset of the vertical reference model relative to the main reference.
|
|
358
|
+
Given that the height of the vertical reference model is often determined by external sources,
|
|
359
|
+
this vertical offset can be used to correct systematic over-/underestimation of a vertical reference model.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
name: str
|
|
363
|
+
reference: str
|
|
364
|
+
|
|
365
|
+
# this used to be water_level_offset from events
|
|
366
|
+
vertical_offset: Optional[us.UnitfulLength] = None
|