Skip to content

Commit

Permalink
Update documentation.
Browse files Browse the repository at this point in the history
Add guides about:
- Adding new data.
- Doing calculations via request.
- The general workflow.

Signed-off-by: Virginia Morales <[email protected]>
  • Loading branch information
VMarfima committed Aug 1, 2024
1 parent 3074fcd commit 242ceda
Show file tree
Hide file tree
Showing 5 changed files with 346 additions and 0 deletions.
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

0 comments on commit 242ceda

Please sign in to comment.