diff --git a/climada_petals/entity/impact_funcs/river_flood.py b/climada_petals/entity/impact_funcs/river_flood.py index f38963ec3..e5082cb7c 100644 --- a/climada_petals/entity/impact_funcs/river_flood.py +++ b/climada_petals/entity/impact_funcs/river_flood.py @@ -29,21 +29,27 @@ from climada.util.constants import RIVER_FLOOD_REGIONS_CSV from climada.entity import ImpactFunc, ImpactFuncSet -LOGGER = logging.getLogger(__name__) -DEF_VAR_EXCEL = {'sheet_name': 'damagefunctions', - 'col_name': {'func_id': 'DamageFunID', - 'inten': 'Intensity', - 'mdd': 'MDD', - 'paa': 'PAA', - 'mdr': 'MDR', - 'name': 'name', - 'peril': 'peril_ID', - 'unit': 'Intensity_unit' - } - } +SECTOR_CO_ID = { + "Residential": 1, + "Commercial": 2, + "Industrial": 3, + "Transport": 4, + "Infrastructure": 5, + "Agriculture": 6, +} +REGION_CO_ID = { + "africa": 10, + "asia": 20, + "europe": 30, + "northamerica": 40, + "oceania": 50, + "southamerica": 60, +} +VALID_REGIONS = "Africa, Asia, Europe, North America, Oceania, South America" +LOGGER = logging.getLogger(__name__) class ImpfRiverFlood(ImpactFunc): """Impact functions for tropical cyclones.""" @@ -55,144 +61,329 @@ def __init__(self): self.continent = '' @classmethod - def from_region(cls, region): - """Create a new ImpfRiverFlood object with parameters for the specified world region. + def from_jrc_region_sector(cls, region, sector="residential"): + """Create a new ImpfRiverFlood object based on the specified world region and sector. + Impact functions come from the following JRC publication: + + Huizinga, J., De Moel, H. and Szewczyk, W., Global flood depth-damage functions: Methodology + and the database with guidelines, EUR 28552 EN, Publications Office of the European Union, + Luxembourg, 2017, ISBN 978-92-79-67781-6, doi:10.2760/16510, JRC105688. + + Notes + ----- + The impact functions assess percentage losses at 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6 meters of + water. For North America, percentage losses higher than 0 are already registerd at 0 meters + of water, because it accounts for the presence of basements (see main publication). Since + this could be problematic when computing impacts, as one would have losses also when there + is no flood, a 0.05 meters of water point is added to all functions (not only North America, + for consistency), and this corresponds to the 0 meters point in the JRC functions. Parameters ---------- region : str - Use damage function parameters for this world region. Supported values: "Africa", - "Asia", "Europe", "NorthAmerica", "Oceania", "SouthAmerica". + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + sector: str + sector for which the impact function was defined. Supported values: "residential", + "commercial", "industrial", "transport", "infrastructure", "agriculture". Returns ------- impf : ImpfRiverFlood - New ImpfRiverFlood object with parameters for the specified world region. + New ImpfRiverFlood object with parameters for the specified world region and sector. Raises ------ ValueError """ - impf = cls() - if region.lower() == "africa": - impf.id = 1 - impf.name = "Flood Africa JRC Residential noPAA" - impf.continent = 'Africa' - impf.intensity = np.array([0., 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) - impf.mdd = np.array([0.0000, 0.2199, 0.3782, 0.5306, 0.6356, 0.8169, - 0.9034, 0.9572, 1.0000, 1.0000]) - impf.mdr = np.array([0.0000, 0.2199, 0.3782, 0.5306, 0.6356, 0.8169, - 0.9034, 0.9572, 1.0000, 1.0000]) - elif region.lower() == "asia": - impf.id = 2 - impf.name = "Flood Asia JRC Residential noPAA" - impf.continent = 'Asia' - impf.intensity = np.array([0., 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) - impf.mdd = np.array([0.000, 0.3266, 0.4941, 0.6166, 0.7207, 0.8695, - 0.9315, 0.9836, 1.0000, 1.0000]) - impf.mdr = np.array([0.000, 0.3266, 0.4941, 0.6166, 0.7207, 0.8695, - 0.9315, 0.9836, 1.0000, 1.0000]) - elif region.lower() == "europe": - impf.id = 3 - impf.name = "Flood Europe JRC Residential noPAA" - impf.continent = 'Europe' - impf.intensity = np.array([0., 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) - impf.mdd = np.array([0.00, 0.25, 0.40, 0.50, 0.60, 0.75, 0.85, 0.95, - 1.00, 1.00]) - impf.mdr = np.array([0.000, 0.250, 0.400, 0.500, 0.600, 0.750, 0.850, - 0.950, 1.000, 1.000]) - elif region.lower().replace(" ", "") == "northamerica": - impf.id = 4 - impf.name = "Flood North America JRC Residential noPAA" - impf.continent = 'NorthAmerica' - impf.intensity = np.array([0., 0.1, 0.5, 1., 1.5, 2., 3., 4., 5., - 6., 12.]) - impf.mdd = np.array([0.0000, 0.2018, 0.4433, 0.5828, 0.6825, 0.7840, - 0.8543, 0.9237, 0.9585, 1.0000, 1.0000]) - impf.mdr = np.array([0.0000, 0.2018, 0.4433, 0.5828, 0.6825, 0.7840, - 0.8543, 0.9237, 0.9585, 1.0000, 1.0000]) - elif region.lower() == "oceania": - impf.id = 5 - impf.name = "Flood Oceania JRC Residential noPAA" - impf.continent = 'Oceania' - impf.intensity = np.array([0., 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) - impf.mdd = np.array([0.00, 0.48, 0.64, 0.71, 0.79, 0.93, 0.97, 0.98, - 1.00, 1.00]) - impf.mdr = np.array([0.000, 0.480, 0.640, 0.710, 0.790, 0.930, 0.970, - 0.980, 1.000, 1.000]) - elif region.lower().replace(" ", "") == "southamerica": - impf.id = 6 - impf.name = "Flood South America JRC Residential noPAA" - impf.continent = 'SouthAmerica' - impf.intensity = np.array([0., 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) - impf.mdd = np.array([0.0000, 0.4908, 0.7112, 0.8420, 0.9494, - 0.9836, 1.0000, 1.0000, 1.0000, 1.0000]) - impf.mdr = np.array([0.0000, 0.4908, 0.7112, 0.8420, 0.9494, 0.9836, - 1.0000, 1.0000, 1.0000, 1.0000]) + + if sector == 'residential': + impf_values, impf_id = from_jrc_impf_residential(region) + + elif sector == 'industrial': + impf_values, impf_id = from_jrc_impf_industrial(region) + + elif sector == 'commercial': + impf_values, impf_id = from_jrc_impf_commercial(region) + + elif sector == 'transport': + impf_values, impf_id = from_jrc_impf_transport(region) + + elif sector == 'infrastructure': + impf_values, impf_id = from_jrc_impf_infrastructure(region) + + elif sector == 'agriculture': + impf_values, impf_id = from_jrc_impf_agriculture(region) + else: - raise ValueError(f"Unrecognized world region: {region}") + raise ValueError(f"Unrecognized sector: {sector}") + + impf = cls() + impf.name = f"Flood {region} JRC {sector.capitalize()} noPAA" + impf.continent = f"{region}" + impf.id = impf_id + impf.mdd = impf_values + impf.intensity = np.array([0., 0.05, 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) impf.paa = np.ones(len(impf.intensity)) + return impf def set_RF_Impf_Africa(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_Africa is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("Africa", *args, **kwargs).__dict__ + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("Africa", *args, **kwargs).__dict__ def set_RF_Impf_Asia(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_Asia is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("Asia", *args, **kwargs).__dict__ + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("Asia", *args, **kwargs).__dict__ def set_RF_Impf_Europe(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_Europe is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("Europe", *args, **kwargs).__dict__ + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("Europe", *args, **kwargs).__dict__ def set_RF_Impf_NorthAmerica(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_NorthAmerica is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("NorthAmerica", *args, **kwargs).__dict__ + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("NorthAmerica", *args, **kwargs).__dict__ def set_RF_Impf_Oceania(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_Oceania is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("Oceania", *args, **kwargs).__dict__ + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("Oceania", *args, **kwargs).__dict__ def set_RF_Impf_SouthAmerica(self, *args, **kwargs): - """This function is deprecated, use ImpfRiverFlood.from_region instead.""" + """This function is deprecated, use ImpfRiverFlood.from_region_sector instead.""" LOGGER.warning("The use of ImpfRiverFlood.set_RF_Impf_SouthAmerica is deprecated." - "Use ImpfRiverFlood.from_region instead.") - self.__dict__ = ImpfRiverFlood.from_region("SouthAmerica", *args, **kwargs).__dict__ - - -def flood_imp_func_set(): - """Builds impact function set for river flood, using standard files""" - - impf_set = ImpactFuncSet() - - impf_africa = ImpfRiverFlood.from_region("Africa") - impf_set.append(impf_africa) - - impf_asia = ImpfRiverFlood.from_region("Asia") - impf_set.append(impf_asia) - - impf_europe = ImpfRiverFlood.from_region("Europe") - impf_set.append(impf_europe) - - impf_na = ImpfRiverFlood.from_region("NorthAmerica") - impf_set.append(impf_na) - - impf_oceania = ImpfRiverFlood.from_region("Oceania") - impf_set.append(impf_oceania) - - impf_sa = ImpfRiverFlood.from_region("SouthAmerica") - impf_set.append(impf_sa) + "Use ImpfRiverFlood.from_region_sector instead.") + self.__dict__ = ImpfRiverFlood.from_jrc_region_sector("SouthAmerica", *args, **kwargs).__dict__ + + + +def _from_jrc_impf(region, sector, impf_values_map): + """Boiler plate function for the public from_jrc_impf_*** functions""" + regkey = region.replace(' ', '').lower() + if regkey not in REGION_CO_ID: + raise ValueError(f"Unrecognized world region: {region}, must be one of {VALID_REGIONS}") + impf_id = REGION_CO_ID[regkey] + SECTOR_CO_ID[sector] + + impf_values = impf_values_map.get(regkey) + if impf_values is None: + raise ValueError(f"No impact function implemented for the {sector} sector in {region}") + return np.array(impf_values), impf_id + + + +def from_jrc_impf_residential(region): + """Create a new ImpfRiverFlood object for the residential sector of the a given + world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + return _from_jrc_impf( + region=region, + sector="Residential", + impf_values_map={ + "africa": [0., 0., 0.22, 0.378, 0.531, 0.636, 0.817, 0.903, 0.957, 1., 1.], + "asia": [0., 0., 0.327, 0.494, 0.617, 0.721, 0.87, 0.931, 0.984, 1., 1.], + "europe": [0., 0., 0.25, 0.4, 0.5, 0.6, 0.75, 0.85, 0.95, 1., 1.], + "northamerica": [0., 0.202, 0.443, 0.583, 0.683, 0.784, 0.854, 0.924, 0.959, 1., 1.], + "oceania": [0., 0., 0.475, 0.640, 0.715, 0.788, 0.929, 0.967, 0.983, 1., 1.], + "southamerica": [0., 0., 0.491, 0.711, 0.842, 0.949, 0.984, 1., 1., 1., 1.], + } + ) + + +def from_jrc_impf_commercial(region): + """Create a new ImpfRiverFlood object for the commercial sector of the a given world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + + return _from_jrc_impf( + region=region, + sector="Commercial", + impf_values_map={ + "asia": [0., 0., 0.377, 0.538, 0.659, 0.763, 0.883, 0.942, 0.981, 1., 1.], + "europe": [0., 0., 0.15, 0.3, 0.45, 0.55, 0.75, 0.9, 1., 1., 1.], + "northamerica": [0., 0.018, 0.239, 0.374, 0.466, 0.552, 0.687, 0.822, 0.908, 1., 1.], + "oceania": [0., 0., 0.239, 0.481, 0.674, 0.865, 1., 1., 1., 1., 1.], + "southamerica": [0., 0., 0.611, 0.84 , 0.924, 0.992, 1., 1., 1., 1., 1.], + } + ) + + +def from_jrc_impf_industrial(region): + """Create a new ImpfRiverFlood object for the industrial sector of the a given world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + + return _from_jrc_impf( + region=region, + sector="Industrial", + impf_values_map={ + "africa": [0., 0., 0.063, 0.247, 0.403, 0.494, 0.685, 0.919, 1., 1., 1.], + "asia": [0., 0., 0.283, 0.482, 0.629, 0.717, 0.857, 0.909, 0.955, 1., 1.], + "europe": [0., 0., 0.15, 0.27, 0.4, 0.52, 0.7, 0.85, 1., 1., 1.], + "northamerica": [0., 0.026, 0.323, 0.511, 0.637, 0.74, 0.86, 0.937, 0.98, 1., 1.], + "southamerica": [0., 0., 0.667, 0.889, 0.947, 1., 1., 1., 1., 1., 1.], + } + ) + + +def from_jrc_impf_transport(region): + """Create a new ImpfRiverFlood object for the transport sector of the a given world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + return _from_jrc_impf( + region=region, + sector="Transport", + impf_values_map={ + "asia": [0., 0., 0.358, 0.572, 0.733, 0.847, 1., 1., 1., 1., 1.], + "europe": [0., 0., 0.317, 0.542, 0.702, 0.832, 1., 1., 1., 1., 1.], + "southamerica": [0., 0., 0.088, 0.175, 0.596, 0.842, 1., 1., 1., 1., 1.], + } + ) + + +def from_jrc_impf_infrastructure(region): + """Create a new ImpfRiverFlood object for the infrastructure sector of the a given world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + return _from_jrc_impf( + region=region, + sector="Infrastructure", + impf_values_map={ + "asia": [0., 0., 0.214, 0.373, 0.604, 0.71, 0.808, 0.887, 0.969, 1., 1.], + "europe": [0., 0., 0.25, 0.42, 0.55, 0.65, 0.8, 0.9, 1., 1., 1.], + } + ) + + +def from_jrc_impf_agriculture(region): + """Create a new ImpfRiverFlood object for the agriculture sector of the a given world region. + + Parameters + ---------- + region : str + world region for which the impact function was defined. Supported values: + "Africa", "Asia", "Europe", "North America", "Oceania", "South America". + + Returns + ------- + impf : ImpfRiverFlood + New ImpfRiverFlood object with parameters for the specified sector. + + Raises + ------ + ValueError + """ + return _from_jrc_impf( + region=region, + sector="Agriculture", + impf_values_map={ + "africa": [0., 0., 0.243, 0.472, 0.741, 0.917, 1., 1., 1., 1., 1.], + "asia": [0., 0., 0.135, 0.37 , 0.524, 0.558, 0.66, 0.834, 0.988, 1., 1.], + "europe": [0., 0., 0.3, 0.55, 0.65, 0.75, 0.85, 0.95, 1., 1., 1.], + "northamerica": [0., 0.019, 0.268, 0.474, 0.551, 0.602, 0.76, 0.874, 0.954, 1., 1.], + } + ) + + +def flood_imp_func_set(sector="residential"): + """Builds impact function set for river flood, using standard files. By default, it reads + functions for the residential sector""" + + impf_africa = ImpfRiverFlood.from_jrc_region_sector("Africa", sector=sector) + impf_asia = ImpfRiverFlood.from_jrc_region_sector("Asia", sector=sector) + impf_europe = ImpfRiverFlood.from_jrc_region_sector("Europe", sector=sector) + impf_na = ImpfRiverFlood.from_jrc_region_sector("NorthAmerica", sector=sector) + impf_oceania = ImpfRiverFlood.from_jrc_region_sector("Oceania", sector=sector) + impf_sa = ImpfRiverFlood.from_jrc_region_sector("SouthAmerica", sector=sector) + + impf_set = ImpactFuncSet([ + impf_africa, + impf_asia, + impf_europe, + impf_na, + impf_oceania, + impf_sa + ]) return impf_set diff --git a/climada_petals/entity/impact_funcs/test/test_fl.py b/climada_petals/entity/impact_funcs/test/test_fl.py index 5ec9930c0..d7950128d 100644 --- a/climada_petals/entity/impact_funcs/test/test_fl.py +++ b/climada_petals/entity/impact_funcs/test/test_fl.py @@ -21,9 +21,51 @@ import unittest import numpy as np - +from itertools import product from climada_petals.entity.impact_funcs import river_flood as fl +IMPF_REGIONS = {1: 'Africa', 2: 'Asia', 3: 'Europe', 4: 'North America', 5: 'Oceania', 6: 'South America'} +IMPF_SECTORS = {1: 'residential', 2: 'commercial', 3: 'industrial', 4: 'transport', 5: 'infrastructure', + 6: 'agriculture'} + +IMPF_MDD = { + 11: np.array([0., 0., 0.22, 0.378, 0.531, 0.636, 0.817, 0.903, 0.957, 1., 1.]), + 21: np.array([0., 0., 0.327, 0.494, 0.617, 0.721, 0.87, 0.931, 0.984, 1., 1.]), + 31: np.array([0., 0., 0.25, 0.4, 0.5, 0.6, 0.75, 0.85, 0.95, 1., 1.]), + 41: np.array([0., 0.202, 0.443, 0.583, 0.683, 0.784, 0.854, 0.924, 0.959, 1., 1.]), + 51: np.array([0., 0., 0.475, 0.640, 0.715, 0.788, 0.929, 0.967, 0.983, 1., 1.]), + 61: np.array([0., 0., 0.491, 0.711, 0.842, 0.949, 0.984, 1., 1., 1., 1.]), + 12: np.array([]), + 22: np.array([0., 0., 0.377, 0.538, 0.659, 0.763, 0.883, 0.942, 0.981, 1., 1.]), + 32: np.array([0., 0., 0.15, 0.3, 0.45, 0.55, 0.75, 0.9, 1., 1., 1.]), + 42: np.array([0., 0.018, 0.239, 0.374, 0.466, 0.552, 0.687, 0.822, 0.908, 1., 1.]), + 52: np.array([0., 0., 0.239, 0.481, 0.674, 0.865, 1., 1., 1., 1., 1.]), + 62: np.array([0., 0., 0.611, 0.84 , 0.924, 0.992, 1., 1., 1., 1., 1.]), + 13: np.array([0., 0., 0.063, 0.247, 0.403, 0.494, 0.685, 0.919, 1., 1., 1.]), + 23: np.array([0., 0., 0.283, 0.482, 0.629, 0.717, 0.857, 0.909, 0.955, 1., 1.]), + 33: np.array([0., 0., 0.15, 0.27, 0.4, 0.52, 0.7, 0.85, 1., 1., 1.]), + 43: np.array([0., 0.026, 0.323, 0.511, 0.637, 0.74, 0.86, 0.937, 0.98, 1., 1.]), + 53: np.array([]), + 63: np.array([0., 0., 0.667, 0.889, 0.947, 1., 1., 1., 1., 1., 1.]), + 14: np.array([]), + 24: np.array([0., 0., 0.358, 0.572, 0.733, 0.847, 1., 1., 1., 1., 1.]), + 34: np.array([0., 0., 0.317, 0.542, 0.702, 0.832, 1., 1., 1., 1., 1.]), + 44: np.array([]), + 54: np.array([]), + 64: np.array([0., 0., 0.088, 0.175, 0.596, 0.842, 1., 1., 1., 1., 1.]), + 15: np.array([]), + 25: np.array([0., 0., 0.214, 0.373, 0.604, 0.71 , 0.808, 0.887, 0.969, 1., 1.]), + 35: np.array([0., 0., 0.25, 0.42, 0.55, 0.65, 0.8, 0.9, 1., 1., 1.]), + 45: np.array([]), + 55: np.array([]), + 65: np.array([]), + 16: np.array([0., 0., 0.243, 0.472, 0.741, 0.917, 1., 1., 1., 1., 1.]), + 26: np.array([0., 0., 0.135, 0.37 , 0.524, 0.558, 0.66, 0.834, 0.988, 1., 1.]), + 36: np.array([0., 0., 0.3, 0.55, 0.65, 0.75, 0.85, 0.95, 1., 1., 1.]), + 46: np.array([0., 0.019, 0.268, 0.474, 0.551, 0.602, 0.76, 0.874, 0.954, 1., 1.]), + 56: np.array([]), + 66: np.array([]) +} class TestIFRiverFlood(unittest.TestCase): """Impact function test""" @@ -33,118 +75,44 @@ def test_flood_imp_func_set(self): np.array(['RF']))) self.assertEqual(test_set.size(), 6) - def test_region_Africa(self): - - impf_1 = fl.ImpfRiverFlood.from_region("Africa") - - self.assertEqual(impf_1.continent, 'Africa') - self.assertEqual(impf_1.name, 'Flood Africa JRC Residential noPAA') - self.assertEqual(impf_1.haz_type, 'RF') - self.assertEqual(impf_1.id, 1) - self.assertEqual(impf_1.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_1.intensity, - np.array([0., 0.5, 1., 1.5, - 2., 3., 4., 5., 6., 12.]))) - self.assertTrue(np.allclose(impf_1.mdd, - np.array([0., 0.2199, 0.3782, - 0.5306, 0.6356, 0.8169, - 0.9034, 0.9572, 1., 1.]))) - self.assertTrue(np.allclose(impf_1.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - - def test_region_Asia(self): - - impf_2 = fl.ImpfRiverFlood.from_region("Asia") - - self.assertEqual(impf_2.continent, 'Asia') - self.assertEqual(impf_2.name, 'Flood Asia JRC Residential noPAA') - self.assertEqual(impf_2.haz_type, 'RF') - self.assertEqual(impf_2.id, 2) - self.assertEqual(impf_2.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_2.intensity, - np.array([0., 0.5, 1., 1.5, - 2., 3., 4., 5., 6., 12.]))) - self.assertTrue(np.allclose(impf_2.mdd, - np.array([0.000, 0.3266, 0.4941, 0.6166, 0.7207, - 0.8695, 0.9315, 0.9836, 1.0000, 1.0000]))) - self.assertTrue(np.allclose(impf_2.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - - def test_region_Europe(self): - - impf_3 = fl.ImpfRiverFlood.from_region("Europe") - - self.assertEqual(impf_3.continent, 'Europe') - self.assertEqual(impf_3.name, 'Flood Europe JRC Residential noPAA') - self.assertEqual(impf_3.haz_type, 'RF') - self.assertEqual(impf_3.id, 3) - self.assertEqual(impf_3.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_3.intensity, - np.array([0., 0.5, 1., 1.5, - 2., 3., 4., 5., 6., 12.]))) - self.assertTrue(np.allclose(impf_3.mdd, - np.array([0.00, 0.25, 0.40, 0.50, 0.60, 0.75, 0.85, - 0.95, 1.00, 1.00]))) - self.assertTrue(np.allclose(impf_3.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - - def test_region_NorthAmerica(self): - - impf_4 = fl.ImpfRiverFlood.from_region("NorthAmerica") - - self.assertEqual(impf_4.continent, 'NorthAmerica') - self.assertEqual(impf_4.name, - 'Flood North America JRC Residential noPAA') - self.assertEqual(impf_4.haz_type, 'RF') - self.assertEqual(impf_4.id, 4) - self.assertEqual(impf_4.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_4.intensity, - np.array([0., 0.1, 0.5, 1., 1.5, 2., 3., 4., 5., - 6., 12.]))) - - self.assertTrue(np.allclose(impf_4.mdd, - np.array([0.0000, 0.2018, 0.4433, 0.5828, 0.6825, - 0.7840, 0.8543, 0.9237, 0.9585, 1.0000, - 1.0000]))) - self.assertTrue(np.allclose(impf_4.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - - def test_region_Oceania(self): - - impf_5 = fl.ImpfRiverFlood.from_region("Oceania") - - self.assertEqual(impf_5.continent, 'Oceania') - self.assertEqual(impf_5.name, 'Flood Oceania JRC Residential noPAA') - self.assertEqual(impf_5.haz_type, 'RF') - self.assertEqual(impf_5.id, 5) - self.assertEqual(impf_5.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_5.intensity, - np.array([0., 0.5, 1., 1.5, - 2., 3., 4., 5., 6., 12.]))) - self.assertTrue(np.allclose(impf_5.mdd, - np.array([0.00, 0.48, 0.64, 0.71, 0.79, 0.93, 0.97, - 0.98, 1.00, 1.00]))) - self.assertTrue(np.allclose(impf_5.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - - def test_region_SouthAmerica(self): - - impf_6 = fl.ImpfRiverFlood.from_region("SouthAmerica") - self.assertEqual(impf_6.continent, 'SouthAmerica') - self.assertEqual(impf_6.name, - 'Flood South America JRC Residential noPAA') - self.assertEqual(impf_6.haz_type, 'RF') - self.assertEqual(impf_6.id, 6) - self.assertEqual(impf_6.intensity_unit, 'm') - self.assertTrue(np.array_equal(impf_6.intensity, - np.array([0., 0.5, 1., 1.5, - 2., 3., 4., 5., 6., 12.]))) - self.assertTrue(np.allclose(impf_6.mdd, - np.array([0.0000, 0.4908, 0.7112, 0.8420, 0.9494, - 0.9836, 1.0000, 1.0000, 1.0000, 1.0000]))) - self.assertTrue(np.allclose(impf_6.paa, - np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))) - + def test_flood_imp_func_parameters(self): + for reg_id, sec_id in product(range(1,7), range(1,7)): + region, sector = IMPF_REGIONS[reg_id], IMPF_SECTORS[sec_id] + impf_id = int(f"{reg_id}{sec_id}") + impf_mdd = IMPF_MDD[impf_id] + + if impf_mdd.size == 0: + with self.assertRaises(ValueError): + fl.ImpfRiverFlood.from_jrc_region_sector(region, sector) + continue + + impf = fl.ImpfRiverFlood.from_jrc_region_sector(region, sector) + self.assertEqual(impf.continent, region) + self.assertEqual( + impf.name, f'Flood {region} JRC {sector.capitalize()} noPAA' + ) + self.assertEqual(impf.haz_type, 'RF') + self.assertEqual(impf.intensity_unit, 'm') + + self.assertEqual(impf.id, impf_id) + np.testing.assert_array_almost_equal( + impf.intensity, + np.array([0., 0.05, 0.5, 1., 1.5, 2., 3., 4., 5., 6., 12.]) + ) + np.testing.assert_array_almost_equal( + impf.mdd, + impf_mdd + ) + np.testing.assert_array_almost_equal( + impf.paa, + np.ones_like(impf.intensity) + ) + + def test_flood_imp_func_invalid_inputs(self): + with self.assertRaises(ValueError): + fl.ImpfRiverFlood.from_jrc_region_sector('unknown country', 'residential') + with self.assertRaises(ValueError): + fl.ImpfRiverFlood.from_jrc_region_sector('Africa', 'unknown sector') # Execute Tests if __name__ == "__main__":