flood-adapt 0.3.11__tar.gz → 0.3.12__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 (147) hide show
  1. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/PKG-INFO +1 -1
  2. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/__init__.py +3 -1
  3. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/fiat_adapter.py +35 -9
  4. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/sfincs_adapter.py +169 -75
  5. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/gui.py +1 -0
  6. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/database_builder.py +316 -223
  7. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/database.py +62 -3
  8. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_benefit.py +1 -0
  9. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_event.py +1 -0
  10. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_measure.py +1 -0
  11. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_projection.py +1 -0
  12. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_scenario.py +1 -0
  13. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_strategy.py +1 -0
  14. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_template.py +2 -1
  15. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/log.py +20 -12
  16. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/historical.py +3 -3
  17. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/hurricane.py +1 -1
  18. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/plotting.py +7 -34
  19. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/PKG-INFO +1 -1
  20. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/tests/test_flood_adapt.py +6 -0
  21. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/LICENSE +0 -0
  22. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/README.md +0 -0
  23. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/__init__.py +0 -0
  24. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/interface/__init__.py +0 -0
  25. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/interface/hazard_adapter.py +0 -0
  26. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/interface/impact_adapter.py +0 -0
  27. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/interface/model_adapter.py +0 -0
  28. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/interface/offshore.py +0 -0
  29. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/adapter/sfincs_offshore.py +0 -0
  30. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/__init__.py +0 -0
  31. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/config.py +0 -0
  32. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/fiat.py +0 -0
  33. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/sfincs.py +0 -0
  34. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/config/site.py +0 -0
  35. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/__init__.py +0 -0
  36. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/default_units/imperial.toml +0 -0
  37. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/default_units/metric.toml +0 -0
  38. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +0 -0
  39. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/black_down_48x48.png +0 -0
  40. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/black_left_48x48.png +0 -0
  41. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/black_right_48x48.png +0 -0
  42. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/black_up_48x48.png +0 -0
  43. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_down.png +0 -0
  44. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_left.png +0 -0
  45. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_right.png +0 -0
  46. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_up.png +0 -0
  47. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_down.png +0 -0
  48. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_left.png +0 -0
  49. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_right.png +0 -0
  50. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_up.png +0 -0
  51. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_left.png +0 -0
  52. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_right.png +0 -0
  53. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/white_down_48x48.png +0 -0
  54. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/white_left_48x48.png +0 -0
  55. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/white_right_48x48.png +0 -0
  56. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/icons/white_up_48x48.png +0 -0
  57. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +0 -0
  58. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +0 -0
  59. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +0 -0
  60. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +0 -0
  61. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/OSM/styles.css +0 -0
  62. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +0 -0
  63. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +0 -0
  64. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +0 -0
  65. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +0 -0
  66. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +0 -0
  67. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/ambulance.png +0 -0
  68. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/car.png +0 -0
  69. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/cart.png +0 -0
  70. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/firetruck.png +0 -0
  71. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/hospital.png +0 -0
  72. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/house.png +0 -0
  73. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/info.png +0 -0
  74. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/money.png +0 -0
  75. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/person.png +0 -0
  76. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/school.png +0 -0
  77. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/truck.png +0 -0
  78. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infographics/images/walking_person.png +0 -0
  79. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +0 -0
  80. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +0 -0
  81. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +0 -0
  82. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +0 -0
  83. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +0 -0
  84. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +0 -0
  85. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +0 -0
  86. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +0 -0
  87. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +0 -0
  88. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +0 -0
  89. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +0 -0
  90. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +0 -0
  91. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder/templates/output_layers/bin_colors.toml +0 -0
  92. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/database_builder.py +0 -0
  93. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/__init__.py +0 -0
  94. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/dbs_static.py +0 -0
  95. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/interface/database.py +0 -0
  96. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/interface/element.py +0 -0
  97. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/dbs_classes/interface/static.py +0 -0
  98. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/flood_adapt.py +0 -0
  99. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/__init__.py +0 -0
  100. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/database_user.py +0 -0
  101. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/exceptions.py +0 -0
  102. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/path_builder.py +0 -0
  103. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/misc/utils.py +0 -0
  104. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/__init__.py +0 -0
  105. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/benefits/__init__.py +0 -0
  106. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/benefits/benefits.py +0 -0
  107. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/__init__.py +0 -0
  108. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/event_factory.py +0 -0
  109. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/event_set.py +0 -0
  110. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/events.py +0 -0
  111. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/events/synthetic.py +0 -0
  112. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/__init__.py +0 -0
  113. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/csv.py +0 -0
  114. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/discharge.py +0 -0
  115. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/forcing.py +0 -0
  116. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/forcing_factory.py +0 -0
  117. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/meteo_handler.py +0 -0
  118. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/netcdf.py +0 -0
  119. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/rainfall.py +0 -0
  120. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/tide_gauge.py +0 -0
  121. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/time_frame.py +0 -0
  122. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/timeseries.py +0 -0
  123. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/unit_system.py +0 -0
  124. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/waterlevels.py +0 -0
  125. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/forcing/wind.py +0 -0
  126. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/measures/__init__.py +0 -0
  127. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/measures/measure_factory.py +0 -0
  128. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/measures/measures.py +0 -0
  129. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/object_model.py +0 -0
  130. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/projections/__init__.py +0 -0
  131. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/projections/projections.py +0 -0
  132. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/scenarios/__init__.py +0 -0
  133. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/scenarios/scenarios.py +0 -0
  134. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/strategies/__init__.py +0 -0
  135. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/objects/strategies/strategies.py +0 -0
  136. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/workflows/__init__.py +0 -0
  137. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/workflows/benefit_runner.py +0 -0
  138. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/workflows/floodmap.py +0 -0
  139. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/workflows/impacts_integrator.py +0 -0
  140. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt/workflows/scenario_runner.py +0 -0
  141. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/SOURCES.txt +0 -0
  142. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/dependency_links.txt +0 -0
  143. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/not-zip-safe +0 -0
  144. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/requires.txt +0 -0
  145. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/flood_adapt.egg-info/top_level.txt +0 -0
  146. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/pyproject.toml +0 -0
  147. {flood_adapt-0.3.11 → flood_adapt-0.3.12}/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.12
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,9 +1,10 @@
1
1
  # has to be here at the start to avoid circular imports
2
- __version__ = "0.3.11"
2
+ __version__ = "0.3.12"
3
3
 
4
4
  from flood_adapt import adapter, dbs_classes, objects
5
5
  from flood_adapt.config.config import Settings
6
6
  from flood_adapt.config.site import Site
7
+ from flood_adapt.database_builder.database_builder import DatabaseBuilder
7
8
  from flood_adapt.flood_adapt import FloodAdapt
8
9
  from flood_adapt.misc.exceptions import ComponentError, DatabaseError, FloodAdaptError
9
10
  from flood_adapt.misc.log import FloodAdaptLogging
@@ -21,6 +22,7 @@ __all__ = [
21
22
  "FloodAdaptError",
22
23
  "DatabaseError",
23
24
  "ComponentError",
25
+ "DatabaseBuilder",
24
26
  ]
25
27
 
26
28
  FloodAdaptLogging() # Initialize logging once for the entire package
@@ -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.
@@ -1539,3 +1543,25 @@ class FiatAdapter(IImpactAdapter):
1539
1543
  if line.startswith("#"):
1540
1544
  line = "#" + " " * hash_spacing + line.lstrip("#")
1541
1545
  file.write(line)
1546
+
1547
+ def _delete_simulation_folder(self, scn: Scenario):
1548
+ """
1549
+ Delete the Delft-FIAT simulation folder for a given scenario.
1550
+
1551
+ Parameters
1552
+ ----------
1553
+ scn : Scenario
1554
+ The scenario for which the simulation folder should be deleted.
1555
+
1556
+ Raises
1557
+ ------
1558
+ OSError
1559
+ If the directory cannot be deleted.
1560
+ """
1561
+ simulation_path = (
1562
+ self.database.scenarios.output_path / scn.name / "Impacts" / "fiat_model"
1563
+ )
1564
+ if simulation_path.exists():
1565
+ self.close_files()
1566
+ shutil.rmtree(simulation_path)
1567
+ 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(
@@ -765,89 +764,32 @@ class SfincsAdapter(IHazardAdapter):
765
764
 
766
765
  with SfincsAdapter(model_root=sim_paths[0]) as dummymodel:
767
766
  # 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()
767
+ mask = dummymodel.get_mask()
768
+ zb = dummymodel.get_bedlevel()
770
769
 
771
770
  zs_maps = []
772
771
  for simulation_path in sim_paths:
773
772
  # read zsmax data from overland sfincs model
774
773
  with SfincsAdapter(model_root=simulation_path) as sim:
775
774
  zsmax = sim._get_zsmax().load()
776
- zs_stacked = zsmax.stack(z=("x", "y"))
777
- zs_maps.append(zs_stacked)
775
+ zs_maps.append(zsmax)
778
776
 
779
777
  # 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
778
  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
779
+ rp_flood_maps = self.calc_rp_maps(
780
+ floodmaps=zs_maps,
781
+ frequencies=frequencies,
782
+ zb=zb,
783
+ mask=mask,
784
+ return_periods=floodmap_rp,
785
+ )
841
786
 
842
787
  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()
788
+ zs_rp_single = rp_flood_maps[ii]
847
789
  zs_rp_single = zs_rp_single.rio.write_crs(
848
790
  zsmax.raster.crs
849
791
  ) # , inplace=True)
850
- zs_rp_single = zs_rp_single.to_dataset(name="risk_map")
792
+ zs_rp_single = zs_rp_single.to_dataset(name="risk_map").transpose()
851
793
  fn_rp = result_path / f"RP_{rp:04d}_maps.nc"
852
794
  zs_rp_single.to_netcdf(fn_rp)
853
795
 
@@ -886,10 +828,21 @@ class SfincsAdapter(IHazardAdapter):
886
828
  self.process(scenario, event)
887
829
  self.postprocess(scenario, event)
888
830
 
889
- if not self.settings.config.save_simulation:
890
- shutil.rmtree(
891
- self._get_simulation_path(scenario, sub_event=event), ignore_errors=True
892
- )
831
+ if self.settings.config.save_simulation:
832
+ self._delete_simulation_folder(scenario, sub_event=event)
833
+
834
+ def _delete_simulation_folder(
835
+ self, scenario: Scenario, sub_event: Optional[Event] = None
836
+ ):
837
+ """Delete the simulation folder for a given scenario and optional sub-event."""
838
+ sim_path = self._get_simulation_path(scenario, sub_event=sub_event)
839
+ if sim_path.exists():
840
+ shutil.rmtree(sim_path, ignore_errors=True)
841
+ self.logger.info(f"Deleted simulation folder: {sim_path}")
842
+
843
+ if sim_path.parent.exists() and not any(sim_path.parent.iterdir()):
844
+ # Remove the parent directory `simulations` if it is empty
845
+ sim_path.parent.rmdir()
893
846
 
894
847
  def _run_risk_scenario(self, scenario: Scenario):
895
848
  """Run the whole workflow for a risk scenario.
@@ -1851,3 +1804,144 @@ class SfincsAdapter(IHazardAdapter):
1851
1804
  fig["data"][0]["name"] = "model"
1852
1805
  fig["data"][1]["name"] = "measurement"
1853
1806
  fig.update_layout(showlegend=True)
1807
+
1808
+ @staticmethod
1809
+ def calc_rp_maps(
1810
+ floodmaps: list[xr.DataArray],
1811
+ frequencies: list[float],
1812
+ zb: xr.DataArray,
1813
+ mask: xr.DataArray,
1814
+ return_periods: list[float],
1815
+ ) -> list[xr.DataArray]:
1816
+ """
1817
+ Calculate return period (RP) flood maps from a set of flood simulation results.
1818
+
1819
+ This function processes multiple flood simulation outputs (water level maps) and their associated frequencies
1820
+ to generate hazard maps for specified return periods. It interpolates water levels for each return period
1821
+ using exceedance probabilities and handles masked or dry cells appropriately.
1822
+
1823
+ Args:
1824
+ floodmaps (list[xr.DataArray]): List of water level maps (xarray DataArrays), one for each simulation.
1825
+ frequencies (list[float]): List of frequencies (probabilities of occurrence) corresponding to each floodmap.
1826
+ zb (np.ndarray): Array of bed elevations for each grid cell.
1827
+ mask (xr.DataArray): Mask indicating valid (1) and invalid (0) grid cells.
1828
+ return_periods (list[float]): List of return periods (in years) for which to generate hazard maps.
1829
+
1830
+ Returns
1831
+ -------
1832
+ list[xr.DataArray]: List of xarray DataArrays, each representing the hazard map for a given return period.
1833
+ Each DataArray contains water levels (meters) for the corresponding return period.
1834
+ """
1835
+ floodmaps = floodmaps.copy() # avoid modifying the original list
1836
+ # Check that all floodmaps have the same shape and dimensions
1837
+ first_shape = floodmaps[0].shape
1838
+ first_dims = floodmaps[0].dims
1839
+ for i, floodmap in enumerate(floodmaps):
1840
+ if floodmap.shape != first_shape or floodmap.dims != first_dims:
1841
+ raise ValueError(
1842
+ f"Floodmap at index {i} does not match the shape or dimensions of the first floodmap. "
1843
+ f"Expected shape {first_shape} and dims {first_dims}, got shape {floodmap.shape} and dims {floodmap.dims}."
1844
+ )
1845
+
1846
+ # Check that zb and mask have the same shape
1847
+ if zb.shape != mask.shape:
1848
+ raise ValueError(
1849
+ "Bed elevation array (zb) and mask must have the same shape."
1850
+ )
1851
+
1852
+ # Check that floodmaps, zb, and mask all have the same shape
1853
+ if (
1854
+ len(first_shape) != len(zb.shape)
1855
+ or first_shape != zb.shape
1856
+ or first_shape != mask.shape
1857
+ ):
1858
+ raise ValueError(
1859
+ f"Floodmaps, bed elevation array (zb), and mask must all have the same shape. "
1860
+ f"Floodmap shape: {first_shape}, zb shape: {zb.shape}, mask shape: {mask.shape}."
1861
+ )
1862
+
1863
+ # stack dimensions if floodmaps are 2D
1864
+ if len(floodmaps[0].shape) > 1:
1865
+ stacking = True
1866
+ for i, floodmap in enumerate(floodmaps):
1867
+ floodmaps[i] = floodmap.stack(z=("x", "y"))
1868
+ zb = zb.stack(z=("x", "y"))
1869
+ mask = mask.stack(z=("x", "y"))
1870
+ else:
1871
+ stacking = False
1872
+
1873
+ # 1a: make a table of all water levels and associated frequencies
1874
+ zs = xr.concat(floodmaps, pd.Index(frequencies, name="frequency"))
1875
+ # Get the indices of columns with all NaN values
1876
+ nan_cells = np.where(np.all(np.isnan(zs), axis=0))[0]
1877
+ # fill nan values with minimum bed levels in each grid cell, np.interp cannot ignore nan values
1878
+ zs = xr.where(np.isnan(zs), np.tile(zb, (zs.shape[0], 1)), zs)
1879
+ # Get table of frequencies
1880
+ freq = np.tile(frequencies, (zs.shape[1], 1)).transpose()
1881
+
1882
+ # 1b: sort water levels in descending order and include the frequencies in the sorting process
1883
+ # (i.e. each h-value should be linked to the same p-values as in step 1a)
1884
+ sort_index = zs.argsort(axis=0)
1885
+ sorted_prob = np.flipud(np.take_along_axis(freq, sort_index, axis=0))
1886
+ sorted_zs = np.flipud(np.take_along_axis(zs.values, sort_index, axis=0))
1887
+
1888
+ # 1c: Compute exceedance probabilities of water depths
1889
+ # Method: accumulate probabilities from top to bottom
1890
+ prob_exceed = np.cumsum(sorted_prob, axis=0)
1891
+
1892
+ # 1d: Compute return periods of water depths
1893
+ # Method: simply take the inverse of the exceedance probability (1/Pex)
1894
+ rp_zs = 1.0 / prob_exceed
1895
+
1896
+ # For each return period (T) of interest do the following:
1897
+ # For each grid cell do the following:
1898
+ # Use the table from step [1d] as a “lookup-table” to derive the T-year water depth. Use a 1-d interpolation technique:
1899
+ # h(T) = interp1 (log(T*), h*, log(T))
1900
+ # in which t* and h* are the values from the table and T is the return period (T) of interest
1901
+ # The resulting T-year water depths for all grids combined form the T-year hazard map
1902
+ rp_da = xr.DataArray(rp_zs, dims=zs.dims)
1903
+
1904
+ # no_data_value = -999 # in SFINCS
1905
+ # sorted_zs = xr.where(sorted_zs == no_data_value, np.nan, sorted_zs)
1906
+
1907
+ valid_cells = np.where(mask == 1)[
1908
+ 0
1909
+ ] # only loop over cells where model is not masked
1910
+ h = matlib.repmat(
1911
+ np.copy(zb), len(return_periods), 1
1912
+ ) # 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
1913
+
1914
+ for jj in valid_cells: # looping over all non-masked cells.
1915
+ # linear interpolation for all return periods to evaluate
1916
+ h[:, jj] = np.interp(
1917
+ np.log10(return_periods),
1918
+ np.log10(rp_da[::-1, jj]),
1919
+ sorted_zs[::-1, jj],
1920
+ left=0,
1921
+ )
1922
+
1923
+ # Re-fill locations that had nan water level for all simulations with nans
1924
+ h[:, nan_cells] = np.full(h[:, nan_cells].shape, np.nan)
1925
+
1926
+ # If a cell has the same water-level as the bed elevation it should be dry (turn to nan)
1927
+ diff = h - np.tile(zb, (h.shape[0], 1))
1928
+ dry = (
1929
+ diff < 10e-10
1930
+ ) # here we use a small number instead of zero for rounding errors
1931
+ h[dry] = np.nan
1932
+
1933
+ rp_maps = []
1934
+ for ii, rp in enumerate(return_periods):
1935
+ da = xr.DataArray(
1936
+ data=h[ii, :], coords={"z": zs["z"]}, attrs={"units": "meters"}
1937
+ )
1938
+ if stacking:
1939
+ # Ensure unstacking creates (y, x) dimensions in the correct order
1940
+ da = da.unstack()
1941
+ # Reorder dimensions if needed
1942
+ if set(da.dims) == {"y", "x"} and da.dims != ("y", "x"):
1943
+ da = da.transpose("y", "x")
1944
+ # #create single nc
1945
+ rp_maps.append(da)
1946
+
1947
+ 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):