From 6cc9cf4ed588cacd474a848db2b6ad1a1002d8e3 Mon Sep 17 00:00:00 2001 From: Joe Moorhouse Date: Sat, 7 May 2022 18:41:57 +0100 Subject: [PATCH 1/2] Expose coastal inundation and fix inventory Signed-off-by: Joe Moorhouse --- src/physrisk/data/event_provider.py | 16 +++++++ src/physrisk/data/inventory.py | 58 ++++++++++---------------- src/physrisk/kernel/calculation.py | 9 ++-- src/test/data/test_events_retrieval.py | 20 ++++++++- 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/physrisk/data/event_provider.py b/src/physrisk/data/event_provider.py index b9caaeb3..8ba49bd7 100644 --- a/src/physrisk/data/event_provider.py +++ b/src/physrisk/data/event_provider.py @@ -64,6 +64,22 @@ def _wri_inundation_prefix(): return "inundation/wri/v2" +_percentiles_map = {"95": "0", "5": "0_perc_05", "50": "0_perc_50"} +_subsidence_set = {"wtsub", "nosub"} + + +def get_source_path_wri_coastal_inundation(*, model: str, scenario: str, year: int): + type = "coast" + # model is expected to be of the form subsidence/percentile, e.g. wtsub/95 + # if percentile is omitted then 95th percentile is used + model_components = model.split("/") + sub = model_components[0] + if sub not in _subsidence_set: + raise ValueError("expected model input of the form {subsidence/percentile}, e.g. wtsub/95, nosub/5, wtsub/50") + perc = "95" if len(model_components) == 1 else model_components[1] + return os.path.join(_wri_inundation_prefix(), f"inun{type}_{scenario}_{sub}_{year}_{_percentiles_map[perc]}") + + def get_source_path_wri_riverine_inundation(*, model: str, scenario: str, year: int): type = "river" return os.path.join(_wri_inundation_prefix(), f"inun{type}_{scenario}_{model}_{year}") diff --git a/src/physrisk/data/inventory.py b/src/physrisk/data/inventory.py index 1c92aed9..e7dbfd5e 100644 --- a/src/physrisk/data/inventory.py +++ b/src/physrisk/data/inventory.py @@ -117,22 +117,17 @@ def __init__(self): "id": "nosub", "display_name": "Baseline no subsidence", "description": "Baseline condition; no subsidence", - "filename": "", - "scenarios": [ - {"id": "historical", "years": [1980]}, - {"id": "rcp4p5", "years": [2030, 2050, 2080]}, - {"id": "rcp8p5", "years": [2030, 2050, 2080]}, - ], + "filename": "inuncoast_{scenario}_nosub_{year}_0", + "scenarios": [{"id": "historical", "years": [1980]}], }, { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "nosub_95", + "id": "nosub/95", "display_name": "95% no subsidence", - "description": "No subsidence; 95th percentile sea rise", - "filename": "", + "description": "No subsidence; 95th percentile sea level rise", + "filename": "inuncoast_{scenario}_nosub_{year}_0", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], @@ -140,12 +135,11 @@ def __init__(self): { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "nosub_05", + "id": "nosub/5", "display_name": "5% no subsidence", - "description": "No subsidence; 5th percentile sea rise", - "filename": "", + "description": "No subsidence; 5th percentile sea level rise", + "filename": "inuncoast_{scenario}_nosub_{year}_0_perc_05", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], @@ -153,12 +147,11 @@ def __init__(self): { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "nosub_50", + "id": "nosub/50", "display_name": "50% no subsidence", - "description": "No subsidence; 50th percentile sea rise", - "filename": "", + "description": "No subsidence; 50th percentile sea level rise", + "filename": "inuncoast_{scenario}_nosub_{year}_0_perc_50", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], @@ -169,22 +162,17 @@ def __init__(self): "id": "wtsub", "display_name": "Baseline with subsidence", "description": "Baseline condition; with subsidence", - "filename": "", - "scenarios": [ - {"id": "historical", "years": [1980]}, - {"id": "rcp4p5", "years": [2030, 2050, 2080]}, - {"id": "rcp8p5", "years": [2030, 2050, 2080]}, - ], + "filename": "inuncoast_{scenario}_wtsub_{year}_0", + "scenarios": [{"id": "historical", "years": [1980]}], }, { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "wtsub_95", + "id": "wtsub/95", "display_name": "95% with subsidence", - "description": "With subsidence; 95th percentile sea rise", - "filename": "", + "description": "With subsidence; 95th percentile sea level rise", + "filename": "inuncoast_{scenario}_wtsub_{year}_0", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], @@ -192,12 +180,11 @@ def __init__(self): { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "wtsub_05", + "id": "wtsub/5", "display_name": "5% with subsidence", - "description": "With subsidence; 5th percentile sea rise", - "filename": "", + "description": "With subsidence; 5th percentile sea level rise", + "filename": "inuncoast_{scenario}_wtsub_{year}_0_perc_05", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], @@ -205,12 +192,11 @@ def __init__(self): { "event_type": "CoastalInundation", "path": "coastal_inundation/wri/v2", - "id": "wtsub_50", + "id": "wtsub/50", "display_name": "50% with subsidence", - "description": "With subsidence; 50th percentile sea rise", - "filename": "", + "description": "With subsidence; 50th percentile sea level rise", + "filename": "inuncoast_{scenario}_wtsub_{year}_0_perc_50", "scenarios": [ - {"id": "historical", "years": [1980]}, {"id": "rcp4p5", "years": [2030, 2050, 2080]}, {"id": "rcp8p5", "years": [2030, 2050, 2080]}, ], diff --git a/src/physrisk/kernel/calculation.py b/src/physrisk/kernel/calculation.py index 695c2b25..97b1c69b 100644 --- a/src/physrisk/kernel/calculation.py +++ b/src/physrisk/kernel/calculation.py @@ -2,12 +2,12 @@ from collections import defaultdict from typing import Any, Dict, List, Optional -from ..data.event_provider import get_source_path_wri_riverine_inundation +from ..data.event_provider import get_source_path_wri_coastal_inundation, get_source_path_wri_riverine_inundation from ..data.pregenerated_hazard_model import ZarrHazardModel from ..models import power_generating_asset_models as pgam from ..utils.helpers import get_iterable from .assets import Asset, PowerGeneratingAsset, TestAsset -from .events import RiverineInundation +from .events import CoastalInundation, RiverineInundation from .hazard_event_distrib import HazardEventDistrib from .hazard_model import HazardModel from .impact_distrib import ImpactDistrib @@ -31,7 +31,10 @@ def __init__( def get_default_zarr_source_paths(): - return {RiverineInundation: get_source_path_wri_riverine_inundation} + return { + RiverineInundation: get_source_path_wri_riverine_inundation, + CoastalInundation: get_source_path_wri_coastal_inundation, + } def get_default_hazard_model(): diff --git a/src/test/data/test_events_retrieval.py b/src/test/data/test_events_retrieval.py index 677e140e..dfcbc8f8 100644 --- a/src/test/data/test_events_retrieval.py +++ b/src/test/data/test_events_retrieval.py @@ -72,7 +72,7 @@ def test_zarr_reading(self): def test_zarr_reading_live(self): # needs valid OSC_S3_BUCKET, OSC_S3_ACCESS_KEY, OSC_S3_SECRET_KEY - request = { + request1 = { "items": [ { "request_item_id": "test_inundation", @@ -85,7 +85,23 @@ def test_zarr_reading_live(self): } ], } - response = requests.get(request_id="get_hazard_data", request_dict=request) + response = requests.get(request_id="get_hazard_data", request_dict=request1) + print(response) + + request2 = { + "items": [ + { + "request_item_id": "test_inundation", + "event_type": "CoastalInundation", + "longitudes": TestData.longitudes, + "latitudes": TestData.latitudes, + "year": 2080, + "scenario": "rcp8p5", + "model": "wtsub/95", + } + ], + } + response = requests.get(request_id="get_hazard_data", request_dict=request2) print(response) @unittest.skip("includes download of large files; deprecated") From 91ff2874a803202f5889af8fb4cbbbf627112c69 Mon Sep 17 00:00:00 2001 From: Joe Moorhouse Date: Sun, 8 May 2022 21:29:28 +0100 Subject: [PATCH 2/2] Separate riverine and coastal real estate inundation models Signed-off-by: Joe Moorhouse --- src/physrisk/kernel/calculation.py | 4 +- src/physrisk/kernel/impact_curve.py | 6 +- src/physrisk/models/real_estate_models.py | 55 ++++++++++- src/test/data/hazard_model_store.py | 50 ++++++---- src/test/data/test_events_retrieval.py | 5 +- src/test/kernel/test_financial_model.py | 6 ++ src/test/models/test_real_estate_models.py | 101 +++++++++++++++++---- 7 files changed, 178 insertions(+), 49 deletions(-) diff --git a/src/physrisk/kernel/calculation.py b/src/physrisk/kernel/calculation.py index 97b1c69b..51e21993 100644 --- a/src/physrisk/kernel/calculation.py +++ b/src/physrisk/kernel/calculation.py @@ -19,8 +19,8 @@ class AssetImpactResult: def __init__( self, impact: ImpactDistrib, - vulnerability: Optional[VulnerabilityDistrib] = None, - event: Optional[HazardEventDistrib] = None, + vulnerability: VulnerabilityDistrib, + event: HazardEventDistrib, hazard_data=None, ): self.impact = impact diff --git a/src/physrisk/kernel/impact_curve.py b/src/physrisk/kernel/impact_curve.py index 2ae5471e..464d1a82 100644 --- a/src/physrisk/kernel/impact_curve.py +++ b/src/physrisk/kernel/impact_curve.py @@ -21,6 +21,7 @@ def __init__( impact_cdfs=None, ): """Create a new asset event distribution. + Args: intensities: possible intensities of hazard event. impacts: fractional damage or fractional average disruption occurring as a result @@ -28,10 +29,7 @@ def __init__( distributions: provides the pdf and optiononally cdf of the impact distribution """ - # probabilities must be sorted and decreasing - # values must be sorted and non-decreasing (intens[i + 1] >= intens[i]) - - if not np.all(np.diff(intensities) > 0): + if not np.all(np.diff(intensities) >= 0): raise ValueError("intensities must be sorted and increasing") self.intensities = np.array(intensities) diff --git a/src/physrisk/models/real_estate_models.py b/src/physrisk/models/real_estate_models.py index 8cbeb87d..3ac19424 100644 --- a/src/physrisk/models/real_estate_models.py +++ b/src/physrisk/models/real_estate_models.py @@ -9,18 +9,32 @@ from physrisk.kernel.impact_curve import ImpactCurve from physrisk.kernel.vulnerability_model import VulnerabilityModel -from ..kernel.events import RiverineInundation +from ..kernel.events import CoastalInundation, RiverineInundation from ..kernel.vulnerability_model import applies_to_events, get_vulnerability_curves_from_resource -@applies_to_events([RiverineInundation]) class RealEstateInundationModel(VulnerabilityModel): + _default_impact_bin_edges = np.array([0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]) + _default_resource = "EU JRC global flood depth-damage functions" + def __init__( self, *, - resource: str = "EU JRC global flood depth-damage functions", - impact_bin_edges=np.array([0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]) + event_type: type, + model: str, + resource: str = _default_resource, + impact_bin_edges=_default_impact_bin_edges ): + """ + Inundation vulnerability model for real estates assets. Applies to both riverine and coastal inundation. + + Args: + event_type: Event type. + model: optional identifier for hazard event model, passed to HazardModel. + resource: embedded resource identifier used to infer vulnerability matrix. + impact_bin_edges: specifies the impact (fractional damage/disruption bins). + """ + curve_set: VulnerabilityCurves = get_vulnerability_curves_from_resource(resource) # for this model, key for looking up curves is (location, asset_type), e.g. ('Asian', 'Building/Industrial') @@ -30,7 +44,8 @@ def __init__( for item in curve_set.items: self.vuln_curves_by_type[item.asset_type].append(item) - super().__init__(model="MIROC-ESM-CHEM", event_type=RiverineInundation, impact_bin_edges=impact_bin_edges) + # global circulation parameter 'model' is a hint; can be overriden by hazard model + super().__init__(model=model, event_type=event_type, impact_bin_edges=impact_bin_edges) def get_impact_curve(self, intensities, asset: RealEstateAsset): # we interpolate the mean and standard deviation and use this to construct distributions @@ -81,3 +96,33 @@ def beta_distrib(mean, std): a = (1 - mean) / (cv * cv) - mean b = a * (1 - mean) / mean return lambda x, a=a, b=b: stats.beta.cdf(x, a, b) + + +@applies_to_events([CoastalInundation]) +class RealEstateCoastalInundationModel(RealEstateInundationModel): + def __init__( + self, + *, + model: str = "wtsub/95", + resource: str = RealEstateInundationModel._default_resource, + impact_bin_edges=RealEstateInundationModel._default_impact_bin_edges + ): + # by default include subsidence and 95% sea-level rise + super().__init__( + event_type=CoastalInundation, model=model, resource=resource, impact_bin_edges=impact_bin_edges + ) + + +@applies_to_events([RiverineInundation]) +class RealEstateRiverineInundationModel(RealEstateInundationModel): + def __init__( + self, + *, + model: str = "MIROC-ESM-CHEM", + resource: str = RealEstateInundationModel._default_resource, + impact_bin_edges=RealEstateInundationModel._default_impact_bin_edges + ): + # by default request HazardModel to use "MIROC-ESM-CHEM" GCM + super().__init__( + event_type=RiverineInundation, model=model, resource=resource, impact_bin_edges=impact_bin_edges + ) diff --git a/src/test/data/hazard_model_store.py b/src/test/data/hazard_model_store.py index 27e0f9fa..13c58372 100644 --- a/src/test/data/hazard_model_store.py +++ b/src/test/data/hazard_model_store.py @@ -3,7 +3,7 @@ import zarr.storage from affine import Affine -from physrisk.data.event_provider import get_source_path_wri_riverine_inundation +from physrisk.data.event_provider import get_source_path_wri_coastal_inundation, get_source_path_wri_riverine_inundation class TestData: @@ -43,6 +43,9 @@ class TestData: -39.2145, ] + coastal_longitudes = [12.2, 50.5919, 90.3473, 90.4295, 90.4804, 90.3429, 90.5153, 90.6007] + coastal_latitudes = [-5.55, 26.1981, 23.6473, 23.6783, 23.5699, 23.9904, 23.59, 23.6112] + def get_mock_hazard_model_store_single_curve(): return_periods = [5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0] @@ -73,28 +76,39 @@ def get_mock_hazard_model_store_single_curve(): def get_mock_hazard_model_store(longitudes, latitudes, curve): + """Returns a Zarr store, to be used with unit tests, + with the specified longitudes and latitudes set to the curve supplied.""" + return_periods = [2.0, 5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0] t = [0.008333333333333333, 0.0, -180.0, 0.0, -0.008333333333333333, 90.0, 0.0, 0.0, 1.0] shape = (len(return_periods), 21600, 43200) store = zarr.storage.MemoryStore(root="hazard.zarr") root = zarr.open(store=store, mode="w") for model, scenario, year in [("MIROC-ESM-CHEM", "rcp8p5", 2080), ("000000000WATCH", "historical", 1980)]: - array_path = get_source_path_wri_riverine_inundation(model=model, scenario=scenario, year=year) - z = root.create_dataset( # type: ignore - array_path, shape=(shape[0], shape[1], shape[2]), chunks=(shape[0], 1000, 1000), dtype="f4" - ) - z.attrs["transform_mat3x3"] = t - z.attrs["index_values"] = return_periods - - t = z.attrs["transform_mat3x3"] - transform = Affine(t[0], t[1], t[2], t[3], t[4], t[5]) - - coords = np.vstack((longitudes, latitudes, np.ones(len(longitudes)))) - inv_trans = ~transform - mat = np.array(inv_trans).reshape(3, 3) - frac_image_coords = mat @ coords - image_coords = np.floor(frac_image_coords).astype(int) - for j in range(len(longitudes)): - z[:, image_coords[1, j], image_coords[0, j]] = curve + array_path_riverine = get_source_path_wri_riverine_inundation(model=model, scenario=scenario, year=year) + _add_curves(root, longitudes, latitudes, array_path_riverine, shape, curve, return_periods, t) + + for model, scenario, year in [("wtsub/95", "rcp8p5", 2080), ("wtsub", "historical", 1980)]: + array_path_coastal = get_source_path_wri_coastal_inundation(model=model, scenario=scenario, year=year) + _add_curves(root, longitudes, latitudes, array_path_coastal, shape, curve, return_periods, t) return store + + +def _add_curves(root, longitudes, latitudes, array_path, shape, curve, return_periods, t): + z = root.create_dataset( # type: ignore + array_path, shape=(shape[0], shape[1], shape[2]), chunks=(shape[0], 1000, 1000), dtype="f4" + ) + z.attrs["transform_mat3x3"] = t + z.attrs["index_values"] = return_periods + + t = z.attrs["transform_mat3x3"] + transform = Affine(t[0], t[1], t[2], t[3], t[4], t[5]) + + coords = np.vstack((longitudes, latitudes, np.ones(len(longitudes)))) + inv_trans = ~transform + mat = np.array(inv_trans).reshape(3, 3) + frac_image_coords = mat @ coords + image_coords = np.floor(frac_image_coords).astype(int) + for j in range(len(longitudes)): + z[:, image_coords[1, j], image_coords[0, j]] = curve diff --git a/src/test/data/test_events_retrieval.py b/src/test/data/test_events_retrieval.py index dfcbc8f8..9b0bf14b 100644 --- a/src/test/data/test_events_retrieval.py +++ b/src/test/data/test_events_retrieval.py @@ -38,6 +38,7 @@ def test_hazard_data_availability_summary(self): self.assertEqual(summary["RiverineInundation"].years, [1980, 2030, 2050, 2080]) def test_zarr_reading(self): + request_dict = { "items": [ { @@ -93,8 +94,8 @@ def test_zarr_reading_live(self): { "request_item_id": "test_inundation", "event_type": "CoastalInundation", - "longitudes": TestData.longitudes, - "latitudes": TestData.latitudes, + "longitudes": TestData.coastal_longitudes, + "latitudes": TestData.coastal_latitudes, "year": 2080, "scenario": "rcp8p5", "model": "wtsub/95", diff --git a/src/test/kernel/test_financial_model.py b/src/test/kernel/test_financial_model.py index 6014a472..0735e7eb 100644 --- a/src/test/kernel/test_financial_model.py +++ b/src/test/kernel/test_financial_model.py @@ -28,6 +28,12 @@ def test_financial_model(self): [0.059601218, 0.33267087, 0.50511575, 0.71471703, 0.8641244, 1.0032823, 1.1491022, 1.1634114, 1.1634114] ) store = get_mock_hazard_model_store(TestData.longitudes, TestData.latitudes, curve) + + # we need to define + # 1) The hazard models + # 2) The vulnerability models + # 3) The financial models + hazard_model = ZarrHazardModel(source_paths=calculation.get_default_zarr_source_paths(), store=store) model = LossModel(hazard_model=hazard_model) diff --git a/src/test/models/test_real_estate_models.py b/src/test/models/test_real_estate_models.py index 8d0f6a71..182cb475 100644 --- a/src/test/models/test_real_estate_models.py +++ b/src/test/models/test_real_estate_models.py @@ -7,17 +7,15 @@ from physrisk.data.pregenerated_hazard_model import ZarrHazardModel from physrisk.kernel import calculation from physrisk.kernel.assets import RealEstateAsset -from physrisk.models.real_estate_models import RealEstateInundationModel +from physrisk.models.real_estate_models import RealEstateCoastalInundationModel, RealEstateRiverineInundationModel class TestRealEstateModels(unittest.TestCase): """Tests RealEstateInundationModel.""" - def test_real_estate_model(self): + def test_real_estate_model_details(self): - curve = np.array( - [0.059601218, 0.33267087, 0.50511575, 0.71471703, 0.8641244, 1.0032823, 1.1491022, 1.1634114, 1.1634114] - ) + curve = np.array([0.0596, 0.333, 0.505, 0.715, 0.864, 1.003, 1.149, 1.163, 1.163]) store = get_mock_hazard_model_store(TestData.longitudes, TestData.latitudes, curve) hazard_model = ZarrHazardModel(source_paths=calculation.get_default_zarr_source_paths(), store=store) @@ -30,7 +28,74 @@ def test_real_estate_model(self): scenario = "rcp8p5" year = 2080 - vulnerability_models = {RealEstateAsset: [RealEstateInundationModel()]} + vulnerability_models = {RealEstateAsset: [RealEstateRiverineInundationModel()]} + + results = calculation.calculate_impacts( + assets, hazard_model, vulnerability_models, scenario=scenario, year=year + ) + + hazard_bin_edges = results[assets[0]].event.intensity_bin_edges + hazard_bin_probs = results[assets[0]].event.prob + + # check one: + # the probability of inundation greater than 0.505m in a year is 1/10.0 + # the probability of inundation greater than 0.333m in a year is 1/5.0 + # therefore the probability of an inundation between 0.333 and 0.505 in a year is 1/5.0 - 1/10.0 + np.testing.assert_almost_equal(hazard_bin_edges[1:3], np.array([0.333, 0.505])) + np.testing.assert_almost_equal(hazard_bin_probs[1], 0.1) + + # check that intensity bin edges for vilnerability matrix are same as for hazard + vulnerability_intensity_bin_edges = results[assets[0]].vulnerability.intensity_bins + np.testing.assert_almost_equal(vulnerability_intensity_bin_edges, hazard_bin_edges) + + # check the impact distribution the matrix is size [len(intensity_bins) - 1, len(impact_bins) - 1] + cond_probs = results[assets[0]].vulnerability.prob_matrix[1, :] + # check conditional prob for inundation intensity 0.333..0.505 + mean, std = np.mean(cond_probs), np.std(cond_probs) + np.testing.assert_almost_equal(cond_probs.sum(), 1) + np.testing.assert_allclose([mean, std], [0.09090909, 0.08184968], rtol=1e-6) + + # probability that impact occurs between impact bin edge 1 and impact bin edge 2 + prob_impact = np.dot(hazard_bin_probs, results[assets[0]].vulnerability.prob_matrix[:, 1]) + np.testing.assert_almost_equal(prob_impact, 0.19350789547968042) + + # no check with pre-calculated values for others: + np.testing.assert_allclose( + results[assets[0]].impact.prob, + np.array( + [ + 0.02815762, + 0.1935079, + 0.11701139, + 0.06043065, + 0.03347816, + 0.02111368, + 0.01504522, + 0.01139892, + 0.00864469, + 0.00626535, + 0.00394643, + ] + ), + rtol=2e-6, + ) + + def test_coastal_real_estate_model(self): + curve = np.array([0.223, 0.267, 0.29, 0.332, 0.359, 0.386, 0.422, 0.449, 0.476]) + + store = get_mock_hazard_model_store(TestData.coastal_longitudes, TestData.coastal_latitudes, curve) + hazard_model = ZarrHazardModel(source_paths=calculation.get_default_zarr_source_paths(), store=store) + + # location="Europe", type="Buildings/Residential" + assets = [ + RealEstateAsset(lat, lon, location="Asia", type="Buildings/Industrial") + for lon, lat in zip(TestData.coastal_longitudes[0:1], TestData.coastal_latitudes[0:1]) + ] + + scenario = "rcp8p5" + year = 2080 + + vulnerability_models = {RealEstateAsset: [RealEstateCoastalInundationModel()]} results = calculation.calculate_impacts( assets, hazard_model, vulnerability_models, scenario=scenario, year=year @@ -40,18 +105,18 @@ def test_real_estate_model(self): results[assets[0]].impact.prob, np.array( [ - 0.02816851, - 0.19360632, - 0.11700387, - 0.06039094, - 0.03344832, - 0.02109813, - 0.01503788, - 0.01139472, - 0.00864163, - 0.00626335, - 0.00394632, + 2.78081230e-02, + 1.96296619e-01, + 1.32234770e-01, + 7.36581177e-02, + 3.83434609e-02, + 1.83916914e-02, + 7.97401009e-03, + 3.04271878e-03, + 9.79400125e-04, + 2.41250436e-04, + 2.98387241e-05, ] ), - rtol=1e-6, + rtol=2e-6, )