Source code for safe.impact_functions.impact_function_manager

# coding=utf-8
"""
InaSAFE Disaster risk assessment tool developed by AusAid -
**Impact Function Manager**

Contact : [email protected]

.. note:: This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
"""

__author__ = '[email protected]'
__revision__ = '$Format:%H$'
__date__ = '20/03/14'
__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
                 'Disaster Reduction')

from safe.common.utilities import add_to_list
from safe.impact_functions.registry import Registry


[docs]class ImpactFunctionManager(object): """Class for managing metadata for all impact function. .. versionadded:: 2.1 """ def __init__(self): """Constructor.""" # Singleton Registry to track all the registered Impact Functions self.registry = Registry() @property
[docs] def impact_functions(self): """Return all registered impact functions.""" return self.registry.impact_functions
[docs] def get_instance(self, class_name): """Return an instance of an impact function given its class name. .. example:: if_manager = ImpactFunctionManager() if_class_name = 'FloodBuildingImpactFunction' if = if_manager.get_instance(if_class_name) :param class_name: The name of IF class. :type class_name: str :return: Impact function instance that matches the argument. :rtype: safe.impact_functions.base.ImpactFunction """ return self.registry.get_instance(class_name)
[docs] def get_class(self, class_name): """Return the class of an impact function given its class name. .. example:: if_manager = ImpactFunctionManager() if_class_name = 'FloodBuildingImpactFunction' if_class = if_manager.get_class(if_class_name) :param class_name: the name of IF class :type class_name: str :return: impact function class that matches the argument. :rtype: safe.impact_functions.base.ImpactFunction """ return self.registry.get_class(class_name)
[docs] def get(self, impact_function_id): """Return an instance of an impact function given its ID. This is a preferred way to get an instance of IF. IF should have a unique human readable ID in their metadata. .. example:: if_manager = ImpactFunctionManager() if_id = 'FloodBuildingImpactFunction' if = if_manager.get(if_id) :param impact_function_id: The ID of impact function in the metadata. :type impact_function_id: str :return An Impact function instance that has matched id. :rtype: safe.impact_functions.base.ImpactFunction """ impact_functions = self.registry.filter_by_metadata( 'id', impact_function_id) if len(impact_functions) == 0: raise Exception( 'Impact function with ID: %s not found' % impact_function_id) elif len(impact_functions) > 1: raise Exception( 'There are some Impact Functions that have the same ID: %s' % impact_function_id) return impact_functions[0].instance()
[docs] def filter(self, hazard_metadata=None, exposure_metadata=None): """Get available impact functions from hazard and exposure metadata. Disabled impact function will not be loaded. .. example:: if_manager = ImpactFunctionManager() hazard_metadata = { 'subcategory': hazard_flood, 'units': unit_wetdry, 'layer_constraints': layer_vector_polygon } exposure_metadata = { 'subcategory': exposure_structure, 'units': unit_building_type_type, 'layer_constraints': layer_vector_polygon } ifs = if_manager.filter(hazard_metadata, exposure_metadata) :param hazard_metadata: The metadata of the hazard. :type hazard_metadata: dict :param exposure_metadata: The metadata of the exposure. :type exposure_metadata: dict """ return self.registry.filter(hazard_metadata, exposure_metadata)
[docs] def filter_by_keywords( self, hazard_keywords=None, exposure_keywords=None): """Get available impact functions from hazard and exposure keywords. Disabled impact function will not be loaded. .. example:: if_manager = ImpactFunctionManager() hazard_keywords = { 'subcategory': 'flood', 'units': 'wetdry', 'layer_type': 'vector', 'data_type': 'polygon' } exposure_keywords = { 'subcategory': 'structure', 'units': 'building_type', 'layer_type': 'vector', 'data_type': 'polygon' } ifs = if_manager.filter_by_keywords(hazard_keywords, exposure_keywords) :param hazard_keywords: The keywords of the hazard. :type hazard_keywords: dict :param exposure_keywords: The keywords of the exposure. :type exposure_keywords: dict """ return self.registry.filter_by_keyword_string( hazard_keywords, exposure_keywords)
[docs] def filter_by_metadata(self, metadata_key, metadata_value): """Return IF classes given its metadata key and value. .. example:: if_manager = ImpactFunctionManager() metadata_key = 'author' metadata_value = 'Akbar Gumbira' ifs = if_manager.filter_by_metadata(metadata_key, metadata_value) :param metadata_key: The key of the metadata e.g 'id', 'name' :type metadata_key: str :param metadata_value: The value of the metadata, e.g for the key 'id' the value is 'FloodNativePolygonExperimentalFunction' :type metadata_value: str, dict :return: Impact Function classes match the arguments :rtype: list """ return self.registry.filter_by_metadata(metadata_key, metadata_value)
@staticmethod
[docs] def get_function_id(impact_function): """Get the ID of the impact function. :param impact_function: Class of an impact function :type impact_function: safe.impact_functions.base.ImpactFunction :returns: The ID of the impact function specified in its metadata. :rtype: str """ return impact_function.metadata().as_dict().get('id', None)
@staticmethod
[docs] def get_function_title(impact_function): """Get title of the impact function. :param impact_function: Class of an impact function :type impact_function: safe.impact_functions.base.ImpactFunction :returns: The title of the impact function specified in its metadata. :rtype: str """ return impact_function.metadata().as_dict().get('title', None)
@staticmethod
[docs] def get_function_name(impact_function): """Get the human readable name of the impact function. :param impact_function: Class of an impact function. :type impact_function: safe.impact_functions.base.ImpactFunction """ return impact_function.metadata().as_dict().get('name', None)
@staticmethod
[docs] def get_function_type(impact_function): """Return the impact function type. :param impact_function: The impact function. :type impact_function: safe.impact_functions.base.ImpactFunction """ return impact_function.function_type()
[docs] def get_functions_for_hazard(self, hazard): """Return all function metadata that has hazard in their metadata. .. versionadded:: 2.2 :param hazard: Dictionary that represent the hazard :type hazard: dict :return: List of impact function metadata. :rtype: list """ impact_functions_metadata = [] for impact_function in self.impact_functions: if impact_function.metadata().has_hazard(hazard): impact_functions_metadata.append( impact_function.metadata().as_dict()) return impact_functions_metadata
[docs] def purposes_for_layer(self, layer_geometry_key): """Get purposes of a layer geometry id. :param layer_geometry_key: The geometry id :type layer_geometry_key: str """ layer_purposes = [] for impact_function in self.impact_functions: if_layer_purposes = impact_function.metadata().purposes_for_layer( layer_geometry_key) if if_layer_purposes: add_to_list(layer_purposes, if_layer_purposes) return layer_purposes
[docs] def hazard_categories_for_layer(self, layer_geometry_key, hazard_key=None): """Get hazard categories form layer_geometry_key :param layer_geometry_key: The geometry id :type layer_geometry_key: str :param hazard_key: The hazard key :type hazard_key: str :returns: List of hazard_categories :rtype: list """ hazard_categories = [] for impact_function in self.impact_functions: if_hazard_categories = impact_function.metadata()\ .hazard_categories_for_layer(layer_geometry_key, hazard_key) if if_hazard_categories: add_to_list(hazard_categories, if_hazard_categories) return hazard_categories
[docs] def hazards_for_layer(self, layer_geometry_key, hazard_category_key=None): """Get hazard categories form layer_geometry_key :param layer_geometry_key: The geometry id :type layer_geometry_key: str :param hazard_category_key: The hazard category :type hazard_category_key: str :returns: List of hazard :rtype: list """ hazards = [] for impact_function in self.impact_functions: if_hazards = impact_function.metadata().hazards_for_layer( layer_geometry_key, hazard_category_key) if if_hazards: add_to_list(hazards, if_hazards) return hazards
[docs] def exposures_for_layer(self, layer_geometry_key): """Get hazard categories form layer_geometry_key :param layer_geometry_key: The geometry id :type layer_geometry_key: str :returns: List of hazard :rtype: list """ exposures = [] for impact_function in self.impact_functions: if_exposures = impact_function.metadata().exposures_for_layer( layer_geometry_key) if if_exposures: add_to_list(exposures, if_exposures) return exposures
[docs] def exposure_units_for_layer( self, exposure_key, layer_geometry_key, layer_mode_key): """Get hazard categories form layer_geometry_key :param exposure_key: The exposure key :type exposure_key: str :param layer_geometry_key: The geometry key :type layer_geometry_key: str :param layer_mode_key: The layer mode key :type layer_mode_key: str :returns: List of exposure unit :rtype: list """ exposure_units = [] for impact_function in self.impact_functions: if_exposure_units = impact_function.metadata().\ exposure_units_for_layer( exposure_key, layer_geometry_key, layer_mode_key) if if_exposure_units: add_to_list(exposure_units, if_exposure_units) return exposure_units
[docs] def continuous_hazards_units_for_layer( self, hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key): """Get continuous hazard units. :param hazard_key: The hazard key :type hazard_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param layer_mode_key: The layer mode key :type layer_mode_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :returns: List of continuous hazard unit :rtype: list """ continuous_hazards_units = [] for impact_function in self.impact_functions: if_continuous_hazard_units = impact_function.metadata().\ continuous_hazards_units_for_layer( hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key) if if_continuous_hazard_units: add_to_list( continuous_hazards_units, if_continuous_hazard_units) return continuous_hazards_units
[docs] def vector_hazards_classifications_for_layer( self, hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key): """Get continuous hazard units. :param hazard_key: The hazard key :type hazard_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param layer_mode_key: The layer mode key :type layer_mode_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :returns: List of vector_hazards_classifications :rtype: list """ vector_hazards_classifications = [] for impact_function in self.impact_functions: if_vector_hazards_classifications = impact_function.metadata().\ vector_hazards_classifications_for_layer( hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key) if if_vector_hazards_classifications: add_to_list( vector_hazards_classifications, if_vector_hazards_classifications) return vector_hazards_classifications
[docs] def raster_hazards_classifications_for_layer( self, hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key): """Get continuous hazard units. :param hazard_key: The hazard key :type hazard_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param layer_mode_key: The layer mode key :type layer_mode_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :returns: List of raster_hazards_classifications :rtype: list """ raster_hazards_classifications = [] for impact_function in self.impact_functions: if_vector_hazards_classifications = impact_function.metadata().\ raster_hazards_classifications_for_layer( hazard_key, layer_geometry_key, layer_mode_key, hazard_category_key) if if_vector_hazards_classifications: add_to_list( raster_hazards_classifications, if_vector_hazards_classifications) return raster_hazards_classifications
[docs] def available_hazards(self, hazard_category_key, ascending=True): """available_hazards from hazard_category_key :param hazard_category_key: The hazard category key :type hazard_category_key: str :param ascending: Sort ascending or not. :type ascending: bool :returns: List of available hazards :rtype: list """ hazards = [] for impact_function in self.impact_functions: if_hazards = impact_function.metadata(). \ available_hazards(hazard_category_key) if if_hazards: add_to_list(hazards, if_hazards) # make it sorted if ascending and hazards: hazards = sorted(hazards, key=lambda k: k['key']) return hazards
[docs] def available_exposures(self, ascending=True): """Return a list of valid available exposures :param ascending: Sort ascending or not. :type ascending: bool :returns: A list of exposures full metadata. :rtype: list """ exposures = [] for impact_function in self.impact_functions: if_exposures = impact_function.metadata().available_exposures() if if_exposures: add_to_list(exposures, if_exposures) # make it sorted if ascending and exposures: exposures = sorted(exposures, key=lambda k: k['key']) return exposures
[docs] def functions_for_constraint( self, hazard_key, exposure_key, hazard_geometry_key=None, exposure_geometry_key=None, hazard_mode_key=None, exposure_mode_key=None): """Obtain all functions that match with the constraints :param hazard_key: The hazard key :type hazard_key: str :param exposure_key: the exposure key :type exposure_key: str :param hazard_geometry_key: The hazard geometry key :type hazard_geometry_key: str :param exposure_geometry_key: The exposure geometry key :type exposure_geometry_key: str :param hazard_mode_key: The hazard mode key :type hazard_mode_key: str :param exposure_mode_key: The exposure mode key :type exposure_mode_key: str :returns: List of matched Impact Function :rtype: list """ impact_functions = [] for impact_function in self.impact_functions: if impact_function.metadata().is_function_for_constraint( hazard_key, exposure_key, hazard_geometry_key, exposure_geometry_key, hazard_mode_key, exposure_mode_key): impact_functions.append(impact_function.metadata().as_dict()) return impact_functions
[docs] def available_hazard_constraints( self, hazard_key, hazard_category_key): """Get hazard constraints for hazard_key and hazard_category_key :param hazard_key: The hazard key :type hazard_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :returns: List of tuple of layer_mode and layer_geometry :rtype: list """ hazard_constraints = [] for impact_function in self.impact_functions: if_hazard_constraints = impact_function.metadata().\ available_hazard_constraints( hazard_key, hazard_category_key) if if_hazard_constraints: add_to_list(hazard_constraints, if_hazard_constraints) return hazard_constraints
[docs] def available_exposure_constraints(self, exposure_key): """Get exposure constraints for exposure_key. :param exposure_key: The exposure key :type exposure_key: str :returns: List of tuple of layer_mode and layer_geometry :rtype: list """ exposure_constraints = [] for impact_function in self.impact_functions: if_exposure_constraints = impact_function.metadata(). \ available_exposure_constraints(exposure_key) if if_exposure_constraints: add_to_list(exposure_constraints, if_exposure_constraints) return exposure_constraints
[docs] def available_hazard_layer_modes( self, hazard_key, hazard_geometry_key, hazard_category_key): """Return all available layer_mode. :param hazard_key: The hazard key :type hazard_key: str :param hazard_geometry_key: The hazard geometry key :type hazard_geometry_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :returns: List of layer_mode :rtype: list """ layer_modes = [] for impact_function in self.impact_functions: if_hazard_layer_mode = impact_function.metadata().\ available_hazard_layer_mode( hazard_key, hazard_geometry_key, hazard_category_key) if if_hazard_layer_mode: add_to_list(layer_modes, if_hazard_layer_mode) return layer_modes
[docs] def available_exposure_layer_modes( self, exposure_key, exposure_geometry_key): """Get exposure layer mode for exposure_key. :param exposure_key: The exposure key :type exposure_key: str :param exposure_geometry_key: The exposure geometry key :type exposure_geometry_key: str :returns: List of layer_mode :rtype: list """ layer_modes = [] for impact_function in self.impact_functions: if_exposure_layer_mode = impact_function.metadata().\ available_exposure_layer_mode( exposure_key, exposure_geometry_key) if if_exposure_layer_mode: add_to_list(layer_modes, if_exposure_layer_mode) return layer_modes
[docs] def hazard_additional_keywords( self, layer_mode_key=None, layer_geometry_key=None, hazard_category_key=None, hazard_key=None): """Return additional_keywords for hazard. :param layer_mode_key: The layer mode key :type layer_mode_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param hazard_category_key: The hazard category key :type hazard_category_key: str :param hazard_key: The hazard key :type hazard_key: str :returns: List of additional keywords :rtype: list """ additional_keywords = [] for impact_function in self.impact_functions: if_additional_keywords = impact_function.metadata().\ hazard_additional_keywords( layer_mode_key=layer_mode_key, layer_geometry_key=layer_geometry_key, hazard_category_key=hazard_category_key, hazard_key=hazard_key) if if_additional_keywords: add_to_list(additional_keywords, if_additional_keywords) return additional_keywords
[docs] def exposure_additional_keywords( self, layer_mode_key=None, layer_geometry_key=None, exposure_key=None): """Return additional_keywords for exposure. :param layer_mode_key: The layer mode key :type layer_mode_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param exposure_key: The hazard key :type exposure_key: str :returns: List of additional keywords :rtype: list """ additional_keywords = [] for impact_function in self.impact_functions: if_additional_keywords = impact_function.metadata().\ exposure_additional_keywords( layer_mode_key=layer_mode_key, layer_geometry_key=layer_geometry_key, exposure_key=exposure_key) if if_additional_keywords: add_to_list(additional_keywords, if_additional_keywords) return additional_keywords
[docs] def exposure_class_fields( self, layer_mode_key=None, layer_geometry_key=None, exposure_key=None): """Return list of exposure class field. :param layer_mode_key: The layer mode key :type layer_mode_key: str :param layer_geometry_key: The layer geometry key :type layer_geometry_key: str :param exposure_key: The exposure key :type exposure_key: str :returns: List of exposure class field. :rtype: list """ result = [] for impact_function in self.impact_functions: if_exposure_class_field = impact_function.metadata(). \ exposure_class_fields( layer_mode_key=layer_mode_key, layer_geometry_key=layer_geometry_key, exposure_key=exposure_key) if if_exposure_class_field: add_to_list(result, if_exposure_class_field) return result