Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation #354

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/user-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ The following sections document the structures and conventions of Physrisk and a

user-guide/introduction
user-guide/vulnerability_config
user-guide/general_workflow
user-guide/add_new_data
user-guide/calculations_via_request
47 changes: 47 additions & 0 deletions docs/user-guide/add_new_data.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# HOW TO ADD NEW DATA\n",
"\n",
"## Adding new hazards\n",
"\n",
"In `src/physrisk/kernel/hazards.py`, all hazards are cataloged, classified as ACUTE, CHRONIC, or UNKNOWN, and designated as either parameter-based or event-based. To add a new hazard, create a new class within this file and specify its type.\n",
"\n",
"Additionally, complete the onboarding process for the new hazard in the hazard program. This step ensures that the hazard and its data are collected in the bucket and included in the inventory used by PhysRisk to calculate impacts and risk measures.\n",
"\n",
"## Adding new vulnerability models\n",
"\n",
"In the `src/physrisk/vulnerability_models` folder, files correspond to each vulnerability model (e.g., `chronic_heat_models`, `power_generating_asset_models`, `real_estate_models`, `thermal_power_generation_models`). Each file contains classes for each type of hazard, with separate classes for default and stress test calculations. The `DictBasedVulnerabilityModelsFactory`, which inherits from the `VulnerabilityModelsFactory` class in `src/physrisk/kernel/vulnerability_model.py`, is used to handle the different vulnerability models, whether they are default or stress test models.\n",
"\n",
"In the `DictBasedVulnerabilityModelsFactory` class, there is a `vulnerability_models` method that retrieves the corresponding vulnerability models using the methods `get_default_vulnerability_models` and `get_stress_test_vulnerability_models`, implemented in `src/physrisk/kernel/calculation.py`.\n",
"\n",
"To add a vulnerability model for a new asset type, create a new file with the corresponding vulnerability classes for each hazard type. Additionally, create a JSON file in the `src/physrisk/datas/static/vulnerability` folder. This JSON file should include the vulnerability curves for these models, detailing `impact_mean`, `impact_std`, `impact_type`, `impact_units`, `intensity`, `intensity_units`, and `location` for each type of event (hazard) and asset.\n",
"\n",
"For adding a vulnerability model for an existing asset, create a new class in the relevant file. All classes must inherit from either a class in `src/physrisk/kernel/vulnerability_model.py` or another class in the same file that inherits from a class in `vulnerability_model.py`. These classes must include at least a constructor, a `get_data_requests` method, and a `get_impact` method.\n",
"\n",
"- The `get_data_requests` method returns an `HazardDataRequest` object, which stores all necessary information to request data from the bucket for calculating impacts and risk measures.\n",
"- The `get_impact` method returns an `ImpactDistrib` object, which contains \"Impact distributions specific to an asset\" and is used for calculating `impact_bins_explicit`, `mean_impact`, `stddev_impact`, `above_mean_stddev_impact`, and `to_exceedance_curve`.\n",
"\n",
"To include the new vulnerability model, update either `get_default_vulnerability_models` or `get_stress_test_vulnerability_models` as appropriate. If introducing a new calculation method, add a new method and integrate it into `DictBasedVulnerabilityModelsFactory`. \n",
"\n",
"## Adding new risk models\n",
"\n",
"In `src/physrisk/risk_models/risk_models.py`, there are three classes that implement risk models: `RealEstateToyRiskMeasures` (which calculates risk measures using exceedance curves), `ThermalPowerPlantsRiskMeasures` (which calculates risk measures using mean intensity and percentiles). Additionally, in `src/physrisk/risk_models/generic_risk_model.py`, the `GenericScoreBasedRiskMeasures` class showcases how different approaches can be combined for calculating risk scores, using vulnerability models for some hazards and direct hazard indicators for others. This generic implementation serves as an example, blending elements from both real estate and Jupiter exposure calculations, without a predefined use case for the measures.\n",
"\n",
"Moreover, similar to the vulnerability models, a factory class `DefaultMeasuresFactory` has been implemented in `src/physrisk/kernel/calculation.py` to select the appropriate risk model based on the `use_case_id`. In this class, there is a method called `calculators` which makes use of `get_default_risk_measure_calculators`, `get_stress_test_risk_measure_calculators`, and `get_default_risk_measure_calculators`, implemented in `src/physrisk/kernel/calculation.py`.\n",
"\n",
"To add new risk models, you need to create a new class in the risk_models file that implements the calculations for the new model.\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
117 changes: 117 additions & 0 deletions docs/user-guide/calculations_via_requests.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# CONTAINER AND REQUEST USAGE GUIDE\n",
"\n",
"In addition to invoking methods directly, as detailed in the `general_workflow.md` guide, you can perform various actions or calculations through requests. For examples of this approach, see `tests/risk_models/risk_models_AK_test.py` and `tests/risk_models/risk_models_test.py`.\n",
"\n",
"## Process\n",
"\n",
"1. **Create a Container**\n",
"\n",
" First, create a `Container` object and configure it by overriding its default providers with custom ones. Here’s an example:\n",
"\n",
" ```python\n",
" # Define custom factories for hazard and vulnerability models\n",
" class TestHazardModelFactory(HazardModelFactory):\n",
" def hazard_model(self, interpolation: str = \"floor\", provider_max_requests: Dict[str, int] = ...):\n",
" return ZarrHazardModel(\n",
" source_paths=get_default_source_paths(), reader=reader\n",
" )\n",
"\n",
" class TestVulnerabilityModelFactory(VulnerabilityModelsFactory):\n",
" def vulnerability_models(self):\n",
" return DictBasedVulnerabilityModels(\n",
" {\n",
" ThermalPowerGeneratingAsset: [\n",
" ThermalPowerGenerationAqueductWaterStressModel()\n",
" ]\n",
" }\n",
" )\n",
"\n",
" # Register custom providers in the container\n",
" container.override_providers(\n",
" hazard_model_factory=providers.Factory(TestHazardModelFactory)\n",
" )\n",
" container.override_providers(\n",
" config=providers.Configuration(default={\"zarr_sources\": [\"embedded\"]})\n",
" )\n",
" container.override_providers(inventory_reader=ZarrReader())\n",
" container.override_providers(zarr_reader=ZarrReader())\n",
" container.override_providers(\n",
" vulnerability_models_factory=providers.Factory(TestVulnerabilityModelFactory)\n",
" )\n",
"\n",
" ``` \n",
" You can include any list of vulnerability models in the configuration. If none are provided, default models will be used.\n",
"\n",
"\n",
"2. **Create a Requester**\n",
"\n",
" After setting up the container, call ``container.requester()`` to obtain an instance of ``Requester``. This object includes the following attributes configured from the container:\n",
" ``hazard_model_factory: HazardModelFactory, vulnerability_models_factory: VulnerabilityModelsFactory, inventory: Inventory, inventory_reader: InventoryReader, reader: ZarrReader, colormaps: Colormaps`` and a ``measures_factory: RiskMeasuresFactory``\n",
" \n",
"\n",
"3. **Call the Method and Obtain a Response**\n",
"\n",
" The `Requester` class has a main method that calls different methods based on the `request_id` provided.\n",
"\n",
" Here is an example of how to call a method using the `get` method:\n",
"\n",
" ```python\n",
" res = requester.get(request_id=\"get_asset_impact\", request_dict=request_dict)\n",
" ```\n",
"\n",
" You can assign the following values to `request_id`:\n",
"\n",
" - `get_hazard_data`: Returns intensity curves for the selected hazards, years, and scenarios.\n",
" - `get_hazard_availability`: Returns the hazards stored in the inventory.\n",
" - `get_hazard_description`: Returns the description assigned to a specific hazard.\n",
" - `get_asset_exposure`: Calculates the exposure of a given asset for a hazard, exposure measure, scenario, and year.\n",
" - `get_asset_impact`: Returns risk measures or impacts based on parameters provided in `request_dict`.\n",
" - `get_example_portfolios`: Returns a JSON with assets and their respective details such as class, type, location, latitude, and longitude.\n",
"\n",
" The structure of `request_dict` depends on the method you are calling. For example, for the `get_asset_impact` method, `request_dict` might look like this:\n",
"\n",
" ```python\n",
" def create_assets_json(assets: Sequence[ThermalPowerGeneratingAsset]):\n",
" assets_dict = {\n",
" \"items\": [\n",
" {\n",
" \"asset_class\": type(asset).__name__,\n",
" \"type\": asset.type,\n",
" \"location\": asset.location,\n",
" \"longitude\": asset.longitude,\n",
" \"latitude\": asset.latitude,\n",
" }\n",
" for asset in assets\n",
" ],\n",
" }\n",
" return assets_dict\n",
"\n",
" request_dict = {\n",
" \"assets\": create_assets_json(assets=assets),\n",
" \"include_asset_level\": False,\n",
" \"include_measures\": True,\n",
" \"include_calc_details\": False,\n",
" \"model_kind\": ModelKind.STRESS_TEST,\n",
" \"years\": years,\n",
" \"scenarios\": scenarios,\n",
" }\n",
" ```\n",
"\n",
" Finally, the ``get`` method calls the appropriate methods corresponding to the ``request_id`` with the necessary parameters and returns the response as a JSON object with the result."
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading