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.
Files changed (100) hide show
  1. flood_adapt/__init__.py +26 -22
  2. flood_adapt/adapter/__init__.py +9 -9
  3. flood_adapt/adapter/fiat_adapter.py +1541 -1541
  4. flood_adapt/adapter/interface/hazard_adapter.py +70 -70
  5. flood_adapt/adapter/interface/impact_adapter.py +36 -36
  6. flood_adapt/adapter/interface/model_adapter.py +89 -89
  7. flood_adapt/adapter/interface/offshore.py +19 -19
  8. flood_adapt/adapter/sfincs_adapter.py +1848 -1848
  9. flood_adapt/adapter/sfincs_offshore.py +193 -193
  10. flood_adapt/config/config.py +248 -248
  11. flood_adapt/config/fiat.py +219 -219
  12. flood_adapt/config/gui.py +331 -331
  13. flood_adapt/config/sfincs.py +481 -336
  14. flood_adapt/config/site.py +129 -129
  15. flood_adapt/database_builder/database_builder.py +2210 -2210
  16. flood_adapt/database_builder/templates/default_units/imperial.toml +9 -9
  17. flood_adapt/database_builder/templates/default_units/metric.toml +9 -9
  18. flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -10
  19. flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -90
  20. flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -57
  21. flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -121
  22. flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -65
  23. flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -45
  24. flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -126
  25. flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -60
  26. flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -121
  27. flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -65
  28. flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -45
  29. flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -4
  30. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -143
  31. flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -153
  32. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -127
  33. flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -57
  34. flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -4
  35. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -191
  36. flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -153
  37. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -178
  38. flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -57
  39. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -9
  40. flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -65
  41. flood_adapt/database_builder/templates/output_layers/bin_colors.toml +5 -5
  42. flood_adapt/database_builder.py +16 -16
  43. flood_adapt/dbs_classes/__init__.py +21 -21
  44. flood_adapt/dbs_classes/database.py +495 -684
  45. flood_adapt/dbs_classes/dbs_benefit.py +77 -76
  46. flood_adapt/dbs_classes/dbs_event.py +61 -59
  47. flood_adapt/dbs_classes/dbs_measure.py +112 -111
  48. flood_adapt/dbs_classes/dbs_projection.py +34 -34
  49. flood_adapt/dbs_classes/dbs_scenario.py +137 -137
  50. flood_adapt/dbs_classes/dbs_static.py +274 -273
  51. flood_adapt/dbs_classes/dbs_strategy.py +130 -129
  52. flood_adapt/dbs_classes/dbs_template.py +279 -278
  53. flood_adapt/dbs_classes/interface/database.py +107 -139
  54. flood_adapt/dbs_classes/interface/element.py +121 -121
  55. flood_adapt/dbs_classes/interface/static.py +47 -47
  56. flood_adapt/flood_adapt.py +1207 -1178
  57. flood_adapt/misc/database_user.py +16 -16
  58. flood_adapt/misc/exceptions.py +22 -0
  59. flood_adapt/misc/log.py +183 -183
  60. flood_adapt/misc/path_builder.py +54 -54
  61. flood_adapt/misc/utils.py +185 -185
  62. flood_adapt/objects/__init__.py +82 -82
  63. flood_adapt/objects/benefits/benefits.py +61 -61
  64. flood_adapt/objects/events/event_factory.py +135 -135
  65. flood_adapt/objects/events/event_set.py +88 -84
  66. flood_adapt/objects/events/events.py +234 -234
  67. flood_adapt/objects/events/historical.py +58 -58
  68. flood_adapt/objects/events/hurricane.py +68 -67
  69. flood_adapt/objects/events/synthetic.py +46 -50
  70. flood_adapt/objects/forcing/__init__.py +92 -92
  71. flood_adapt/objects/forcing/csv.py +68 -68
  72. flood_adapt/objects/forcing/discharge.py +66 -66
  73. flood_adapt/objects/forcing/forcing.py +150 -150
  74. flood_adapt/objects/forcing/forcing_factory.py +182 -182
  75. flood_adapt/objects/forcing/meteo_handler.py +93 -93
  76. flood_adapt/objects/forcing/netcdf.py +40 -40
  77. flood_adapt/objects/forcing/plotting.py +453 -429
  78. flood_adapt/objects/forcing/rainfall.py +98 -98
  79. flood_adapt/objects/forcing/tide_gauge.py +191 -191
  80. flood_adapt/objects/forcing/time_frame.py +90 -90
  81. flood_adapt/objects/forcing/timeseries.py +564 -564
  82. flood_adapt/objects/forcing/unit_system.py +580 -580
  83. flood_adapt/objects/forcing/waterlevels.py +108 -108
  84. flood_adapt/objects/forcing/wind.py +124 -124
  85. flood_adapt/objects/measures/measure_factory.py +92 -92
  86. flood_adapt/objects/measures/measures.py +529 -529
  87. flood_adapt/objects/object_model.py +74 -68
  88. flood_adapt/objects/projections/projections.py +103 -103
  89. flood_adapt/objects/scenarios/scenarios.py +22 -22
  90. flood_adapt/objects/strategies/strategies.py +89 -89
  91. flood_adapt/workflows/benefit_runner.py +579 -554
  92. flood_adapt/workflows/floodmap.py +85 -85
  93. flood_adapt/workflows/impacts_integrator.py +85 -85
  94. flood_adapt/workflows/scenario_runner.py +70 -70
  95. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
  96. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -865
  97. flood_adapt-0.3.10.dist-info/RECORD +140 -0
  98. flood_adapt-0.3.9.dist-info/RECORD +0 -139
  99. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
  100. {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
@@ -1,108 +1,108 @@
1
- import math
2
- import os
3
- from pathlib import Path
4
- from typing import Annotated
5
-
6
- import numpy as np
7
- import pandas as pd
8
- from pydantic import BaseModel
9
-
10
- from flood_adapt.misc.utils import (
11
- copy_file_to_output_dir,
12
- validate_file_extension,
13
- )
14
- from flood_adapt.objects.forcing import unit_system as us
15
- from flood_adapt.objects.forcing.forcing import (
16
- ForcingSource,
17
- IWaterlevel,
18
- )
19
- from flood_adapt.objects.forcing.time_frame import (
20
- TimeFrame,
21
- )
22
- from flood_adapt.objects.forcing.timeseries import (
23
- CSVTimeseries,
24
- SyntheticTimeseries,
25
- TimeseriesFactory,
26
- )
27
-
28
-
29
- class SurgeModel(BaseModel):
30
- """BaseModel describing the expected variables and data types for harmonic tide parameters of synthetic model."""
31
-
32
- timeseries: SyntheticTimeseries
33
-
34
-
35
- class TideModel(BaseModel):
36
- """BaseModel describing the expected variables and data types for harmonic tide parameters of synthetic model."""
37
-
38
- harmonic_amplitude: us.UnitfulLength
39
- harmonic_phase: us.UnitfulTime
40
- harmonic_period: us.UnitfulTime = us.UnitfulTime(
41
- value=12.4, units=us.UnitTypesTime.hours
42
- )
43
-
44
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
45
- index = pd.date_range(
46
- start=time_frame.start_time,
47
- end=time_frame.end_time,
48
- freq=time_frame.time_step,
49
- name="time",
50
- )
51
- seconds = np.arange(len(index)) * time_frame.time_step.total_seconds()
52
- seconds.round(decimals=0)
53
-
54
- amp = self.harmonic_amplitude.value
55
- omega = 2 * math.pi / (self.harmonic_period.convert(us.UnitTypesTime.seconds))
56
- phase_seconds = self.harmonic_phase.convert(us.UnitTypesTime.seconds)
57
-
58
- tide = amp * np.cos(omega * (seconds - phase_seconds))
59
- return pd.DataFrame(data=tide, index=index)
60
-
61
-
62
- class WaterlevelSynthetic(IWaterlevel):
63
- source: ForcingSource = ForcingSource.SYNTHETIC
64
-
65
- surge: SurgeModel
66
- tide: TideModel
67
-
68
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
69
- tide_df = self.tide.to_dataframe(time_frame=time_frame)
70
-
71
- surge_df = TimeseriesFactory.from_object(self.surge.timeseries).to_dataframe(
72
- time_frame=time_frame
73
- )
74
-
75
- # Combine
76
- tide_df.columns = ["waterlevel"]
77
- surge_df.columns = ["waterlevel"]
78
- surge_df = surge_df.reindex(tide_df.index, method="nearest", limit=1).fillna(
79
- value=self.surge.timeseries.fill_value
80
- )
81
-
82
- wl_df = tide_df.add(surge_df, axis="index", fill_value=0)
83
- wl_df.columns = ["waterlevel"]
84
-
85
- return wl_df
86
-
87
-
88
- class WaterlevelCSV(IWaterlevel):
89
- source: ForcingSource = ForcingSource.CSV
90
-
91
- path: Annotated[Path, validate_file_extension([".csv"])]
92
- units: us.UnitTypesLength = us.UnitTypesLength.meters
93
-
94
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
95
- return CSVTimeseries.load_file(
96
- path=self.path, units=us.UnitfulLength(value=0, units=self.units)
97
- ).to_dataframe(time_frame=time_frame)
98
-
99
- def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
100
- self.path = copy_file_to_output_dir(self.path, Path(output_dir))
101
-
102
-
103
- class WaterlevelModel(IWaterlevel):
104
- source: ForcingSource = ForcingSource.MODEL
105
-
106
-
107
- class WaterlevelGauged(IWaterlevel):
108
- source: ForcingSource = ForcingSource.GAUGED
1
+ import math
2
+ import os
3
+ from pathlib import Path
4
+ from typing import Annotated
5
+
6
+ import numpy as np
7
+ import pandas as pd
8
+ from pydantic import BaseModel
9
+
10
+ from flood_adapt.misc.utils import (
11
+ copy_file_to_output_dir,
12
+ validate_file_extension,
13
+ )
14
+ from flood_adapt.objects.forcing import unit_system as us
15
+ from flood_adapt.objects.forcing.forcing import (
16
+ ForcingSource,
17
+ IWaterlevel,
18
+ )
19
+ from flood_adapt.objects.forcing.time_frame import (
20
+ TimeFrame,
21
+ )
22
+ from flood_adapt.objects.forcing.timeseries import (
23
+ CSVTimeseries,
24
+ SyntheticTimeseries,
25
+ TimeseriesFactory,
26
+ )
27
+
28
+
29
+ class SurgeModel(BaseModel):
30
+ """BaseModel describing the expected variables and data types for harmonic tide parameters of synthetic model."""
31
+
32
+ timeseries: SyntheticTimeseries
33
+
34
+
35
+ class TideModel(BaseModel):
36
+ """BaseModel describing the expected variables and data types for harmonic tide parameters of synthetic model."""
37
+
38
+ harmonic_amplitude: us.UnitfulLength
39
+ harmonic_phase: us.UnitfulTime
40
+ harmonic_period: us.UnitfulTime = us.UnitfulTime(
41
+ value=12.4, units=us.UnitTypesTime.hours
42
+ )
43
+
44
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
45
+ index = pd.date_range(
46
+ start=time_frame.start_time,
47
+ end=time_frame.end_time,
48
+ freq=time_frame.time_step,
49
+ name="time",
50
+ )
51
+ seconds = np.arange(len(index)) * time_frame.time_step.total_seconds()
52
+ seconds.round(decimals=0)
53
+
54
+ amp = self.harmonic_amplitude.value
55
+ omega = 2 * math.pi / (self.harmonic_period.convert(us.UnitTypesTime.seconds))
56
+ phase_seconds = self.harmonic_phase.convert(us.UnitTypesTime.seconds)
57
+
58
+ tide = amp * np.cos(omega * (seconds - phase_seconds))
59
+ return pd.DataFrame(data=tide, index=index)
60
+
61
+
62
+ class WaterlevelSynthetic(IWaterlevel):
63
+ source: ForcingSource = ForcingSource.SYNTHETIC
64
+
65
+ surge: SurgeModel
66
+ tide: TideModel
67
+
68
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
69
+ tide_df = self.tide.to_dataframe(time_frame=time_frame)
70
+
71
+ surge_df = TimeseriesFactory.from_object(self.surge.timeseries).to_dataframe(
72
+ time_frame=time_frame
73
+ )
74
+
75
+ # Combine
76
+ tide_df.columns = ["waterlevel"]
77
+ surge_df.columns = ["waterlevel"]
78
+ surge_df = surge_df.reindex(tide_df.index, method="nearest", limit=1).fillna(
79
+ value=self.surge.timeseries.fill_value
80
+ )
81
+
82
+ wl_df = tide_df.add(surge_df, axis="index", fill_value=0)
83
+ wl_df.columns = ["waterlevel"]
84
+
85
+ return wl_df
86
+
87
+
88
+ class WaterlevelCSV(IWaterlevel):
89
+ source: ForcingSource = ForcingSource.CSV
90
+
91
+ path: Annotated[Path, validate_file_extension([".csv"])]
92
+ units: us.UnitTypesLength = us.UnitTypesLength.meters
93
+
94
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
95
+ return CSVTimeseries.load_file(
96
+ path=self.path, units=us.UnitfulLength(value=0, units=self.units)
97
+ ).to_dataframe(time_frame=time_frame)
98
+
99
+ def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
100
+ self.path = copy_file_to_output_dir(self.path, Path(output_dir))
101
+
102
+
103
+ class WaterlevelModel(IWaterlevel):
104
+ source: ForcingSource = ForcingSource.MODEL
105
+
106
+
107
+ class WaterlevelGauged(IWaterlevel):
108
+ source: ForcingSource = ForcingSource.GAUGED
@@ -1,124 +1,124 @@
1
- import os
2
- from pathlib import Path
3
- from typing import Annotated, Any
4
-
5
- import pandas as pd
6
- import xarray as xr
7
-
8
- from flood_adapt.misc.utils import (
9
- copy_file_to_output_dir,
10
- validate_file_extension,
11
- )
12
- from flood_adapt.objects.forcing import unit_system as us
13
- from flood_adapt.objects.forcing.forcing import (
14
- ForcingSource,
15
- IWind,
16
- )
17
- from flood_adapt.objects.forcing.netcdf import validate_netcdf_forcing
18
- from flood_adapt.objects.forcing.timeseries import (
19
- CSVTimeseries,
20
- SyntheticTimeseries,
21
- TimeFrame,
22
- TimeseriesFactory,
23
- )
24
-
25
-
26
- class WindConstant(IWind):
27
- source: ForcingSource = ForcingSource.CONSTANT
28
-
29
- speed: us.UnitfulVelocity
30
- direction: us.UnitfulDirection
31
-
32
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
33
- time = pd.date_range(
34
- start=time_frame.start_time,
35
- end=time_frame.end_time,
36
- freq=time_frame.time_step,
37
- name="time",
38
- )
39
- data = {
40
- "mag": [self.speed.value for _ in range(len(time))],
41
- "dir": [self.direction.value for _ in range(len(time))],
42
- }
43
- return pd.DataFrame(data=data, index=time)
44
-
45
-
46
- class WindSynthetic(IWind):
47
- source: ForcingSource = ForcingSource.SYNTHETIC
48
-
49
- magnitude: SyntheticTimeseries
50
- direction: SyntheticTimeseries
51
-
52
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
53
- time = pd.date_range(
54
- start=time_frame.start_time,
55
- end=time_frame.end_time,
56
- freq=time_frame.time_step,
57
- name="time",
58
- )
59
-
60
- magnitude = TimeseriesFactory.from_object(self.magnitude).to_dataframe(
61
- time_frame=time_frame,
62
- )
63
-
64
- direction = TimeseriesFactory.from_object(self.direction).to_dataframe(
65
- time_frame=time_frame,
66
- )
67
- return pd.DataFrame(
68
- index=time,
69
- data={
70
- "mag": magnitude.reindex(time).to_numpy().flatten(),
71
- "dir": direction.reindex(time).to_numpy().flatten(),
72
- },
73
- )
74
-
75
-
76
- class WindTrack(IWind):
77
- source: ForcingSource = ForcingSource.TRACK
78
-
79
- path: Annotated[Path, validate_file_extension([".cyc", ".spw"])]
80
- # path to cyc file, set this when creating it
81
-
82
- def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
83
- if self.path:
84
- self.path = copy_file_to_output_dir(self.path, Path(output_dir))
85
-
86
-
87
- class WindCSV(IWind):
88
- source: ForcingSource = ForcingSource.CSV
89
-
90
- path: Annotated[Path, validate_file_extension([".csv"])]
91
-
92
- units: dict[str, Any] = {
93
- "speed": us.UnitTypesVelocity.mps,
94
- "direction": us.UnitTypesDirection.degrees,
95
- }
96
-
97
- def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
98
- return CSVTimeseries.load_file(
99
- path=self.path, units=us.UnitfulVelocity(value=0, units=self.units["speed"])
100
- ).to_dataframe(time_frame)
101
-
102
- def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
103
- self.path = copy_file_to_output_dir(self.path, Path(output_dir))
104
-
105
-
106
- class WindMeteo(IWind):
107
- source: ForcingSource = ForcingSource.METEO
108
-
109
-
110
- class WindNetCDF(IWind):
111
- source: ForcingSource = ForcingSource.NETCDF
112
- units: us.UnitTypesVelocity = us.UnitTypesVelocity.mps
113
-
114
- path: Annotated[Path, validate_file_extension([".nc"])]
115
-
116
- def read(self) -> xr.Dataset:
117
- required_vars = ("wind10_v", "wind10_u", "press_msl")
118
- required_coords = ("time", "lat", "lon")
119
- with xr.open_dataset(self.path) as ds:
120
- validated_ds = validate_netcdf_forcing(ds, required_vars, required_coords)
121
- return validated_ds
122
-
123
- def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
124
- self.path = copy_file_to_output_dir(self.path, Path(output_dir))
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Annotated, Any
4
+
5
+ import pandas as pd
6
+ import xarray as xr
7
+
8
+ from flood_adapt.misc.utils import (
9
+ copy_file_to_output_dir,
10
+ validate_file_extension,
11
+ )
12
+ from flood_adapt.objects.forcing import unit_system as us
13
+ from flood_adapt.objects.forcing.forcing import (
14
+ ForcingSource,
15
+ IWind,
16
+ )
17
+ from flood_adapt.objects.forcing.netcdf import validate_netcdf_forcing
18
+ from flood_adapt.objects.forcing.timeseries import (
19
+ CSVTimeseries,
20
+ SyntheticTimeseries,
21
+ TimeFrame,
22
+ TimeseriesFactory,
23
+ )
24
+
25
+
26
+ class WindConstant(IWind):
27
+ source: ForcingSource = ForcingSource.CONSTANT
28
+
29
+ speed: us.UnitfulVelocity
30
+ direction: us.UnitfulDirection
31
+
32
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
33
+ time = pd.date_range(
34
+ start=time_frame.start_time,
35
+ end=time_frame.end_time,
36
+ freq=time_frame.time_step,
37
+ name="time",
38
+ )
39
+ data = {
40
+ "mag": [self.speed.value for _ in range(len(time))],
41
+ "dir": [self.direction.value for _ in range(len(time))],
42
+ }
43
+ return pd.DataFrame(data=data, index=time)
44
+
45
+
46
+ class WindSynthetic(IWind):
47
+ source: ForcingSource = ForcingSource.SYNTHETIC
48
+
49
+ magnitude: SyntheticTimeseries
50
+ direction: SyntheticTimeseries
51
+
52
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
53
+ time = pd.date_range(
54
+ start=time_frame.start_time,
55
+ end=time_frame.end_time,
56
+ freq=time_frame.time_step,
57
+ name="time",
58
+ )
59
+
60
+ magnitude = TimeseriesFactory.from_object(self.magnitude).to_dataframe(
61
+ time_frame=time_frame,
62
+ )
63
+
64
+ direction = TimeseriesFactory.from_object(self.direction).to_dataframe(
65
+ time_frame=time_frame,
66
+ )
67
+ return pd.DataFrame(
68
+ index=time,
69
+ data={
70
+ "mag": magnitude.reindex(time).to_numpy().flatten(),
71
+ "dir": direction.reindex(time).to_numpy().flatten(),
72
+ },
73
+ )
74
+
75
+
76
+ class WindTrack(IWind):
77
+ source: ForcingSource = ForcingSource.TRACK
78
+
79
+ path: Annotated[Path, validate_file_extension([".cyc", ".spw"])]
80
+ # path to cyc file, set this when creating it
81
+
82
+ def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
83
+ if self.path:
84
+ self.path = copy_file_to_output_dir(self.path, Path(output_dir))
85
+
86
+
87
+ class WindCSV(IWind):
88
+ source: ForcingSource = ForcingSource.CSV
89
+
90
+ path: Annotated[Path, validate_file_extension([".csv"])]
91
+
92
+ units: dict[str, Any] = {
93
+ "speed": us.UnitTypesVelocity.mps,
94
+ "direction": us.UnitTypesDirection.degrees,
95
+ }
96
+
97
+ def to_dataframe(self, time_frame: TimeFrame) -> pd.DataFrame:
98
+ return CSVTimeseries.load_file(
99
+ path=self.path, units=us.UnitfulVelocity(value=0, units=self.units["speed"])
100
+ ).to_dataframe(time_frame)
101
+
102
+ def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
103
+ self.path = copy_file_to_output_dir(self.path, Path(output_dir))
104
+
105
+
106
+ class WindMeteo(IWind):
107
+ source: ForcingSource = ForcingSource.METEO
108
+
109
+
110
+ class WindNetCDF(IWind):
111
+ source: ForcingSource = ForcingSource.NETCDF
112
+ units: us.UnitTypesVelocity = us.UnitTypesVelocity.mps
113
+
114
+ path: Annotated[Path, validate_file_extension([".nc"])]
115
+
116
+ def read(self) -> xr.Dataset:
117
+ required_vars = ("wind10_v", "wind10_u", "press_msl")
118
+ required_coords = ("time", "lat", "lon")
119
+ with xr.open_dataset(self.path) as ds:
120
+ validated_ds = validate_netcdf_forcing(ds, required_vars, required_coords)
121
+ return validated_ds
122
+
123
+ def save_additional(self, output_dir: Path | str | os.PathLike) -> None:
124
+ self.path = copy_file_to_output_dir(self.path, Path(output_dir))
@@ -1,92 +1,92 @@
1
- import os
2
- from typing import Union
3
-
4
- import tomli
5
-
6
- from flood_adapt.objects.measures.measures import (
7
- Buyout,
8
- Elevate,
9
- FloodProof,
10
- FloodWall,
11
- GreenInfrastructure,
12
- Measure,
13
- MeasureType,
14
- Pump,
15
- )
16
-
17
-
18
- class MeasureFactory:
19
- @staticmethod
20
- def get_measure_type(filepath: Union[str, os.PathLike]):
21
- """Get a measure type from toml file."""
22
- with open(filepath, mode="rb") as fp:
23
- toml = tomli.load(fp)
24
- type = toml.get("type")
25
- return MeasureType(type)
26
-
27
- @staticmethod
28
- def get_measure_object(filepath: Union[str, os.PathLike]) -> Measure:
29
- measure_type = MeasureFactory.get_measure_type(filepath)
30
-
31
- if MeasureType.is_impact(measure_type):
32
- return ImpactMeasureFactory.get_impact_measure(measure_type).load_file(
33
- filepath
34
- )
35
- elif MeasureType.is_hazard(measure_type):
36
- return HazardMeasureFactory.get_hazard_measure(measure_type).load_file(
37
- filepath
38
- )
39
- else:
40
- raise ValueError(f"Measure type {measure_type} not recognized.")
41
-
42
-
43
- class ImpactMeasureFactory:
44
- """Simple parser to get the respective measure subclass from a measure type string given in the config file.
45
-
46
- Args:
47
- type (str): name of measure type
48
-
49
- Returns
50
- -------
51
- Measure: Measure subclass
52
- """
53
-
54
- @staticmethod
55
- def get_impact_measure(impact_measure: str):
56
- if impact_measure == "elevate_properties":
57
- return Elevate
58
- elif impact_measure == "buyout_properties":
59
- return Buyout
60
- elif impact_measure == "floodproof_properties":
61
- return FloodProof
62
- else:
63
- raise ValueError(f"Measure type {impact_measure} not recognized.")
64
-
65
-
66
- class HazardMeasureFactory:
67
- """Simple parser to get the respective measure subclass from a measure type string given in the config file.
68
-
69
- Args:
70
- type (str): name of measure type
71
-
72
- Returns
73
- -------
74
- Measure: Measure subclass
75
- """
76
-
77
- @staticmethod
78
- def get_hazard_measure(hazard_measure: str):
79
- if (
80
- hazard_measure == "floodwall" or hazard_measure == "levee"
81
- ): # these should use the same class right?
82
- return FloodWall
83
- elif (
84
- hazard_measure == "water_square"
85
- or hazard_measure == "total_storage"
86
- or hazard_measure == "greening"
87
- ):
88
- return GreenInfrastructure
89
- elif hazard_measure == "pump":
90
- return Pump
91
- else:
92
- raise ValueError(f"Measure type {hazard_measure} not recognized.")
1
+ import os
2
+ from typing import Union
3
+
4
+ import tomli
5
+
6
+ from flood_adapt.objects.measures.measures import (
7
+ Buyout,
8
+ Elevate,
9
+ FloodProof,
10
+ FloodWall,
11
+ GreenInfrastructure,
12
+ Measure,
13
+ MeasureType,
14
+ Pump,
15
+ )
16
+
17
+
18
+ class MeasureFactory:
19
+ @staticmethod
20
+ def get_measure_type(filepath: Union[str, os.PathLike]):
21
+ """Get a measure type from toml file."""
22
+ with open(filepath, mode="rb") as fp:
23
+ toml = tomli.load(fp)
24
+ type = toml.get("type")
25
+ return MeasureType(type)
26
+
27
+ @staticmethod
28
+ def get_measure_object(filepath: Union[str, os.PathLike]) -> Measure:
29
+ measure_type = MeasureFactory.get_measure_type(filepath)
30
+
31
+ if MeasureType.is_impact(measure_type):
32
+ return ImpactMeasureFactory.get_impact_measure(measure_type).load_file(
33
+ filepath
34
+ )
35
+ elif MeasureType.is_hazard(measure_type):
36
+ return HazardMeasureFactory.get_hazard_measure(measure_type).load_file(
37
+ filepath
38
+ )
39
+ else:
40
+ raise ValueError(f"Measure type {measure_type} not recognized.")
41
+
42
+
43
+ class ImpactMeasureFactory:
44
+ """Simple parser to get the respective measure subclass from a measure type string given in the config file.
45
+
46
+ Args:
47
+ type (str): name of measure type
48
+
49
+ Returns
50
+ -------
51
+ Measure: Measure subclass
52
+ """
53
+
54
+ @staticmethod
55
+ def get_impact_measure(impact_measure: str):
56
+ if impact_measure == "elevate_properties":
57
+ return Elevate
58
+ elif impact_measure == "buyout_properties":
59
+ return Buyout
60
+ elif impact_measure == "floodproof_properties":
61
+ return FloodProof
62
+ else:
63
+ raise ValueError(f"Measure type {impact_measure} not recognized.")
64
+
65
+
66
+ class HazardMeasureFactory:
67
+ """Simple parser to get the respective measure subclass from a measure type string given in the config file.
68
+
69
+ Args:
70
+ type (str): name of measure type
71
+
72
+ Returns
73
+ -------
74
+ Measure: Measure subclass
75
+ """
76
+
77
+ @staticmethod
78
+ def get_hazard_measure(hazard_measure: str):
79
+ if (
80
+ hazard_measure == "floodwall" or hazard_measure == "levee"
81
+ ): # these should use the same class right?
82
+ return FloodWall
83
+ elif (
84
+ hazard_measure == "water_square"
85
+ or hazard_measure == "total_storage"
86
+ or hazard_measure == "greening"
87
+ ):
88
+ return GreenInfrastructure
89
+ elif hazard_measure == "pump":
90
+ return Pump
91
+ else:
92
+ raise ValueError(f"Measure type {hazard_measure} not recognized.")