Skip to content

Commit

Permalink
Merge branch 'main' into fix-vulnerability-curves-damage-types
Browse files Browse the repository at this point in the history
  • Loading branch information
frederique-hub authored Oct 31, 2023
2 parents 7ee262e + 0486132 commit 5e2e01c
Show file tree
Hide file tree
Showing 16 changed files with 1,614 additions and 423 deletions.
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,15 @@ venv.bak/
cache
/examples/FIAT_database
hydromt_fiat/data/damage_functions/flooding/AllDDF_HAZUS_fractions.xlsx
hydromt_fiat/data/damage_functions/flooding/Hazus_IWR_curves.csv
hydromt_fiat/data/damage_functions/flooding/Hazus_IWR_curves.xlsx
examples/data/update_ground_floor_height/test_update_ground_floor_height_points
examples/data/update_ground_floor_height/test_update_ground_floor_height_polygons
examples/data/building_footprints/fiat_model_bfs
examples/data/aggregation_zones/output
examples/data/aggregation_zones/output

# notebooks
/examples/aggregation_zones_example_files
/examples/data/aggregation_zones/aggregation_zones_test1/
/examples/data/aggregation_zones/aggregation_zones_test2/
examples/aggregation_zones_example.html
1,776 changes: 1,489 additions & 287 deletions examples/aggregation_zones_example.ipynb

Large diffs are not rendered by default.

25 changes: 0 additions & 25 deletions examples/data/aggregation_zones/config_aggregation.yml

This file was deleted.

8 changes: 8 additions & 0 deletions examples/data/aggregation_zones/configuration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
setup_aggregation_areas:
aggregation_area_fn: "data/aggregation_zones/aggregation_zones/base_zones.gpkg"
attribute_names: ZONE_BASE
label_names: Base_zones




13 changes: 13 additions & 0 deletions examples/data/aggregation_zones/configuration_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
setup_aggregation_areas:
aggregation_area_fn:
- "data/aggregation_zones/aggregation_zones/base_zones.gpkg"
- "data/aggregation_zones/aggregation_zones/land_use.gpkg"
- "data/aggregation_zones/aggregation_zones/accomodation_type.gpkg"
attribute_names:
- ZONE_BASE
- LAND_USE
- ACCOM
label_names:
- Base_zones
- Land_use
- Accommodation_type
36 changes: 13 additions & 23 deletions hydromt_fiat/api/data_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from typing_extensions import Optional, TypedDict, Union
from typing_extensions import Optional, TypedDict, Union, List

from pydantic import BaseModel

Expand Down Expand Up @@ -53,36 +53,26 @@ class ModelIni(BaseModel):
crs: str


class ExposureVectorIni(BaseModel):
class VulnerabilityIni(BaseModel):
vulnerability_fn: str
vulnerability_identifiers_and_linking_fn: str
unit: Units
functions_mean: Union[str, list]
functions_max: Union[str, list, None]
step_size: Union[float, None]


class ExposureBuildingsIni(BaseModel):
asset_locations: str
occupancy_type: str
max_potential_damage: str
ground_floor_height: str
unit: Units
extraction_method: ExtractionMethod


class HazardIni(BaseModel):
hazard_map_fn: str
hazard_type: str
return_period: Optional[Union[int, None]] = None
crs: Optional[str] = None
no_data: Optional[int] = -9999
var: Optional[Union[str, None]] = None
chunks: Optional[Union[int, str]] = "auto"
no_data: Optional[int] = -9999
var: Optional[Union[str, None]] = None
chunks: Optional[Union[int, str]] = "auto"


class VulnerabilityIni(BaseModel):
vulnerability_fn: str
link_table: str
units: Units
damage_types : Union[List[str], None]


class ConfigIni(BaseModel):
setup_config: ModelIni
setup_hazard: HazardIni
setup_vulnerability: VulnerabilityIni
setup_exposure_buildings: ExposureVectorIni
setup_exposure_buildings: ExposureBuildingsIni
34 changes: 14 additions & 20 deletions hydromt_fiat/api/exposure_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DataCatalogEntry,
DataType,
Driver,
ExposureVectorIni,
ExposureBuildingsIni,
ExtractionMethod,
Units,
)
Expand All @@ -22,17 +22,19 @@ class ExposureViewModel:
def __init__(
self, database: IDatabase, data_catalog: DataCatalog, logger: logging.Logger
):
self.exposure_model = ExposureVectorIni(
self.exposure_model = ExposureBuildingsIni(
asset_locations="",
occupancy_type="",
max_potential_damage=-999,
ground_floor_height=-999,
unit=Units.m.value,
extraction_method=ExtractionMethod.centroid.value,
damage_types=["structure", "content"]
)
self.database: IDatabase = database
self.data_catalog: DataCatalog = data_catalog
self.logger: logging.Logger = logger
self.exposure: ExposureVector = None

def create_interest_area(self, **kwargs: str):
fpath = kwargs.get("fpath")
Expand All @@ -57,37 +59,36 @@ def set_asset_locations_source(
):
if input_source == "NSI":
# NSI is already defined in the data catalog
# Add NSI to the configuration file
self.exposure_model.asset_locations = input_source
self.exposure_model.occupancy_type = input_source
self.exposure_model.max_potential_damage = input_source
self.exposure_model.ground_floor_height = 1 # TODO: make flexible
self.exposure_model.ground_floor_height = input_source
self.exposure_model.unit = Units.ft.value # TODO: make flexible

# Download NSI from the database
region = self.data_catalog.get_geodataframe("area_of_interest")
exposure = ExposureVector(
self.exposure = ExposureVector(
data_catalog=self.data_catalog,
logger=self.logger,
region=region,
crs=crs,
)

exposure.setup_from_single_source(
self.exposure.setup_buildings_from_single_source(
input_source,
self.exposure_model.ground_floor_height,
"centroid", # TODO: MAKE FLEXIBLE
)
primary_object_types = (
exposure.exposure_db["Primary Object Type"].unique().tolist()
self.exposure.exposure_db["Primary Object Type"].unique().tolist()
)
secondary_object_types = (
exposure.exposure_db["Secondary Object Type"].unique().tolist()
self.exposure.exposure_db["Secondary Object Type"].unique().tolist()
)
exposure.set_exposure_geoms_from_xy()
gdf = self.exposure.get_full_gdf(self.exposure.exposure_db)

return (
exposure.exposure_geoms[0],
gdf,
primary_object_types,
secondary_object_types,
)
Expand All @@ -110,13 +111,6 @@ def set_asset_locations_source(
print(catalog_entry)
# write to data catalog

def create_extraction_map(self, *args):
# TODO: implement callback
# if no exceptions, then self.exposure_model.extraction_method = args[0]
# else if
# make backend call to api with arguments to set extraction method per object:
# create first with default method. Then get uploaded or drawn area and merge with default methid
# save file to database
# change self.exposure_model.extraction_method to file
...
# change self.exposure_model.extraction_method to file
def setup_extraction_method(self, extraction_method):
if self.exposure:
self.exposure.setup_extraction_method(extraction_method)
6 changes: 0 additions & 6 deletions hydromt_fiat/api/hazard_vm.py

This file was deleted.

67 changes: 30 additions & 37 deletions hydromt_fiat/api/hydromt_fiat_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,42 @@
from hydromt_fiat.api.data_types import ConfigIni
from hydromt_fiat.api.dbs_controller import LocalDatabase
from hydromt_fiat.api.exposure_vm import ExposureViewModel
from hydromt_fiat.api.hazard_vm import HazardViewModel
from hydromt_fiat.api.model_vm import ModelViewModel
from hydromt_fiat.api.vulnerability_vm import VulnerabilityViewModel
from hydromt_fiat.fiat import FiatModel
from hydromt.log import setuplog


class Singleton(object):
_instance = None

def __new__(cls, *args: Any, **kwargs: Any):
if not isinstance(cls._instance, cls):
cls._instance = object.__new__(cls)
return cls._instance


class HydroMtViewModel(Singleton):
is_initialized: bool = False
class HydroMtViewModel:
data_catalog: DataCatalog
database: LocalDatabase

def __init__(
self,
database_path: str,
catalog_path: Union[List, str],
hydromt_fiat_path: str = None,
hydromt_fiat_path: str,
):
if not self.__class__.is_initialized:
database_path = Path(database_path)

HydroMtViewModel.database = LocalDatabase.create_database(database_path)
HydroMtViewModel.data_catalog = DataCatalog(catalog_path)
database_path = Path(database_path)

if hydromt_fiat_path is not None:
logger = setuplog("hydromt_fiat", log_level=10)
self.fiat_model = FiatModel(
data_libs=catalog_path,
root=hydromt_fiat_path,
mode="w+",
logger=logger,
)
HydroMtViewModel.database = LocalDatabase.create_database(database_path)
HydroMtViewModel.data_catalog = DataCatalog(catalog_path)

self.model_vm = ModelViewModel()
self.exposure_vm = ExposureViewModel(
HydroMtViewModel.database, HydroMtViewModel.data_catalog, logger
)
self.vulnerability_vm = VulnerabilityViewModel(
HydroMtViewModel.database, HydroMtViewModel.data_catalog, logger
)
self.hazard_vm = HazardViewModel()
logger = setuplog("hydromt_fiat", log_level=10)
self.fiat_model = FiatModel(
data_libs=catalog_path,
root=hydromt_fiat_path,
mode="w+",
logger=logger,
)

self.__class__.is_initialized = True
self.model_vm = ModelViewModel()
self.exposure_vm = ExposureViewModel(
HydroMtViewModel.database, HydroMtViewModel.data_catalog, logger
)
self.vulnerability_vm = VulnerabilityViewModel(
HydroMtViewModel.database, HydroMtViewModel.data_catalog, logger
)

def clear_database(self):
# TODO: delete database after hydromt_fiat has run
Expand All @@ -71,7 +55,6 @@ def save_data_catalog(self):
def build_config_ini(self):
config_ini = ConfigIni(
setup_config=self.model_vm.config_model,
setup_hazard=self.hazard_vm.hazard_model,
setup_vulnerability=self.vulnerability_vm.vulnerability_model,
setup_exposure_buildings=self.exposure_vm.exposure_model,
)
Expand All @@ -81,7 +64,17 @@ def build_config_ini(self):
with open(database_path / "config.ini", "wb") as f:
tomli_w.dump(config_ini.dict(exclude_none=True), f)

def read(self):
self.fiat_model.read()

def run_hydromt_fiat(self):
config_ini = ConfigIni(
setup_config=self.model_vm.config_model,
setup_vulnerability=self.vulnerability_vm.vulnerability_model,
setup_exposure_buildings=self.exposure_vm.exposure_model,
)
region = self.data_catalog.get_geodataframe("area_of_interest")
self.fiat_model.build(region={"geom": region}, opt=ConfigIni.dict())
self.fiat_model.build(region={"geom": region}, opt=config_ini.dict())
self.fiat_model.write()


25 changes: 21 additions & 4 deletions hydromt_fiat/api/vulnerability_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,29 @@ def __init__(
self, database: IDatabase, data_catalog: DataCatalog, logger: logging.Logger
):
self.vulnerability_model = VulnerabilityIni(
vulnerability_fn="", link_table="", units=Units.m.value
vulnerability_fn="",
vulnerability_identifiers_and_linking_fn="",
unit=Units.ft.value,
functions_mean="default",
)
self.database: IDatabase = database
self.data_catalog: DataCatalog = data_catalog
self.logger: logging.Logger = logger
self.linking_standard_colnames = ["Name", "Link"]
self.linking_standard_colnames = [
"FIAT Damage Function Name",
"Exposure Link",
] # add "Damage Type" ?
self.linking_colnames = list()
self.linking_list = list()

def get_default_curves_linking_file(self):
return self.data_catalog.get_dataframe("default_hazus_iwr_linking")

def add_vulnerability_curves_to_model(self, vulnerability_fn, link_table):
self.vulnerability_model.vulnerability_fn = vulnerability_fn
self.vulnerability_model.vulnerability_identifiers_and_linking_fn = link_table
print("Damage curves added")

def get_hazus_curves(self):
self.logger.info("Getting Hazus curves")
df_vulnerability = self.data_catalog.get_dataframe("hazus_vulnerability_curves")
Expand All @@ -45,7 +59,10 @@ def save_linking_table(self):
df = pd.DataFrame(
columns=self.linking_standard_colnames, data=self.linking_list
)
self.vulnerability_model.link_table = str(
self.vulnerability_model.vulnerability_identifiers_and_linking_fn = str(
self.database.drive / "linking_table.csv"
)
df.to_csv(self.vulnerability_model.link_table, index=False)
df.to_csv(
self.vulnerability_model.vulnerability_identifiers_and_linking_fn,
index=False,
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"Secondary Object Type": "occtype",
"Max Potential Damage: Structure": "val_struct",
"Max Potential Damage: Content": "val_cont",
"Ground Floor Height": "found_ht",
"Ground Elevation": "ground_elv",
"X Coordinate": "x",
"Y Coordinate": "y",
"geometry": "geometry",
"Aggregation Label: Census Block": "cbfips"
}
2 changes: 1 addition & 1 deletion hydromt_fiat/fiat.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def setup_exposure_buildings(
"""
self.exposure = ExposureVector(self.data_catalog, self.logger, self.region)

if asset_locations == occupancy_type == max_potential_damage:
if asset_locations == occupancy_type == max_potential_damage == ground_floor_height:
# The source for the asset locations, occupancy type and maximum potential
# damage is the same, use one source to create the exposure data.
self.exposure.setup_buildings_from_single_source(
Expand Down
Loading

0 comments on commit 5e2e01c

Please sign in to comment.