Using the Loss Calculator
Using the Loss Calculator¶
This continues from an open connection to your 25.01 sample database, as in Explore Data.
# uncomment to install the packages
# !pip install matplotlib folium mapclassify geopandas
# !pip install exposurelib taxonomylib
# !pip install git+https://git.gfz-potsdam.de/globaldynamicexposure/loss-calculator@docs-patch
from exposurelib import SpatiaLiteExposure
from shapely import from_wkt
import geopandas
Set up the database for calculations¶
Open a new database connection for the loss calculator's own working
database, then copy the 25.01 data it needs into it. db.create_tables()
already creates the current entities/assets/entity_assets/taxonomies
schema, so this is a straight table-for-table copy — note that sources
must be copied too, since entities.source_id has a foreign key to it:
db = SpatiaLiteExposure('data/losscalculator.db')
try:
db.connect()
db.create_tables()
print('attach database')
db.connection.executescript(
"""
ATTACH DATABASE 'data/CDMX_2501_sample.db' AS source;
INSERT INTO taxonomies SELECT * FROM source.taxonomies;
INSERT INTO sources SELECT * FROM source.sources;
INSERT INTO entities SELECT * FROM source.entities;
INSERT INTO assets SELECT * FROM source.assets;
INSERT INTO entity_assets SELECT * FROM source.entity_assets;
"""
)
db.connection.commit()
db.close()
except Exception as e:
print("Delete existing dataset if Integrity Error - InitSpatialMetaData()")
print(e)
Not fully verified against the loss-calculator package
Everything from here on depends on the external damagecalculator CLI
and the loss-calculator package
(git+https://.../loss-calculator@docs-patch). The database-copy step
above has been run for real against a 25.01 sample and works. Whether
the view_damage_tile_1 view (and the SQL the CLI issues internally)
has itself been updated for the 25.01 entities/assets/entity_assets
schema, rather than the old flat Entity/Asset/Taxonomy tables,
still needs confirming by whoever maintains loss-calculator.
Calculate damage loss¶
!damagecalculator damage \
-e data/losscalculator.db \
-f data/fragility_ESRM20_various_IM.xml \
-g data/ground_motion_field.csv \
-t data/esrm20_exposure_vulnerability_mapping.csv \
-S losscalculator
db = SpatiaLiteExposure('data/losscalculator.db')
db.connect()
sql_query = """
SELECT
quadkey,
ST_AsText(geometry),
no_damage_damage AS no_damage,
slight_damage,
moderate_damage,
extensive_damage,
complete_damage
FROM view_damage_tile_1
"""
db.cursor.execute(sql_query)
res = db.cursor.fetchall()
df_dict = {
"quadkey": [], "geometry": [], "no_damage": [],
"slight_damage": [], "moderate_damage": [],
"extensive_damage": [], "complete_damage": [],
}
for quadkey, geom, nd, sd, md, ed, cd in res:
df_dict["quadkey"].append(quadkey)
df_dict["geometry"].append(from_wkt(geom))
df_dict["no_damage"].append(nd)
df_dict["slight_damage"].append(sd)
df_dict["moderate_damage"].append(md)
df_dict["extensive_damage"].append(ed)
df_dict["complete_damage"].append(cd)
Check results on a map¶
gdf = geopandas.GeoDataFrame(df_dict, crs='EPSG:4326')
gdf.iloc[:, 2:] = gdf.iloc[:, 2:].round(2)
gdf.explore('slight_damage')
Get descriptive statistics¶
damage_columns = ["no_damage", "slight_damage", "moderate_damage", "extensive_damage", "complete_damage"]
damage_stats = gdf[damage_columns].describe().T
damage_stats["total"] = gdf[damage_columns].sum()
damage_stats