{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Custom vulnerability functions for asset-level impact calculations\n", "In this walk-through, custom vulnerability functions are defined and used to perform the asset-level impact calculations. The portfolio is identical to the one previously calculated; the difference is only in the config-based vulnerability.\n", "\n", "There is no option exposed to inject a custom vulnerability config via the API at the moment, hence the library is used.\n", "\n", "We start by defining a portfolio and an acute vulnerability function for Wind." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# pip install nbformat pandas plotly requests" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from io import StringIO\n", "import json\n", "from typing import NamedTuple\n", "from dependency_injector import providers\n", "from physrisk.container import Container\n", "from physrisk.vulnerability_models.vulnerability import VulnerabilityModelsFactory\n", "from physrisk.vulnerability_models.config_based_impact_curves import (\n", " VulnerabilityConfigItem,\n", " config_items_from_csv,\n", " config_items_to_df,\n", ")\n", "import plotly.io\n", "from plotly.subplots import make_subplots\n", "\n", "plotly.io.renderers.default = \"notebook\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a portfolio. The \"type\" attribute can be used to define an arbitrary scheme to capture categories of assets, matching the vulnerability configuration. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "portfolio = {\n", " \"items\": [\n", " {\n", " \"asset_class\": \"RealEstateAsset\",\n", " \"type\": \"Buildings/Industrial\",\n", " \"location\": \"Asia\",\n", " \"latitude\": 24.0426,\n", " \"longitude\": 91.0158,\n", " },\n", " {\n", " \"asset_class\": \"RealEstateAsset\",\n", " \"type\": \"Buildings/Industrial\",\n", " \"location\": \"Asia\",\n", " \"latitude\": 22.6588,\n", " \"longitude\": 90.3373,\n", " },\n", " ]\n", "}\n", "request = {\n", " \"assets\": portfolio,\n", " \"include_asset_level\": True,\n", " \"include_calc_details\": True,\n", " \"include_measures\": True,\n", " \"years\": [2050],\n", " \"scenario\": \"ssp585\",\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Configuration can be defined programmatically, but is also intended to be maintained in CSV format. Here we write the config line to CSV and read back again. In practise, a file of config lines can be maintained. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hazard_class,asset_class,asset_identifier,indicator_id,indicator_units,impact_id,impact_units,curve_type,points_x,points_y,points_z,cap_of_points_x,cap_of_points_y,activation_of_points_x\n", "Wind,RealEstateAsset,\"type=Buildings/Industrial,location=Asia\",max_speed,m/s,damage,,indicator/piecewise_linear,\"[20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 110.0]\",\"[0.0, 0.0, 0.0, 0.03, 0.11, 0.23, 0.37, 0.52, 0.63, 0.71, 0.78, 0.83, 0.87, 0.89, 0.92, 1.0]\",,,,\n", "\n" ] } ], "source": [ "config_items = [\n", " VulnerabilityConfigItem(\n", " hazard_class=\"Wind\",\n", " asset_class=\"RealEstateAsset\",\n", " asset_identifier=\"type=Buildings/Industrial,location=Asia\",\n", " indicator_id=\"max_speed\",\n", " indicator_units=\"m/s\",\n", " impact_id=\"damage\",\n", " impact_units=None,\n", " curve_type=\"indicator/piecewise_linear\",\n", " points_x=[20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 110],\n", " points_y=[\n", " 0,\n", " 0,\n", " 0,\n", " 0.03,\n", " 0.11,\n", " 0.23,\n", " 0.37,\n", " 0.52,\n", " 0.63,\n", " 0.71,\n", " 0.78,\n", " 0.83,\n", " 0.87,\n", " 0.89,\n", " 0.92,\n", " 1.0,\n", " ],\n", " activation_of_points_x=None,\n", " cap_of_points_x=None,\n", " cap_of_points_y=None,\n", " )\n", "]\n", "\n", "csv_config = config_items_to_df(config_items).to_csv(index=False)\n", "print(csv_config)\n", "\n", "config_items = config_items_from_csv(StringIO(csv_config))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Having defined the configuration the calculation is run. Dependency injection is used to apply the custom configuration. " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# we make use of dependency injection to inject a vulnerability model that accepts the configuration.\n", "container = Container()\n", "container.override_providers(\n", " vulnerability_models_factory=providers.Factory(\n", " VulnerabilityModelsFactory, config=config_items\n", " )\n", ")\n", "requester = container.requester()\n", "response = json.loads(\n", " requester.get(request_id=\"get_asset_impact\", request_dict=request)\n", ")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "asset0_impacts = response[\"asset_impacts\"][1][\"impacts\"]\n", "\n", "\n", "class Key(NamedTuple):\n", " hazard_type: str\n", " scenario_id: str\n", " year: str\n", "\n", "\n", "asset0_impact_dict = {}\n", "for i in asset0_impacts:\n", " key = i[\"key\"]\n", " asset0_impact_dict[Key(key[\"hazard_type\"], key[\"scenario_id\"], key[\"year\"])] = i\n", "\n", "hazard_types = set(k.hazard_type for k in asset0_impact_dict.keys())\n", "wind_impact_histo = asset0_impact_dict[Key(\"Wind\", \"historical\", \"None\")]\n", "wind_impact_ssp585 = asset0_impact_dict[Key(\"Wind\", \"ssp585\", \"2050\")]\n", "\n", "exceedance_histo = wind_impact_histo[\"impact_exceedance\"]\n", "exceedance_ssp585 = wind_impact_ssp585[\"impact_exceedance\"]\n", "\n", "fig1 = make_subplots(rows=1, cols=1)\n", "\n", "fig1.add_scatter(\n", " x=exceedance_histo[\"exceed_probabilities\"],\n", " y=exceedance_histo[\"values\"],\n", " name=\"baseline wind\",\n", " row=1,\n", " col=1,\n", ")\n", "fig1.add_scatter(\n", " x=exceedance_ssp585[\"exceed_probabilities\"],\n", " y=exceedance_ssp585[\"values\"],\n", " name=\"wind SSP585\",\n", " row=1,\n", " col=1,\n", ")\n", "fig1.update_xaxes(\n", " title=\"Annual exceedance probability\",\n", " title_font={\"size\": 14},\n", " row=1,\n", " col=1,\n", " type=\"log\",\n", " autorange=\"reversed\",\n", ")\n", "fig1.update_yaxes(\n", " title=\"Damage as fraction of insurable value\", title_font={\"size\": 14}, row=1, col=1\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.15" } }, "nbformat": 4, "nbformat_minor": 2 }