Commit 501baa62 authored by Marius Kriegerowski's avatar Marius Kriegerowski
Browse files

Added ground motion field abstraction and optimized imports

parent 481e114b
Pipeline #36053 passed with stage
in 2 minutes and 23 seconds
......@@ -17,19 +17,19 @@
# along with this program. If not, see http://www.gnu.org/licenses/.
import os
import argparse
import numpy as np
import pandas as pd
import geopandas as gpd
import datetime
import os
import sqlite3
import geopandas as gpd
import pandas as pd
from shapely import wkt
from .fragility_model import FragilityModel
from .ground_motion import GMField
from .losslib import get_full_gm_field
VERSION_STRING = "losscalculator version 0.1"
......@@ -39,7 +39,7 @@ def damage_calculator(
fragility_source,
intensity_measure_map_filepath,
taxonomy_map_filepath,
gm_field_filepath,
gm_field: GMField,
interpolation_method="linear",
result_filepath="damage_result.csv",
output_format="gpkg",
......@@ -63,7 +63,6 @@ def damage_calculator(
damage_by_assets = []
# Read inputs.
gm_field = np.loadtxt(gm_field_filepath, delimiter=",", skiprows=1)
if exposure_format == "csv":
exposure = pd.read_csv(exposure_filepath)
else: # exposure_format == "spatialite"
......@@ -95,9 +94,10 @@ def damage_calculator(
sql_statement += "INNER JOIN Taxonomy ON BuildingAsset.taxonomy_id = Taxonomy.id "
sql_statement += "INNER JOIN District ON BuildingAsset.district_id = District.id"
exposure = pd.read_sql_query(sql_statement, conn)
fragility_model = FragilityModel(
fragility_source,
gm_field_filepath,
gm_field.im_types,
intensity_measure_map_filepath,
taxonomy_map_filepath,
use_xml_fragilities,
......@@ -106,7 +106,7 @@ def damage_calculator(
# Interpolate the ground-motion values for all the assets of the exposure model.
# pylint: disable=E1101
full_gm_field = get_full_gm_field(
gm_field, exposure.lon, exposure.lat, interpolation_method
gm_field.data, exposure.lon, exposure.lat, interpolation_method
)
# Going through each asset to do the damage calculation.
......@@ -367,13 +367,15 @@ def main():
startTime = datetime.datetime.now()
print(startTime)
gm_field = GMField.load_from_csv(gm_field_filepath)
damage_calculator(
exposure_filepath,
exposure_format,
fragility_source,
intensity_measure_map,
taxonomy_map_filepath,
gm_field_filepath,
gm_field,
interpolation_method,
result_filepath,
output_format,
......
#!/usr/bin/python3
# Copyright (c) 2021:
# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
import csv
import numpy as np
import xml.etree.ElementTree as ETree
import glob
from scipy.stats import lognorm
import xml.etree.ElementTree as ETree
from pathlib import Path
import numpy as np
from scipy.stats import lognorm
class FragilityModel:
"""
......@@ -15,7 +34,7 @@ class FragilityModel:
def __init__(
self,
fragility_source,
gmf_filepath,
im_types,
intensity_measure_map_filepath=None,
taxonomy_map_filepath=None,
use_xml_fragilities=True,
......@@ -61,16 +80,8 @@ class FragilityModel:
provided by the Global Earthquake Model or a file search pattern
for CSV files containing fragility functions (e.g.: 'csvfiles/*.csv')
gmf_filepath (str):
File path to the ground-motion field.
(Header line contains the intensity-measure names)
File example extract:
lon,lat,gmv_PGA,gmv_SA(0.3),gmv_SA(0.6),gmv_SA(1.0)
22.89028,36.31806,4.822530E-03,1.255729E-02,8.736364E-03,5.612176E-03
22.89028,36.32083,4.830462E-03,1.257595E-02,8.748890E-03,5.619673E-03
...
im_types (list(str)):
intensity-measure types used in the ground-motion field.
intensity_measure_map_filepath (str):
File path to a CSV file mapping the intensity types from the
......@@ -265,9 +276,6 @@ class FragilityModel:
next(reader)
self.taxonomy_map = {rows[0]: rows[1] for rows in reader}
# Extracting the ground-motion types available in the ground-motion field.
with open(gmf_filepath) as gmf:
im_types = gmf.readline().strip().split(",")[2:]
im_types_dict = {}
for index, value in enumerate(im_types):
im_types_dict[value] = index + 2
......
#!/usr/bin/python3
# Copyright (c) 2021:
# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
import logging
from dataclasses import dataclass
import numpy as np
logger = logging.getLogger(__name__)
@dataclass
class GMField:
"""Dataclass containing a ground motion field.
Attributes:
self.data: ground motion data as 2D numpy array
self.im_types: header information associated with ground-motion data
"""
data: np.array
im_types: list[str]
def save_to_csv(self, out_filepath: str) -> None:
"""Save ground motion field to csv file.
Args:
out_filepath: file path to store result
"""
header = ".".join(self.im_types)
np.savetxt(out_filepath, self.data, header=header)
logger.info(f"Stored ground motion field at {out_filepath}")
@classmethod
def load_from_csv(cls, in_filepath: str):
"""Loads a ground-motion field from a csv file
Args:
in_filepath: path to a csv file containing header information and
ground-motion field data
Returns:
GMField instance
"""
with open(in_filepath) as gmf:
im_types = gmf.readline().strip().split(",")[2:]
data = np.loadtxt(in_filepath, delimiter=",", skiprows=1)
return cls(data=data, im_types=im_types)
#!/usr/bin/python3
# Copyright (c) 2021:
# Helmholtz-Zentrum Potsdam Deutsches GeoForschungsZentrum GFZ
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
import os
import pytest as pytest
from losscalculator.ground_motion import GMField
import numpy as np
@pytest.fixture
def demo_ground_motion_field(pytestconfig):
input_file = pytestconfig.rootdir / "examples/example_cell/data/ground_motion_values.csv"
ground_motion_field = GMField.load_from_csv(input_file)
yield ground_motion_field
def test_ground_motion_properties(demo_ground_motion_field):
assert isinstance(demo_ground_motion_field.im_types, list)
assert len(demo_ground_motion_field.im_types) > 1
assert isinstance(demo_ground_motion_field.data, np.ndarray)
def test_csv_writer(demo_ground_motion_field, tmp_path):
out_filepath = tmp_path / "test-output.csv"
demo_ground_motion_field.save_to_csv(out_filepath=out_filepath)
assert os.path.exists(out_filepath)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment