Source code for safe.engine.impact_functions_for_testing.NEXIS_building_impact_model

import sys

from safe.impact_functions.core import FunctionProvider
from safe.impact_functions.core import get_hazard_layer, get_exposure_layer

from safe.impact_functions.utilities import Damage_curve
from safe.storage.vector import Vector
from safe.engine.interpolation import assign_hazard_values_to_exposure_data

# A maximum floating point number for this package
MAXFLOAT = float(sys.maxint)

#------------------------------------------------------------
# Define damage curves for tsunami structural building damage
#------------------------------------------------------------
struct_damage_curve = {'Double brick': Damage_curve([[-MAXFLOAT, 0.0],
                                                     [0.0, 0.016],
                                                     [0.1, 0.150],
                                                     [0.3, 0.425],
                                                     [0.5, 0.449],
                                                     [1.0, 0.572],
                                                     [1.5, 0.582],
                                                     [2.0, 0.587],
                                                     [2.5, 0.647],
                                                     [MAXFLOAT, 64.7]]),
                       'Brick veneer': Damage_curve([[-MAXFLOAT, 0.0],
                                                     [0.0, 0.016],
                                                     [0.1, 0.169],
                                                     [0.3, 0.445],
                                                     [0.5, 0.472],
                                                     [1.0, 0.618],
                                                     [1.5, 0.629],
                                                     [2.0, 0.633],
                                                     [2.5, 0.694],
                                                     [MAXFLOAT, 69.4]]),
                       'Timber': Damage_curve([[-MAXFLOAT, 0.0],
                                               [0.0, 0.016],
                                               [0.3, 0.645],
                                               [1.0, 0.818],
                                               [2.0, 0.955],
                                               [MAXFLOAT, 99.4]])}

contents_damage_curve = Damage_curve([[-MAXFLOAT, 0.0],
                                      [0.0, 0.013],
                                      [0.1, 0.102],
                                      [0.3, 0.381],
                                      [0.5, 0.500],
                                      [1.0, 0.970],
                                      [1.5, 0.976],
                                      [2.0, 0.986],
                                      [MAXFLOAT, 98.6]])


[docs]class TsunamiBuildingLossFunction(FunctionProvider): """Risk plugin for earthquake damage based on empirical results :param requires category=='hazard' and \ subcategory.startswith('tsunami') and \ layertype=='raster' :param requires category=='exposure' and \ subcategory=='structure' and \ layertype=='vector' and \ nothing=='never' """ @staticmethod def target_value(): field = 'STRUCT_DAMAGE_fraction' return field[0:9] @staticmethod
[docs] def run(layers): """Risk plugin for tsunami building damage """ # Extract data H = get_hazard_layer(layers) # Ground shaking E = get_exposure_layer(layers) # Building locations # Interpolate hazard level to building locations H = assign_hazard_values_to_exposure_data(H, E, attribute_name='depth') # Extract relevant numerical data coordinates = E.get_geometry() inundation = H.get_data() # Calculate N = len(H) impact = [] for i in range(N): #------------------- # Extract parameters #------------------- depth = float(inundation[i]['depth']) #shore_distance = E.get_data('SHORE_DIST', i) # FIXME: Get rid of the type casting when # issue #66 is done number_of_people_in_building = int(E.get_data('NEXIS_PEOP', i)) wall_type = E.get_data('WALL_TYPE', i) contents_value = E.get_data('CONT_VALUE', i) structure_value = E.get_data('STR_VALUE', i) #------------------------ # Compute people affected #------------------------ if 0.01 < depth < 1.0: people_affected = number_of_people_in_building else: people_affected = 0 if depth >= 1.0: people_severely_affected = number_of_people_in_building else: people_severely_affected = 0 #---------------------------------------- # Compute impact on buldings and contents #---------------------------------------- depth_floor = depth - 0.3 # Adjust for floor height if depth_floor >= 0.0: buildings_inundated = 1 else: buildings_inundated = 0 if depth_floor < 0.0: structural_damage = contents_damage = 0.0 else: # Water is deep enough to cause damage if wall_type in struct_damage_curve: curve = struct_damage_curve[wall_type] else: # Establish default for unknown wall type curve = struct_damage_curve['Brick veneer'] structural_damage = curve(depth_floor) contents_damage = contents_damage_curve(depth_floor) #--------------- # Compute losses #--------------- structural_loss = structural_damage * structure_value contents_loss = contents_damage * contents_value #------- # Return #------- impact.append({'NEXIS_PEOP': number_of_people_in_building, 'PEOPLE_AFFECTED': people_affected, 'PEOPLE_SEV_AFFECTED': people_severely_affected, 'STRUCT_INUNDATED': buildings_inundated, 'STRUCT_DAMAGE_fraction': structural_damage, 'CONTENTS_DAMAGE_fraction': contents_damage, 'STRUCT_LOSS_AUD': structural_loss, 'CONTENTS_LOSS_AUD': contents_loss, 'DEPTH': depth}) # FIXME (Ole): Need helper to generate new layer using # correct spatial reference # (i.e. sensibly wrap the following lines) V = Vector(data=impact, projection=E.get_projection(), geometry=coordinates, name='Estimated tsunami impact') return V