Skip to content

Commit

Permalink
Add new hazards, changes related to threshold-based indicators and do…
Browse files Browse the repository at this point in the history
…c update. (os-climate#224)

In addition to inventory update, includes update to methodology doc and changes needed to support threshold-based indicators (i.e. multiple hazard indicator thresholds in same array) in API and UI. Improve handling of missing maps for UI. 
---------

Signed-off-by: Joe Moorhouse <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
joemoorhouse and pre-commit-ci[bot] authored Feb 28, 2024
1 parent b63a1e7 commit 90a22fc
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 101 deletions.
Binary file modified methodology/PhysicalRiskMethodology.pdf
Binary file not shown.
190 changes: 137 additions & 53 deletions methodology/PhysicalRiskMethodology.tex

Large diffs are not rendered by default.

21 changes: 17 additions & 4 deletions methodology/PhysicalRiskMethodologyBibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ @book{Nelsen:2007
address = {New York~(NY)}
}

% TemperatureAndTheAllocationofTime
@article{NeidellEtAl:2014,
title={Temperature and the Allocation of Time: Implications for Climate Change},
author={Matthew Neidell, Joshua Graff Zivin},
Expand All @@ -214,12 +213,15 @@ @article{NeidellEtAl:2014
publisher={The University of Chicago Press on behalf of the Society of Labor Economists and the NORC at the University of Chicago}
}

% TemperatureAndWork
@article{NeidellEtAl:2021,
title={Temperature and work: Time allocated to work under varying climate and labor market conditions},
author={Matthew Neidell, Joshua Graff Zivin, Megan Sheahan, Jacqueline Willwerth, Charles Fant, Marcus Sarofim, Jeremy Martinich},
journal={PLOS ONE},
author={Neidell, Matthew and Graff Zivin, Joshua and Sheahan, Megan and Willwerth, Jacqueline and Fant, Charles and Sarofim, Marcus and Martinich, Jeremy},
journal={PloS one},
volume={16},
number={8},
pages={e0254224},
year={2021},
publisher={Public Library of Science San Francisco, CA USA}
}

@misc{OasisFinancialModule,
Expand Down Expand Up @@ -256,6 +258,17 @@ @article{RangerEtAl:2022
publisher={Washington, DC: World Bank}
}

@article{RaschkeEtAl:2022,
title={About the return period of a catastrophe},
author={Raschke, Mathias},
journal={Natural Hazards and Earth System Sciences},
volume={22},
number={1},
pages={245--263},
year={2022},
publisher={Copernicus GmbH}
}

@book{ReisingerEtAl:2020,
title={The Concept of Risk in the IPCC Sixth Assessment Report: A Summary of Cross-Working Group Discussions},
author={Reisinger, Andy and Howden, Mark and Vera, Carolina and others},
Expand Down
21 changes: 18 additions & 3 deletions src/physrisk/api/v1/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,25 @@ class Countries(BaseModel):


class IntensityCurve(BaseModel):
"""Intensity curve of an acute hazard."""
"""Hazard indicator intensity curve. Acute hazards are parameterized by event intensities and
return periods in years. Chronic hazards are parameterized by a set of index values.
Index values are defined per indicator."""

intensities: List[float]
return_periods: List[float]
intensities: List[float] = Field([], description="Hazard indicator intensities.")
return_periods: Optional[List[float]] = Field(
[], description="[Deprecated] Return period in years in the case of an acute hazard."
)
index_values: Optional[List[float]] = Field(
[],
description="Set of index values. \
This is return period in years in the case of an acute hazard or \
a set of indicator value thresholds in the case of a multi-threshold chronic hazard.",
)
index_name: str = Field(
"",
description="Name of the index. In the case of an acute hazard this is 'return period'; \
for a multi-threshold chronic hazard this is 'threshold'.",
)


class ExceedanceCurve(BaseModel):
Expand Down
9 changes: 8 additions & 1 deletion src/physrisk/data/image_creator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io
import logging
from functools import lru_cache
from pathlib import PurePosixPath
from typing import Callable, List, NamedTuple, Optional
Expand All @@ -10,6 +11,8 @@
from physrisk.data import colormap_provider
from physrisk.data.zarr_reader import ZarrReader

logger = logging.getLogger(__name__)


class Tile(NamedTuple):
x: int
Expand Down Expand Up @@ -46,7 +49,11 @@ def convert(
Returns:
bytes: Image data.
"""
image = self._to_image(path, colormap, tile=tile, min_value=min_value, max_value=max_value)
try:
image = self._to_image(path, colormap, tile=tile, min_value=min_value, max_value=max_value)
except Exception as e:
logger.exception(e)
image = Image.fromarray(np.array([[0]]), mode="RGBA")
image_bytes = io.BytesIO()
image.save(image_bytes, format=format)
return image_bytes.getvalue()
Expand Down
137 changes: 104 additions & 33 deletions src/physrisk/data/static/hazard/inventory.json

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions src/physrisk/kernel/vulnerability_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def get_data_requests(
) -> Union[HazardDataRequest, Iterable[HazardDataRequest]]: ...


class EventBased(Protocol):
def impact_samples(self, asset: Asset, data_responses: Iterable[HazardDataResponse]) -> np.ndarray:
# event-based models generate impact samples based on events received by the hazard model
# the events may be in the form of an array of severities in the form of return periods.
...


class VulnerabilityModelBase(ABC, DataRequester):
def __init__(self, indicator_id: str, hazard_type: type, impact_type: ImpactType):
self.indicator_id = indicator_id
Expand Down Expand Up @@ -112,20 +119,20 @@ def get_distributions(
"""
...

def get_impact(self, asset: Asset, event_data_responses: Iterable[HazardDataResponse]):
impact, _, _ = self.get_impact_details(asset, event_data_responses)
def get_impact(self, asset: Asset, data_responses: Iterable[HazardDataResponse]):
impact, _, _ = self.get_impact_details(asset, data_responses)
return impact

def get_impact_details(
self, asset: Asset, event_data_responses: Iterable[HazardDataResponse]
self, asset: Asset, data_responses: Iterable[HazardDataResponse]
) -> Tuple[ImpactDistrib, VulnerabilityDistrib, HazardEventDistrib]:
"""Return impact distribution along with vulnerability and hazard event distributions used to infer this.
Args:
asset: the asset.
event_data_responses: the responses to the requests made by get_data_requests, in the same order.
"""
vulnerability_dist, event_dist = self.get_distributions(asset, event_data_responses)
vulnerability_dist, event_dist = self.get_distributions(asset, data_responses)
impact_prob = vulnerability_dist.prob_matrix.T @ event_dist.prob
return (
ImpactDistrib(
Expand Down
16 changes: 13 additions & 3 deletions src/physrisk/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,22 @@ def _get_hazard_data(request: HazardDataRequest, hazard_model: HazardModel):
resps = (response_dict[req] for req in requests)
intensity_curves = [
(
IntensityCurve(intensities=list(resp.intensities), return_periods=list(resp.return_periods))
IntensityCurve(
intensities=list(resp.intensities),
index_values=list(resp.return_periods),
index_name="return period",
return_periods=[],
)
if isinstance(resp, hmHazardEventDataResponse)
else (
IntensityCurve(intensities=list(resp.parameters), return_periods=list(resp.param_defns))
IntensityCurve(
intensities=list(resp.parameters),
index_values=list(resp.param_defns),
index_name="threshold",
return_periods=[],
)
if isinstance(resp, HazardParameterDataResponse)
else IntensityCurve(intensities=[], return_periods=[])
else IntensityCurve(intensities=[], index_values=[], index_name="", return_periods=[])
)
)
for resp in resps
Expand Down

0 comments on commit 90a22fc

Please sign in to comment.