{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Manual Damage Curves Tutorial\n", "\n", "This tutorial demonstrates how to perform a **damage analysis using custom/manual damage curves** in RA2CE. \n", "Manual curves allow you to define site-specific or locally calibrated hazard–damage relationships rather than relying on generic reference curves.\n", "\n", "This is particularly useful when:\n", "\n", "- You have local historical damage data.\n", "- You want to account for specific infrastructure types.\n", "- You need to test alternative vulnerability scenarios." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "\n", "## Step 1: Define project paths\n", "\n", "As usual, define your project folder and subdirectories:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "\n", "root_dir = Path(\"data\", \"damage_manual\")\n", "static_path = root_dir.joinpath(\"static\")\n", "hazard_path = static_path.joinpath(\"hazard\")\n", "network_path = static_path.joinpath(\"network\")\n", "output_path = root_dir.joinpath(\"output\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Step 2: Configure the road network and hazard\n", "\n", "The network is downloaded from **OpenStreetMap (OSM)**, clipped to a region polygon (`polygon.geojson`). \n", "We specify which **road types** should be included in the analysis." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\hauth\\miniforge3\\envs\\ra2ce_env\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "from ra2ce.network.network_config_data.enums.road_type_enum import RoadTypeEnum\n", "from ra2ce.network.network_config_data.enums.source_enum import SourceEnum\n", "from ra2ce.network.network_config_data.enums.network_type_enum import NetworkTypeEnum\n", "from ra2ce.network.network_config_data.network_config_data import NetworkSection\n", "from ra2ce.ra2ce_handler import Ra2ceHandler\n", "\n", "\n", "network_section = NetworkSection(\n", " network_type=NetworkTypeEnum.DRIVE,\n", " source=SourceEnum.OSM_DOWNLOAD,\n", " polygon=static_path.joinpath(\"polygon.geojson\"),\n", " save_gpkg=True,\n", " road_types=[\n", " RoadTypeEnum.SECONDARY,\n", " RoadTypeEnum.SECONDARY_LINK,\n", " RoadTypeEnum.PRIMARY,\n", " RoadTypeEnum.PRIMARY_LINK,\n", " RoadTypeEnum.TRUNK,\n", " RoadTypeEnum.MOTORWAY,\n", " RoadTypeEnum.MOTORWAY_LINK,\n", " ],\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We provide hazard input in the form of **GeoTIFF raster files** (e.g., flood depth maps). \n", "RA2CE will overlay these rasters with the road network to compute hazard intensities for each asset." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from ra2ce.network.network_config_data.enums.aggregate_wl_enum import AggregateWlEnum\n", "from ra2ce.network.network_config_data.network_config_data import HazardSection\n", "\n", "hazard_section = HazardSection(\n", " hazard_map=[Path(file) for file in hazard_path.glob(\"*.tif\")],\n", " aggregate_wl=AggregateWlEnum.MEAN, # mean water depth used in analysis\n", " hazard_crs=\"EPSG:4326\", # ensure hazard map is in EPSG:4326 projection\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We combine the network and hazard information into a single configuration object." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from ra2ce.network.network_config_data.network_config_data import NetworkConfigData\n", "\n", "network_config_data = NetworkConfigData(\n", " root_path=root_dir,\n", " static_path=static_path,\n", " network=network_section,\n", " hazard=hazard_section\n", ")\n", "network_config_data.network.save_gpkg = True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Step 3: Define the damage analysis\n", "\n", "Here, we specify that RA2CE should perform a **damage analysis** using **manual damage curves (MAN)** with the class [AnalysisSectionDamages](../api/ra2ce.analysis.analysis_config_data.html#ra2ce.analysis.analysis_config_data.analysis_config_data.AnalysisSectionDamages){.api-ref} and the attribute `damage_curve` set to [DamageCurveEnum.MAN](../api/ra2ce.analysis.analysis_config_data.enums.html#ra2ce.analysis.analysis_config_data.enums.damage_curve_enum.DamageCurveEnum.MAN){.api-ref}\n", "For manual damage curves, it is important to also specify the input data in the folder path in the config `input_path`. This is the location where the custom manual curves will be defined and placed (see next step).\n", "\n", "The event type can be set to EVENT if damages are to be calculated for the hazard maps only (example below), or to RETURN_PERIOD if the analysis should estimate risk over a specified return period (see tutorial )." ] }, { "cell_type": "code", "execution_count": null, "id": "3dc2947b", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from ra2ce.analysis.damages.damages import AnalysisSectionDamages\n", "from ra2ce.analysis.analysis_config_data.enums.analysis_damages_enum import AnalysisDamagesEnum\n", "from ra2ce.analysis.analysis_config_data.enums.event_type_enum import EventTypeEnum\n", "from ra2ce.analysis.analysis_config_data.enums.damage_curve_enum import DamageCurveEnum\n", "from ra2ce.analysis.analysis_config_data.analysis_config_data import AnalysisConfigData\n", "\n", "damages_analysis = [AnalysisSectionDamages(\n", " name='damages_reference_curve_manual',\n", " analysis=AnalysisDamagesEnum.DAMAGES,\n", " event_type=EventTypeEnum.EVENT,\n", " damage_curve=DamageCurveEnum.MAN, # use manual damage curve\n", " save_csv=True,\n", " save_gpkg=True\n", ")]\n", "\n", "analysis_config_data = AnalysisConfigData(\n", " analyses=damages_analysis,\n", " output_path=output_path,\n", " input_path=root_dir.joinpath(\"input_data\")\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Step 4: Create damage curve files\n", "\n", "In the manual situation, two input files are expected:\n", "\n", "1. A file that specifies the **shape of the vulnerability curve**:\n", " - x-axis = hazard intensity (e.g. water depth in cm)\n", " - y-axis = damage fraction (0–1, representing the % of total construction cost)\n", "\n", "2. A file that specifies the **construction costs** per road type and number of lanes.\n", "\n", "Both files should be placed in the folder `input_data/damage_functions/all_road_types/`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vulnerability curve (hazard severity vs. damage fraction)\n", "\n", "The file `hazard_severity_damage_fraction.csv` looks like:\n", "```text\n", "depth;damage\n", "cm;% of total construction costs\n", "0;0\n", "100;0.1\n", "200;0.2\n", "400;0.4\n", "800;0.8\n", "12000;1\n", "```\n", "\n", "Where:\n", "- `depth` = water depth in **cm**\n", "- `damage` = damage fraction (0–1, relative to construction cost)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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WbIEMpkM33//PaRSKQYNGoR58+bBz8/vhff7JGdnZ5w4cQKff/45tmzZgu+++w729vZo3Lix2uF16tSpKCgoQFRUFNavX49mzZph165dmDx58lPHnzlzBnPmzEF+fj46d+6M7777Dubm5i99PNOnT8f169fx9ddfIz8/Hx06dFAJ582bN0fjxo2RnJyMYcOGqbVNQ0ND7N69G19++SWioqKwefNm2Nvbo127dvD391eO0+bXa/Dgwfjyyy/h4+ODZs2alXl+6NChqF27NubOnYt58+ahuLgYbm5uaN++vfJiXiJtkYgn3xsjIiIi0pLAwEDY2dkhNjZW16UQVQmcc05EREQV4tSpU0hISMCIESN0XQpRlcEz50RERKRV586dw+nTp/HNN98gKysLV69ehampqa7LIqoSeOaciIiItGrTpk0ICwuDTCbD2rVrGcyJNMAz50REREREeoJnzomIiIiI9ATDORERERGRnuB9zomqGIVCgTt37sDKyuqZH51NRERE+kMIgfz8fNSuXRsGBk8/P85wTlTF3LlzB+7u7roug4iIiF7AzZs3UadOnac+z3BOVMVYWVkBePTNbW1trbXtymQy7N27F127di330xPpH+yV+tgrzbBf6mOv1Mdeqa8ie5WXlwd3d3fl7/GnYTgnqmIeT2WxtrbWejg3NzeHtbU1f3g/B3ulPvZKM+yX+tgr9bFX6quMXj1vSiovCCUiIiIi0hMM50REREREeoLhnIiIiIhITzCcExERERHpCYZzIiIiIiI9wXBORERERKQnGM6JiIiIiPQEwzkRERERkZ5gOCciIiIi0hMM50RERERU48kVAsdTs3E6S4LjqdmQK4RO6mA4J6pEf/75J3r37o3atWtDIpFg69atui6JiIioxos+l4Z2X+3HWytOYfUlQ7y14hTafbUf0efSKr0WhnOiSlRQUICAgAAsW7ZM16UQERERHgXz93+LQ1pukcry9NwivP9bXKUHdKNK3RtRDde9e3d0795d12UQERERHk1lmbkjCeVNYBEAJABm7khCF18XGBpIKqUmhnMiPVdcXIzi4mLl47y8PACATCaDTCbT2n4eb0ub26yu2Cv1sVeaYb/Ux16pj716uuOp2WXOmP+bAJCWW4RjlzMR5G33UvtSt/8SIYRuZrsT1XASiQS///47+vXr98xxM2bMwMyZM8ss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ESNGAACCg4PRunVr9OvXD3v37sW1a9fw119/4dNPP1W5s4mpqSlGjhyJxMREHD58GOPHj8egQYOUc7e9vLxw5swZXLhwAVlZWZDJZFo9lsjISKxduxaRkZFITk7G2bNn8dVXX2l1H0RUORjOiYioRoqOjoarqyu8vLzQrVs3HDhwAIsXL8a2bdtgaGgI4NFUj927d+O1115DWFgYGjRogCFDhuD69evKOdoA4OPjgzfeeAM9evRA165d0aRJE3z33XfK50ePHo2GDRuiRYsWcHR0xNGjR7V6LK+//jo2btyI7du3o2nTpujUqRNOnDih1X0QUeWQCN4ziYiI6IXNmDEDW7duRUJCQqXsTyKR4Pfff9fqJ44+y6hRo5CTk4OtW7dWyv6IajqeOSciIqpiQkNDUadOnQrdx+HDh2FpaYk1a9ZU6H6ISBXv1kJERFSFXLp0CQCUU28qSosWLZTvBlhaWlbovojoH5zWQkRERESkJzithYiIiIhITzCcExERERHpCYZzIiIiIiI9wXBORERERKQnGM6JiIiIiPQEwzkRERERkZ5gOCciIiIi0hMM50REREREeoLhnIiIiIhIT/wfxKq9LgD7vUUAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "\n", "input_data_path = root_dir.joinpath(\"input_data\")\n", "vuln_curves = pd.read_csv(input_data_path.joinpath(\"damage_functions\", \"all_road_types\",\"hazard_severity_damage_fraction.csv\"), delimiter=\";\")\n", "\n", "plt.plot(vuln_curves[\"depth\"], vuln_curves[\"damage\"], marker=\"o\")\n", "plt.xlabel(\"Depth [cm]\")\n", "plt.ylabel(\"Damage fraction\")\n", "plt.title(\"Manual vulnerability curve\")\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Manual vulnerability curve](/_resources/figures/manual_vuln_curve.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Maximum construction costs per road type and lanes\n", "\n", "The file `max_damage_road_types.csv` looks like:\n", "```text\n", "Road_type \\ lanes;1;2;3;4;5;6;7;8\n", "unit;euro/m;euro/m;euro/m;euro/m;euro/m;euro/m;euro/m;euro/m\n", "tertiary_link;110;120;130;140;150;130;140;150\n", "tertiary;110;120;130;140;150;130;140;150\n", "trunk;110;120;130;140;150;130;140;150\n", "trunk_link;110;120;130;140;150;130;140;150\n", "secondary_link;11;12;13;14;15;13;14;15\n", "secondary;11;12;13;14;15;13;14;15\n", "primary_link;11;12;13;14;15;13;14;15\n", "primary;11;12;13;14;15;13;14;15\n", "residential;1100;1200;1300;1400;1500;1300;1400;1500\n", "['tertiary', 'residential'];510;520;530;540;550;530;540;550\n", "motorway;1100;1200;1300;1400;1500;1300;1400;1500\n", "motorway_link;510;520;530;540;550;530;540;550\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Note**\n", ">\n", "> - The *first file* defines the shape of the damage curve (hazard → damage fraction).\n", "> - The *second file* defines the maximum construction costs per road type and lane count.\n", "> - Together, they allow RA2CE to estimate damages in absolute currency units." ] }, { "cell_type": "markdown", "id": "059effee", "metadata": {}, "source": [ "----\n", "## Step 5: Run the analysis" ] }, { "cell_type": "code", "execution_count": 7, "id": "b6e0c6ca", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\hauth\\miniforge3\\envs\\ra2ce_env\\Lib\\site-packages\\osmnx\\simplification.py:513: UserWarning: Geometry is in a geographic CRS. Results from 'buffer' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", "\n", " merged = convert.graph_to_gdfs(G, edges=False)[\"geometry\"].buffer(tolerance).unary_union\n", "c:\\Users\\hauth\\miniforge3\\envs\\ra2ce_env\\Lib\\site-packages\\osmnx\\simplification.py:560: UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.\n", "\n", " centroids = node_clusters.centroid\n", "100%|██████████| 127/127 [00:00<00:00, 126827.76it/s]\n", "2025-10-01 05:05:17 PM - [avg_speed_calculator.py:175] - root - WARNING - No valid file found with average speeds data\\damage_manual\\static\\output_graph\\avg_speed.csv, calculating and saving them instead.\n", "Graph hazard overlay with flood100: 100%|██████████| 109/109 [00:00<00:00, 184.69it/s]\n", "Graph fraction with hazard overlay with flood100: 100%|██████████| 109/109 [01:00<00:00, 1.81it/s]\n", "Graph hazard overlay with flood1000: 100%|██████████| 109/109 [00:00<00:00, 229.58it/s]\n", "Graph fraction with hazard overlay with flood1000: 100%|██████████| 109/109 [01:16<00:00, 1.42it/s]\n", "2025-10-01 05:07:37 PM - [hazard_intersect_builder_for_tif.py:225] - root - WARNING - Some geometries have NoneType objects (no coordinate information), namely: Empty GeoDataFrame\n", "Columns: [osmid, oneway, lanes, ref, highway, maxspeed, reversed, length, rfid_c, rfid, avgspeed, time, bridge, name, junction, geometry]\n", "Index: [].This could be due to segmentation, and might cause an exception in hazard overlay\n", "Network hazard overlay with flood100: 100%|██████████| 2727/2727 [00:02<00:00, 910.21it/s] \n", "Network fraction with hazard overlay with flood100: 100%|██████████| 2727/2727 [00:12<00:00, 209.88it/s]\n", "Network hazard overlay with flood1000: 100%|██████████| 2727/2727 [00:03<00:00, 880.10it/s] \n", "Network fraction with hazard overlay with flood1000: 100%|██████████| 2727/2727 [00:17<00:00, 156.20it/s]\n", "2025-10-01 05:08:14 PM - [damage_network_base.py:121] - root - WARNING - Of the 2727 road segments, only 1568 had lane data, so for 1159 the '\n", " lane data will be interpolated from the existing data\n", "2025-10-01 05:08:15 PM - [damage_network_base.py:134] - root - WARNING - Interpolated the missing lane data as follows: {'motorway': 2.0, 'primary': 2.0, 'secondary': 2.0, 'trunk': 1.0}\n" ] }, { "data": { "text/plain": [ "[DamagesResultWrapper(segment_based_result=AnalysisResult(analysis_result= osmid oneway lanes ref infra_type \\\n", " u v key \n", " 42002848 4336238970 0 435722626 True 3.0 N2 trunk \n", " 42003549 5284280675 0 215573156 True 2.0 A79 motorway \n", " 5284280682 0 254696086 True 2.0 A2 motorway \n", " 42004326 3744093239 0 254696086 True 2.0 A2 motorway \n", " 42005137 2832217846 0 720205318 True 1.0 A79 motorway_link \n", " ... ... ... ... ... ... \n", " 12680821393 42080697 0 6773022 False 2.0 nan secondary \n", " 42080429 0 6773022 False 2.0 nan secondary \n", " 12696408646 2540119540 0 6773079 False 2.0 nan secondary \n", " 42083916 0 6773079 False 2.0 nan secondary \n", " 13073531942 4659465278 0 435562863 True 2.0 A79 motorway \n", " \n", " maxspeed reversed length rfid_c rfid ... \\\n", " u v key ... \n", " 42002848 4336238970 0 80 False 121.954 1 1 ... \n", " 42003549 5284280675 0 100 False 31.186 2 2 ... \n", " 5284280682 0 100 False 43.429 3 3 ... \n", " 42004326 3744093239 0 100 False 26.171 4 3 ... \n", " 42005137 2832217846 0 80 False 54.061 5 99 ... \n", " ... ... ... ... ... ... ... \n", " 12680821393 42080697 0 50 False 29.033 2723 45 ... \n", " 42080429 0 50 True 22.549 2724 54 ... \n", " 12696408646 2540119540 0 50 False 33.712 2725 78 ... \n", " 42083916 0 50 True 2.818 2726 95 ... \n", " 13073531942 4659465278 0 100 False 23.232 2727 124 ... \n", " \n", " F_EV1_me F_EV1_fr F_EV2_mi F_EV2_ma F_EV2_me \\\n", " u v key \n", " 42002848 4336238970 0 NaN 1.0 NaN NaN NaN \n", " 42003549 5284280675 0 NaN 1.0 NaN NaN NaN \n", " 5284280682 0 NaN 1.0 NaN NaN NaN \n", " 42004326 3744093239 0 NaN 1.0 NaN NaN NaN \n", " 42005137 2832217846 0 1.000000 1.0 1.0 2.0 1.166667 \n", " ... ... ... ... ... ... \n", " 12680821393 42080697 0 4.090909 1.0 5.0 5.0 5.000000 \n", " 42080429 0 3.750000 1.0 3.0 5.0 4.437500 \n", " 12696408646 2540119540 0 1.000000 1.0 1.0 1.0 1.000000 \n", " 42083916 0 1.000000 1.0 1.0 2.0 1.666667 \n", " 13073531942 4659465278 0 1.416667 1.0 1.0 3.0 2.000000 \n", " \n", " F_EV2_fr road_type lanes_copy dam_EV1_al \\\n", " u v key \n", " 42002848 4336238970 0 1.0 trunk 3.0 NaN \n", " 42003549 5284280675 0 1.0 motorway 2.0 NaN \n", " 5284280682 0 1.0 motorway 2.0 NaN \n", " 42004326 3744093239 0 1.0 motorway 2.0 NaN \n", " 42005137 2832217846 0 1.0 motorway 1.0 2757.0 \n", " ... ... ... ... ... \n", " 12680821393 42080697 0 1.0 secondary 2.0 143.0 \n", " 42080429 0 1.0 secondary 2.0 101.0 \n", " 12696408646 2540119540 0 1.0 secondary 2.0 40.0 \n", " 42083916 0 1.0 secondary 2.0 3.0 \n", " 13073531942 4659465278 0 1.0 motorway 2.0 3949.0 \n", " \n", " dam_EV2_al \n", " u v key \n", " 42002848 4336238970 0 NaN \n", " 42003549 5284280675 0 NaN \n", " 5284280682 0 NaN \n", " 42004326 3744093239 0 NaN \n", " 42005137 2832217846 0 3217.0 \n", " ... ... \n", " 12680821393 42080697 0 174.0 \n", " 42080429 0 120.0 \n", " 12696408646 2540119540 0 40.0 \n", " 42083916 0 6.0 \n", " 13073531942 4659465278 0 5576.0 \n", " \n", " [2727 rows x 28 columns], analysis_config=AnalysisSectionDamages(name='damages_reference_curve_manual', save_gpkg=True, save_csv=True, analysis=, representative_damage_percentage=100, event_type=, damage_curve=, risk_calculation_mode=, risk_calculation_year=0, create_table=False, file_name=None), output_path=WindowsPath('data/damage_manual/output'), _custom_name='damages_reference_curve_manual_segmented'), link_based_result=AnalysisResult(analysis_result= u v key \\\n", " 0 42002848 3510081992 0 \n", " 1 42002848 42005643 0 \n", " 2 42002848 2832217848 0 \n", " 3 42003549 1912827603 0 \n", " 4 42003549 2119022099 0 \n", " .. ... ... ... \n", " 104 2587147852 2832217848 0 \n", " 105 3441582565 3441582576 0 \n", " 106 3475087790 3475088037 0 \n", " 107 9646055861 9646055863 0 \n", " 108 9646055861 10036651817 0 \n", " \n", " osmid oneway lanes \\\n", " 0 435722626 True 3 \n", " 1 72400805 True 2 \n", " 2 [720205318, 284802951] True 1 \n", " 3 [382923864, 215573156] True ['3', '2'] \n", " 4 [337060729, 254696086, 7125689, 7125692, 10930... True 2 \n", " .. ... ... ... \n", " 104 [369221729, 720205319] True 1 \n", " 105 [337060737, 587459365] True 2 \n", " 106 [340294690, 340294691, 340294686] True ['1', '2'] \n", " 107 6779700 True 1 \n", " 108 6779700 True 1 \n", " \n", " ref highway maxspeed reversed ... EV1_me EV1_fr EV2_me \\\n", " 0 N2 trunk 80 False ... 1.000000 1.0 1.000000 \n", " 1 N2 trunk 80 False ... NaN 1.0 NaN \n", " 2 A79 motorway_link 80 False ... 2.837607 1.0 3.508065 \n", " 3 A79 motorway 100 False ... 4.592040 1.0 4.892019 \n", " 4 A2 motorway 100 False ... 4.510000 1.0 4.539823 \n", " .. ... ... ... ... ... ... ... ... \n", " 104 A79 motorway 100 False ... 4.330798 1.0 4.637363 \n", " 105 nan primary 50 False ... 4.227273 1.0 3.323529 \n", " 106 nan primary 50 False ... 4.000000 1.0 4.062500 \n", " 107 nan secondary 50 False ... 1.000000 1.0 3.400000 \n", " 108 nan secondary 50 False ... 1.500000 1.0 2.444444 \n", " \n", " EV2_fr dam_EV1_al_segments dam_EV1_al \\\n", " 0 1.0 [nan, 1364.0] 1364.0 \n", " 1 1.0 [nan, nan, nan, nan, nan] 0.0 \n", " 2 1.0 [5581.0, 9553.0, 2757.0, nan, nan, nan, nan, 2... 27270.0 \n", " 3 1.0 [13464.0, 15332.0, nan, 8167.0, 10481.0, 8444.... 191760.0 \n", " 4 1.0 [nan, nan, 12109.0, nan, nan, nan, nan, 2392.0... 84491.0 \n", " .. ... ... ... \n", " 104 1.0 [16409.0, 27780.0, 27231.0, 36025.0, 33800.0, ... 220478.0 \n", " 105 1.0 [27.0, nan, nan, 55.0, 34.0, 47.0, nan, 42.0, ... 405.0 \n", " 106 1.0 [nan, nan, 123.0, 148.0] 271.0 \n", " 107 1.0 [2.0, 2.0, 2.0, 2.0] 8.0 \n", " 108 1.0 [nan, nan, nan, nan, nan, nan, 2.0, nan, nan, ... 12.0 \n", " \n", " dam_EV2_al_segments dam_EV2_al \\\n", " 0 [nan, 1364.0] 1364.0 \n", " 1 [nan, nan, nan, nan, nan] 0.0 \n", " 2 [6725.0, 10747.0, 3217.0, nan, nan, nan, nan, ... 34419.0 \n", " 3 [13464.0, 15332.0, nan, 10209.0, 10500.0, 9703... 209378.0 \n", " 4 [nan, nan, 12109.0, 7222.0, nan, nan, nan, 340... 109199.0 \n", " .. ... ... \n", " 104 [19170.0, 20835.0, 28273.0, 33725.0, 39306.0, ... 226039.0 \n", " 105 [27.0, 24.0, nan, 55.0, 43.0, 47.0, 9.0, 42.0,... 480.0 \n", " 106 [nan, nan, 127.0, 151.0] 278.0 \n", " 107 [5.0, 8.0, 8.0, 8.0] 29.0 \n", " 108 [4.0, 2.0, nan, 2.0, 6.0, 7.0, 7.0, 7.0, 5.0, ... 84.0 \n", " \n", " name junction \n", " 0 nan nan \n", " 1 nan nan \n", " 2 nan nan \n", " 3 nan nan \n", " 4 nan nan \n", " .. ... ... \n", " 104 nan nan \n", " 105 Nieuwe Limmelderweg nan \n", " 106 Nieuwe Limmelderweg nan \n", " 107 nan roundabout \n", " 108 nan roundabout \n", " \n", " [109 rows x 27 columns], analysis_config=AnalysisSectionDamages(name='damages_reference_curve_manual', save_gpkg=True, save_csv=True, analysis=, representative_damage_percentage=100, event_type=, damage_curve=, risk_calculation_mode=, risk_calculation_year=0, create_table=False, file_name=None), output_path=WindowsPath('data/damage_manual/output'), _custom_name='damages_reference_curve_manual_link_based'))]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ra2ceHandler.run_with_config_data(network_config_data, analysis_config_data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Output\n", "\n", "The results of the manual damage analysis are provided in **two GeoPackage (GPKG) files**:\n", "\n", "- `damages_reference_curve_manual_link_based.gpkg`: damage estimates per **network link**\n", "- `damages_reference_curve_manual_segment.gpkg`: damage estimates per **100m segment**\n", "\n", "Key attributes of interest (in currency):\n", "\n", "- `dam_EV1_al` : estimated damage for the first flood map (manual method).\n", "- `dam_EV2_al` : estimated damage for the second flood map (manual method).\n", "\n", "You can open these files in GIS software (QGIS, ArcGIS) or load them in Python with GeoPandas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import geopandas as gpd\n", "output_path = root_dir / \"output\" / 'damages'\n", "link_based = gpd.read_file(output_path / \"damages_reference_curve_manual_link_based.gpkg\")\n", "segment_based = gpd.read_file(output_path / \"damages_reference_curve_manual_segmented.gpkg\")\n", "\n", "# Inspect the first rows\n", "print(link_based.head())\n", "print(segment_based.head())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can open the results in GIS software to visualize which road segments are most affected by the hazard." ] } ], "metadata": { "kernelspec": { "display_name": "ra2ce_env", "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.11.13" } }, "nbformat": 4, "nbformat_minor": 5 }