flood-adapt 0.3.11__tar.gz → 0.3.13__tar.gz

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 (148) hide show
  1. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/PKG-INFO +1 -1
  2. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/__init__.py +3 -2
  3. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/fiat_adapter.py +44 -9
  4. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/sfincs_adapter.py +173 -76
  5. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/gui.py +1 -0
  6. flood_adapt-0.3.13/flood_adapt/database_builder/__init__.py +23 -0
  7. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/database_builder.py +615 -362
  8. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +2 -2
  9. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +1 -1
  10. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +1 -1
  11. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/database.py +62 -3
  12. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_benefit.py +1 -0
  13. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_event.py +1 -0
  14. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_measure.py +1 -0
  15. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_projection.py +1 -0
  16. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_scenario.py +1 -0
  17. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_strategy.py +1 -0
  18. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_template.py +2 -1
  19. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/misc/log.py +20 -12
  20. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/historical.py +3 -3
  21. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/hurricane.py +1 -1
  22. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/plotting.py +7 -34
  23. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/PKG-INFO +1 -1
  24. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/SOURCES.txt +0 -1
  25. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/tests/test_flood_adapt.py +6 -0
  26. flood_adapt-0.3.11/flood_adapt/database_builder.py +0 -16
  27. flood_adapt-0.3.11/flood_adapt/workflows/__init__.py +0 -0
  28. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/LICENSE +0 -0
  29. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/README.md +0 -0
  30. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/__init__.py +0 -0
  31. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/interface/__init__.py +0 -0
  32. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/interface/hazard_adapter.py +0 -0
  33. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/interface/impact_adapter.py +0 -0
  34. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/interface/model_adapter.py +0 -0
  35. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/interface/offshore.py +0 -0
  36. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/adapter/sfincs_offshore.py +0 -0
  37. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/__init__.py +0 -0
  38. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/config.py +0 -0
  39. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/fiat.py +0 -0
  40. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/sfincs.py +0 -0
  41. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/config/site.py +0 -0
  42. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/default_units/imperial.toml +0 -0
  43. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/default_units/metric.toml +0 -0
  44. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +0 -0
  45. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/black_down_48x48.png +0 -0
  46. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/black_left_48x48.png +0 -0
  47. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/black_right_48x48.png +0 -0
  48. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/black_up_48x48.png +0 -0
  49. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_down.png +0 -0
  50. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_left.png +0 -0
  51. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_right.png +0 -0
  52. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_up.png +0 -0
  53. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_down.png +0 -0
  54. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_left.png +0 -0
  55. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_right.png +0 -0
  56. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_up.png +0 -0
  57. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_left.png +0 -0
  58. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_right.png +0 -0
  59. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/white_down_48x48.png +0 -0
  60. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/white_left_48x48.png +0 -0
  61. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/white_right_48x48.png +0 -0
  62. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/icons/white_up_48x48.png +0 -0
  63. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +0 -0
  64. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +0 -0
  65. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/OSM/styles.css +0 -0
  66. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +0 -0
  67. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +0 -0
  68. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +0 -0
  69. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +0 -0
  70. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/ambulance.png +0 -0
  71. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/car.png +0 -0
  72. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/cart.png +0 -0
  73. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/firetruck.png +0 -0
  74. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/hospital.png +0 -0
  75. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/house.png +0 -0
  76. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/info.png +0 -0
  77. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/money.png +0 -0
  78. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/person.png +0 -0
  79. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/school.png +0 -0
  80. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/truck.png +0 -0
  81. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infographics/images/walking_person.png +0 -0
  82. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +0 -0
  83. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +0 -0
  84. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +0 -0
  85. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +0 -0
  86. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +0 -0
  87. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +0 -0
  88. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +0 -0
  89. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +0 -0
  90. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +0 -0
  91. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +0 -0
  92. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +0 -0
  93. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +0 -0
  94. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/database_builder/templates/output_layers/bin_colors.toml +0 -0
  95. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/__init__.py +0 -0
  96. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/dbs_static.py +0 -0
  97. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/interface/database.py +0 -0
  98. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/interface/element.py +0 -0
  99. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/dbs_classes/interface/static.py +0 -0
  100. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/flood_adapt.py +0 -0
  101. {flood_adapt-0.3.11/flood_adapt/database_builder → flood_adapt-0.3.13/flood_adapt/misc}/__init__.py +0 -0
  102. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/misc/database_user.py +0 -0
  103. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/misc/exceptions.py +0 -0
  104. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/misc/path_builder.py +0 -0
  105. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/misc/utils.py +0 -0
  106. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/__init__.py +0 -0
  107. {flood_adapt-0.3.11/flood_adapt/misc → flood_adapt-0.3.13/flood_adapt/objects/benefits}/__init__.py +0 -0
  108. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/benefits/benefits.py +0 -0
  109. {flood_adapt-0.3.11/flood_adapt/objects/benefits → flood_adapt-0.3.13/flood_adapt/objects/events}/__init__.py +0 -0
  110. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/event_factory.py +0 -0
  111. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/event_set.py +0 -0
  112. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/events.py +0 -0
  113. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/events/synthetic.py +0 -0
  114. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/__init__.py +0 -0
  115. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/csv.py +0 -0
  116. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/discharge.py +0 -0
  117. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/forcing.py +0 -0
  118. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/forcing_factory.py +0 -0
  119. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/meteo_handler.py +0 -0
  120. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/netcdf.py +0 -0
  121. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/rainfall.py +0 -0
  122. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/tide_gauge.py +0 -0
  123. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/time_frame.py +0 -0
  124. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/timeseries.py +0 -0
  125. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/unit_system.py +0 -0
  126. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/waterlevels.py +0 -0
  127. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/forcing/wind.py +0 -0
  128. {flood_adapt-0.3.11/flood_adapt/objects/events → flood_adapt-0.3.13/flood_adapt/objects/measures}/__init__.py +0 -0
  129. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/measures/measure_factory.py +0 -0
  130. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/measures/measures.py +0 -0
  131. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/object_model.py +0 -0
  132. {flood_adapt-0.3.11/flood_adapt/objects/measures → flood_adapt-0.3.13/flood_adapt/objects/projections}/__init__.py +0 -0
  133. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/projections/projections.py +0 -0
  134. {flood_adapt-0.3.11/flood_adapt/objects/projections → flood_adapt-0.3.13/flood_adapt/objects/scenarios}/__init__.py +0 -0
  135. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/scenarios/scenarios.py +0 -0
  136. {flood_adapt-0.3.11/flood_adapt/objects/scenarios → flood_adapt-0.3.13/flood_adapt/objects/strategies}/__init__.py +0 -0
  137. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/objects/strategies/strategies.py +0 -0
  138. {flood_adapt-0.3.11/flood_adapt/objects/strategies → flood_adapt-0.3.13/flood_adapt/workflows}/__init__.py +0 -0
  139. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/workflows/benefit_runner.py +0 -0
  140. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/workflows/floodmap.py +0 -0
  141. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/workflows/impacts_integrator.py +0 -0
  142. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt/workflows/scenario_runner.py +0 -0
  143. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/dependency_links.txt +0 -0
  144. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/not-zip-safe +0 -0
  145. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/requires.txt +0 -0
  146. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/flood_adapt.egg-info/top_level.txt +0 -0
  147. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/pyproject.toml +0 -0
  148. {flood_adapt-0.3.11 → flood_adapt-0.3.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: flood-adapt
3
- Version: 0.3.11
3
+ Version: 0.3.13
4
4
  Summary: A software package support system which can be used to assess the benefits and costs of flood resilience measures
5
5
  Author-email: Gundula Winter <Gundula.Winter@deltares.nl>, Panos Athanasiou <Panos.Athanasiou@deltares.nl>, Frederique de Groen <Frederique.deGroen@deltares.nl>, Tim de Wilde <Tim.deWilde@deltares.nl>, Julian Hofer <Julian.Hofer@deltares.nl>, Daley Adrichem <Daley.Adrichem@deltares.nl>, Luuk Blom <Luuk.Blom@deltares.nl>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1,7 +1,7 @@
1
1
  # has to be here at the start to avoid circular imports
2
- __version__ = "0.3.11"
2
+ __version__ = "0.3.13"
3
3
 
4
- from flood_adapt import adapter, dbs_classes, objects
4
+ from flood_adapt import adapter, database_builder, dbs_classes, objects
5
5
  from flood_adapt.config.config import Settings
6
6
  from flood_adapt.config.site import Site
7
7
  from flood_adapt.flood_adapt import FloodAdapt
@@ -18,6 +18,7 @@ __all__ = [
18
18
  "objects",
19
19
  "dbs_classes",
20
20
  "adapter",
21
+ "database_builder",
21
22
  "FloodAdaptError",
22
23
  "DatabaseError",
23
24
  "ComponentError",
@@ -153,11 +153,16 @@ class FiatAdapter(IImpactAdapter):
153
153
 
154
154
  def close_files(self):
155
155
  """Close all open files and clean up file handles."""
156
- if hasattr(self.logger, "handlers"):
157
- for handler in self.logger.handlers:
158
- if isinstance(handler, logging.FileHandler):
159
- handler.close()
160
- self.logger.removeHandler(handler)
156
+ loggers = [self.logger]
157
+ if self._model is not None:
158
+ loggers.append(self._model.logger)
159
+
160
+ for logger in loggers:
161
+ if hasattr(logger, "handlers"):
162
+ for handler in logger.handlers:
163
+ if isinstance(handler, logging.FileHandler):
164
+ handler.close()
165
+ logger.removeHandler(handler)
161
166
 
162
167
  def __enter__(self) -> "FiatAdapter":
163
168
  return self
@@ -198,11 +203,10 @@ class FiatAdapter(IImpactAdapter):
198
203
  ------
199
204
  OSError: If the directory cannot be deleted.
200
205
  """
201
- self.logger.info("Deleting Delft-FIAT simulation folder")
202
- try:
206
+ self.close_files()
207
+ if self.model_root.exists():
208
+ self.logger.info(f"Deleting {self.model_root}")
203
209
  shutil.rmtree(self.model_root)
204
- except OSError as e_info:
205
- self.logger.warning(f"{e_info}\nCould not delete {self.model_root}.")
206
210
 
207
211
  def fiat_completed(self) -> bool:
208
212
  """Check if fiat has run as expected.
@@ -876,6 +880,15 @@ class FiatAdapter(IImpactAdapter):
876
880
  for aggr in self.config.aggregation
877
881
  ]
878
882
  new_dev_geom_name = Path(self.config.new_development_file_name).stem
883
+ # Ensure new_devs geom is in the correct CRS
884
+ new_dev_geom = gpd.read_file(area_path)
885
+ if new_dev_geom.crs != self.model.exposure.crs:
886
+ self.logger.warning(
887
+ f"New development area geometries are in {new_dev_geom.crs}, but the model is in {self.model.exposure.crs}. Reprojecting geometries."
888
+ )
889
+ new_dev_geom = new_dev_geom.to_crs(self.model.exposure.crs)
890
+ # Replace file with the reprojected one
891
+ new_dev_geom.to_file(area_path, driver="GPKG", mode="w")
879
892
  # Use hydromt function
880
893
  self.model.exposure.setup_new_composite_areas(
881
894
  percent_growth=population_growth,
@@ -1539,3 +1552,25 @@ class FiatAdapter(IImpactAdapter):
1539
1552
  if line.startswith("#"):
1540
1553
  line = "#" + " " * hash_spacing + line.lstrip("#")
1541
1554
  file.write(line)
1555
+
1556
+ def _delete_simulation_folder(self, scn: Scenario):
1557
+ """
1558
+ Delete the Delft-FIAT simulation folder for a given scenario.
1559
+
1560
+ Parameters
1561
+ ----------
1562
+ scn : Scenario
1563
+ The scenario for which the simulation folder should be deleted.
1564
+
1565
+ Raises
1566
+ ------
1567
+ OSError
1568
+ If the directory cannot be deleted.
1569
+ """
1570
+ simulation_path = (
1571
+ self.database.scenarios.output_path / scn.name / "Impacts" / "fiat_model"
1572
+ )
1573
+ if simulation_path.exists():
1574
+ self.close_files()
1575
+ shutil.rmtree(simulation_path)
1576
+ self.logger.info(f"Deleted Delft-FIAT simulation folder: {simulation_path}")
@@ -257,9 +257,8 @@ class SfincsAdapter(IHazardAdapter):
257
257
  template_path = (
258
258
  self.database.static.get_overland_sfincs_model().get_model_root()
259
259
  )
260
- shutil.copytree(template_path, sim_path, dirs_exist_ok=True)
261
260
 
262
- with SfincsAdapter(model_root=sim_path) as model:
261
+ with SfincsAdapter(model_root=template_path) as model:
263
262
  model._load_scenario_objects(scenario, event)
264
263
  is_risk = "Probabilistic " if model._event_set is not None else ""
265
264
  self.logger.info(
@@ -676,7 +675,10 @@ class SfincsAdapter(IHazardAdapter):
676
675
  )
677
676
 
678
677
  event = self.database.events.get(scenario.event)
679
- if self.settings.obs_point[ii].name == self.settings.tide_gauge.name:
678
+ if (
679
+ self.settings.tide_gauge is not None
680
+ and self.settings.obs_point[ii].name == self.settings.tide_gauge.name
681
+ ):
680
682
  self._add_tide_gauge_plot(fig, event, units=gui_units)
681
683
 
682
684
  # write html to results folder
@@ -765,89 +767,32 @@ class SfincsAdapter(IHazardAdapter):
765
767
 
766
768
  with SfincsAdapter(model_root=sim_paths[0]) as dummymodel:
767
769
  # read mask and bed level
768
- mask = dummymodel.get_mask().stack(z=("x", "y"))
769
- zb = dummymodel.get_bedlevel().stack(z=("x", "y")).to_numpy()
770
+ mask = dummymodel.get_mask()
771
+ zb = dummymodel.get_bedlevel()
770
772
 
771
773
  zs_maps = []
772
774
  for simulation_path in sim_paths:
773
775
  # read zsmax data from overland sfincs model
774
776
  with SfincsAdapter(model_root=simulation_path) as sim:
775
777
  zsmax = sim._get_zsmax().load()
776
- zs_stacked = zsmax.stack(z=("x", "y"))
777
- zs_maps.append(zs_stacked)
778
+ zs_maps.append(zsmax)
778
779
 
779
780
  # Create RP flood maps
780
-
781
- # 1a: make a table of all water levels and associated frequencies
782
- zs = xr.concat(zs_maps, pd.Index(frequencies, name="frequency"))
783
- # Get the indices of columns with all NaN values
784
- nan_cells = np.where(np.all(np.isnan(zs), axis=0))[0]
785
- # fill nan values with minimum bed levels in each grid cell, np.interp cannot ignore nan values
786
- zs = xr.where(np.isnan(zs), np.tile(zb, (zs.shape[0], 1)), zs)
787
- # Get table of frequencies
788
- freq = np.tile(frequencies, (zs.shape[1], 1)).transpose()
789
-
790
- # 1b: sort water levels in descending order and include the frequencies in the sorting process
791
- # (i.e. each h-value should be linked to the same p-values as in step 1a)
792
- sort_index = zs.argsort(axis=0)
793
- sorted_prob = np.flipud(np.take_along_axis(freq, sort_index, axis=0))
794
- sorted_zs = np.flipud(np.take_along_axis(zs.values, sort_index, axis=0))
795
-
796
- # 1c: Compute exceedance probabilities of water depths
797
- # Method: accumulate probabilities from top to bottom
798
- prob_exceed = np.cumsum(sorted_prob, axis=0)
799
-
800
- # 1d: Compute return periods of water depths
801
- # Method: simply take the inverse of the exceedance probability (1/Pex)
802
- rp_zs = 1.0 / prob_exceed
803
-
804
- # For each return period (T) of interest do the following:
805
- # For each grid cell do the following:
806
- # Use the table from step [1d] as a “lookup-table” to derive the T-year water depth. Use a 1-d interpolation technique:
807
- # h(T) = interp1 (log(T*), h*, log(T))
808
- # in which t* and h* are the values from the table and T is the return period (T) of interest
809
- # The resulting T-year water depths for all grids combined form the T-year hazard map
810
- rp_da = xr.DataArray(rp_zs, dims=zs.dims)
811
-
812
- # no_data_value = -999 # in SFINCS
813
- # sorted_zs = xr.where(sorted_zs == no_data_value, np.nan, sorted_zs)
814
-
815
- valid_cells = np.where(mask == 1)[
816
- 0
817
- ] # only loop over cells where model is not masked
818
- h = matlib.repmat(
819
- np.copy(zb), len(floodmap_rp), 1
820
- ) # if not flooded (i.e. not in valid_cells) revert to bed_level, read from SFINCS results so it is the minimum bed level in a grid cell
821
-
822
781
  self.logger.info("Calculating flood risk maps, this may take some time")
823
- for jj in valid_cells: # looping over all non-masked cells.
824
- # linear interpolation for all return periods to evaluate
825
- h[:, jj] = np.interp(
826
- np.log10(floodmap_rp),
827
- np.log10(rp_da[::-1, jj]),
828
- sorted_zs[::-1, jj],
829
- left=0,
830
- )
831
-
832
- # Re-fill locations that had nan water level for all simulations with nans
833
- h[:, nan_cells] = np.full(h[:, nan_cells].shape, np.nan)
834
-
835
- # If a cell has the same water-level as the bed elevation it should be dry (turn to nan)
836
- diff = h - np.tile(zb, (h.shape[0], 1))
837
- dry = (
838
- diff < 10e-10
839
- ) # here we use a small number instead of zero for rounding errors
840
- h[dry] = np.nan
782
+ rp_flood_maps = self.calc_rp_maps(
783
+ floodmaps=zs_maps,
784
+ frequencies=frequencies,
785
+ zb=zb,
786
+ mask=mask,
787
+ return_periods=floodmap_rp,
788
+ )
841
789
 
842
790
  for ii, rp in enumerate(floodmap_rp):
843
- # #create single nc
844
- zs_rp_single = xr.DataArray(
845
- data=h[ii, :], coords={"z": zs["z"]}, attrs={"units": "meters"}
846
- ).unstack()
791
+ zs_rp_single = rp_flood_maps[ii]
847
792
  zs_rp_single = zs_rp_single.rio.write_crs(
848
793
  zsmax.raster.crs
849
794
  ) # , inplace=True)
850
- zs_rp_single = zs_rp_single.to_dataset(name="risk_map")
795
+ zs_rp_single = zs_rp_single.to_dataset(name="risk_map").transpose()
851
796
  fn_rp = result_path / f"RP_{rp:04d}_maps.nc"
852
797
  zs_rp_single.to_netcdf(fn_rp)
853
798
 
@@ -886,10 +831,21 @@ class SfincsAdapter(IHazardAdapter):
886
831
  self.process(scenario, event)
887
832
  self.postprocess(scenario, event)
888
833
 
889
- if not self.settings.config.save_simulation:
890
- shutil.rmtree(
891
- self._get_simulation_path(scenario, sub_event=event), ignore_errors=True
892
- )
834
+ if self.settings.config.save_simulation:
835
+ self._delete_simulation_folder(scenario, sub_event=event)
836
+
837
+ def _delete_simulation_folder(
838
+ self, scenario: Scenario, sub_event: Optional[Event] = None
839
+ ):
840
+ """Delete the simulation folder for a given scenario and optional sub-event."""
841
+ sim_path = self._get_simulation_path(scenario, sub_event=sub_event)
842
+ if sim_path.exists():
843
+ shutil.rmtree(sim_path, ignore_errors=True)
844
+ self.logger.info(f"Deleted simulation folder: {sim_path}")
845
+
846
+ if sim_path.parent.exists() and not any(sim_path.parent.iterdir()):
847
+ # Remove the parent directory `simulations` if it is empty
848
+ sim_path.parent.rmdir()
893
849
 
894
850
  def _run_risk_scenario(self, scenario: Scenario):
895
851
  """Run the whole workflow for a risk scenario.
@@ -1851,3 +1807,144 @@ class SfincsAdapter(IHazardAdapter):
1851
1807
  fig["data"][0]["name"] = "model"
1852
1808
  fig["data"][1]["name"] = "measurement"
1853
1809
  fig.update_layout(showlegend=True)
1810
+
1811
+ @staticmethod
1812
+ def calc_rp_maps(
1813
+ floodmaps: list[xr.DataArray],
1814
+ frequencies: list[float],
1815
+ zb: xr.DataArray,
1816
+ mask: xr.DataArray,
1817
+ return_periods: list[float],
1818
+ ) -> list[xr.DataArray]:
1819
+ """
1820
+ Calculate return period (RP) flood maps from a set of flood simulation results.
1821
+
1822
+ This function processes multiple flood simulation outputs (water level maps) and their associated frequencies
1823
+ to generate hazard maps for specified return periods. It interpolates water levels for each return period
1824
+ using exceedance probabilities and handles masked or dry cells appropriately.
1825
+
1826
+ Args:
1827
+ floodmaps (list[xr.DataArray]): List of water level maps (xarray DataArrays), one for each simulation.
1828
+ frequencies (list[float]): List of frequencies (probabilities of occurrence) corresponding to each floodmap.
1829
+ zb (np.ndarray): Array of bed elevations for each grid cell.
1830
+ mask (xr.DataArray): Mask indicating valid (1) and invalid (0) grid cells.
1831
+ return_periods (list[float]): List of return periods (in years) for which to generate hazard maps.
1832
+
1833
+ Returns
1834
+ -------
1835
+ list[xr.DataArray]: List of xarray DataArrays, each representing the hazard map for a given return period.
1836
+ Each DataArray contains water levels (meters) for the corresponding return period.
1837
+ """
1838
+ floodmaps = floodmaps.copy() # avoid modifying the original list
1839
+ # Check that all floodmaps have the same shape and dimensions
1840
+ first_shape = floodmaps[0].shape
1841
+ first_dims = floodmaps[0].dims
1842
+ for i, floodmap in enumerate(floodmaps):
1843
+ if floodmap.shape != first_shape or floodmap.dims != first_dims:
1844
+ raise ValueError(
1845
+ f"Floodmap at index {i} does not match the shape or dimensions of the first floodmap. "
1846
+ f"Expected shape {first_shape} and dims {first_dims}, got shape {floodmap.shape} and dims {floodmap.dims}."
1847
+ )
1848
+
1849
+ # Check that zb and mask have the same shape
1850
+ if zb.shape != mask.shape:
1851
+ raise ValueError(
1852
+ "Bed elevation array (zb) and mask must have the same shape."
1853
+ )
1854
+
1855
+ # Check that floodmaps, zb, and mask all have the same shape
1856
+ if (
1857
+ len(first_shape) != len(zb.shape)
1858
+ or first_shape != zb.shape
1859
+ or first_shape != mask.shape
1860
+ ):
1861
+ raise ValueError(
1862
+ f"Floodmaps, bed elevation array (zb), and mask must all have the same shape. "
1863
+ f"Floodmap shape: {first_shape}, zb shape: {zb.shape}, mask shape: {mask.shape}."
1864
+ )
1865
+
1866
+ # stack dimensions if floodmaps are 2D
1867
+ if len(floodmaps[0].shape) > 1:
1868
+ stacking = True
1869
+ for i, floodmap in enumerate(floodmaps):
1870
+ floodmaps[i] = floodmap.stack(z=("x", "y"))
1871
+ zb = zb.stack(z=("x", "y"))
1872
+ mask = mask.stack(z=("x", "y"))
1873
+ else:
1874
+ stacking = False
1875
+
1876
+ # 1a: make a table of all water levels and associated frequencies
1877
+ zs = xr.concat(floodmaps, pd.Index(frequencies, name="frequency"))
1878
+ # Get the indices of columns with all NaN values
1879
+ nan_cells = np.where(np.all(np.isnan(zs), axis=0))[0]
1880
+ # fill nan values with minimum bed levels in each grid cell, np.interp cannot ignore nan values
1881
+ zs = xr.where(np.isnan(zs), np.tile(zb, (zs.shape[0], 1)), zs)
1882
+ # Get table of frequencies
1883
+ freq = np.tile(frequencies, (zs.shape[1], 1)).transpose()
1884
+
1885
+ # 1b: sort water levels in descending order and include the frequencies in the sorting process
1886
+ # (i.e. each h-value should be linked to the same p-values as in step 1a)
1887
+ sort_index = zs.argsort(axis=0)
1888
+ sorted_prob = np.flipud(np.take_along_axis(freq, sort_index, axis=0))
1889
+ sorted_zs = np.flipud(np.take_along_axis(zs.values, sort_index, axis=0))
1890
+
1891
+ # 1c: Compute exceedance probabilities of water depths
1892
+ # Method: accumulate probabilities from top to bottom
1893
+ prob_exceed = np.cumsum(sorted_prob, axis=0)
1894
+
1895
+ # 1d: Compute return periods of water depths
1896
+ # Method: simply take the inverse of the exceedance probability (1/Pex)
1897
+ rp_zs = 1.0 / prob_exceed
1898
+
1899
+ # For each return period (T) of interest do the following:
1900
+ # For each grid cell do the following:
1901
+ # Use the table from step [1d] as a “lookup-table” to derive the T-year water depth. Use a 1-d interpolation technique:
1902
+ # h(T) = interp1 (log(T*), h*, log(T))
1903
+ # in which t* and h* are the values from the table and T is the return period (T) of interest
1904
+ # The resulting T-year water depths for all grids combined form the T-year hazard map
1905
+ rp_da = xr.DataArray(rp_zs, dims=zs.dims)
1906
+
1907
+ # no_data_value = -999 # in SFINCS
1908
+ # sorted_zs = xr.where(sorted_zs == no_data_value, np.nan, sorted_zs)
1909
+
1910
+ valid_cells = np.where(mask == 1)[
1911
+ 0
1912
+ ] # only loop over cells where model is not masked
1913
+ h = matlib.repmat(
1914
+ np.copy(zb), len(return_periods), 1
1915
+ ) # if not flooded (i.e. not in valid_cells) revert to bed_level, read from SFINCS results so it is the minimum bed level in a grid cell
1916
+
1917
+ for jj in valid_cells: # looping over all non-masked cells.
1918
+ # linear interpolation for all return periods to evaluate
1919
+ h[:, jj] = np.interp(
1920
+ np.log10(return_periods),
1921
+ np.log10(rp_da[::-1, jj]),
1922
+ sorted_zs[::-1, jj],
1923
+ left=0,
1924
+ )
1925
+
1926
+ # Re-fill locations that had nan water level for all simulations with nans
1927
+ h[:, nan_cells] = np.full(h[:, nan_cells].shape, np.nan)
1928
+
1929
+ # If a cell has the same water-level as the bed elevation it should be dry (turn to nan)
1930
+ diff = h - np.tile(zb, (h.shape[0], 1))
1931
+ dry = (
1932
+ diff < 10e-10
1933
+ ) # here we use a small number instead of zero for rounding errors
1934
+ h[dry] = np.nan
1935
+
1936
+ rp_maps = []
1937
+ for ii, rp in enumerate(return_periods):
1938
+ da = xr.DataArray(
1939
+ data=h[ii, :], coords={"z": zs["z"]}, attrs={"units": "meters"}
1940
+ )
1941
+ if stacking:
1942
+ # Ensure unstacking creates (y, x) dimensions in the correct order
1943
+ da = da.unstack()
1944
+ # Reorder dimensions if needed
1945
+ if set(da.dims) == {"y", "x"} and da.dims != ("y", "x"):
1946
+ da = da.transpose("y", "x")
1947
+ # #create single nc
1948
+ rp_maps.append(da)
1949
+
1950
+ return rp_maps
@@ -39,6 +39,7 @@ class Layer(BaseModel):
39
39
  class FloodMapLayer(Layer):
40
40
  zbmax: float
41
41
  depth_min: float
42
+ roads_min_zoom_level: int = 14
42
43
 
43
44
 
44
45
  class AggregationDmgLayer(Layer):
@@ -0,0 +1,23 @@
1
+ from flood_adapt.database_builder.database_builder import (
2
+ Basins,
3
+ ConfigModel,
4
+ FootprintsOptions,
5
+ GuiConfigModel,
6
+ SpatialJoinModel,
7
+ SviConfigModel,
8
+ TideGaugeConfigModel,
9
+ UnitSystems,
10
+ create_database,
11
+ )
12
+
13
+ __all__ = [
14
+ "Basins",
15
+ "ConfigModel",
16
+ "FootprintsOptions",
17
+ "GuiConfigModel",
18
+ "SpatialJoinModel",
19
+ "SviConfigModel",
20
+ "TideGaugeConfigModel",
21
+ "UnitSystems",
22
+ "create_database",
23
+ ]