Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Virginia Morales <[email protected]>
  • Loading branch information
VMarfima committed Sep 23, 2024
1 parent 3074fcd commit 8d163dc
Show file tree
Hide file tree
Showing 5 changed files with 408 additions and 7 deletions.
34 changes: 34 additions & 0 deletions docs/add_new_data.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
HOW TO ADD NEW DATA
===================

Adding new hazards
------------------

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.

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.

Adding new vulnerability models
-------------------------------

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.
In the ``DictBasedVulnerabilityModelsFactory`` class there is a ``vulnerability_models`` method which 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``

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.

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.

- 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.
- 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``.

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``.


Adding new risk models
----------------------

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.

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 order to do so in this class there is a method called ``calculators`` which makes use of ``get_default_risk_measure_calculators`` , ``get_default_risk_measure_calculators`` and ``get_default_risk_measure_calculators``, implemented in ``src/physrisk/kernel/calculation.py``.

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.
100 changes: 100 additions & 0 deletions docs/calculations_via_requests.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
CONTAINER AND REQUEST USAGE GUIDE
=================================

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``.

Process
-------

1. Create a Container

First, create a ``Container`` object and configure it by overriding its default providers with custom ones. Here’s an example:

.. code-block:: python
# Define custom factories for hazard and vulnerability models
class TestHazardModelFactory(HazardModelFactory):
def hazard_model(self, interpolation: str = "floor", provider_max_requests: Dict[str, int] = ...):
return ZarrHazardModel(
source_paths=get_default_source_paths(), reader=reader
)
class TestVulnerabilityModelFactory(VulnerabilityModelsFactory):
def vulnerability_models(self):
return DictBasedVulnerabilityModels(
{
ThermalPowerGeneratingAsset: [
ThermalPowerGenerationAqueductWaterStressModel()
]
}
)
# Register custom providers in the container
container.override_providers(
hazard_model_factory=providers.Factory(TestHazardModelFactory)
)
container.override_providers(
config=providers.Configuration(default={"zarr_sources": ["embedded"]})
)
container.override_providers(inventory_reader=ZarrReader())
container.override_providers(zarr_reader=ZarrReader())
container.override_providers(
vulnerability_models_factory=providers.Factory(TestVulnerabilityModelFactory)
)
You can include any list of vulnerability models in the configuration. If none are provided, default models will be used.

2. Create a Requester

After setting up the container, call ``container.requester()`` to obtain an instance of ``Requester``. This object includes the following attributes configured from the container:
``hazard_model_factory: HazardModelFactory, vulnerability_models_factory: VulnerabilityModelsFactory, inventory: Inventory, inventory_reader: InventoryReader, reader: ZarrReader, colormaps: Colormaps`` and a ``measures_factory: RiskMeasuresFactory``

3. Call the Method and Obtain a Response

The ``Requester`` class has a main method that calls different methods based on the ``request_id`` provided.

Here is an example of how to call a method using the ``get`` method:

.. code-block:: python
res = requester.get(request_id="get_asset_impact", request_dict=request_dict)
You can assign the following values to ``request_id``:

- ``get_hazard_data``: Returns intensity curves for the selected hazards, years, and scenarios.
- ``get_hazard_availability``: Returns the hazards stored in the inventory.
- ``get_hazard_description``: Returns the description assigned to a specific hazard.
- ``get_asset_exposure``: Calculates the exposure of a given asset for a hazard, exposure measure, scenario, and year.
- ``get_asset_impact``: Returns risk measures or impacts based on parameters provided in ``request_dict``.
- ``get_example_portfolios``: Returns a JSON with assets and their respective details such as class, type, location, latitude, and longitude.

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:

.. code-block:: python
def create_assets_json(assets: Sequence[ThermalPowerGeneratingAsset]):
assets_dict = {
"items": [
{
"asset_class": type(asset).__name__,
"type": asset.type,
"location": asset.location,
"longitude": asset.longitude,
"latitude": asset.latitude,
}
for asset in assets
],
}
return assets_dict
request_dict = {
"assets": create_assets_json(assets=assets),
"include_asset_level": False,
"include_measures": True,
"include_calc_details": False,
"model_kind": ModelKind.STRESS_TEST,
"years": years,
"scenarios": scenarios,
}
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.
Loading

0 comments on commit 8d163dc

Please sign in to comment.