Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
66 changes: 66 additions & 0 deletions climada/hazard/forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,69 @@

Define Forecast variant of Hazard.
"""

import logging

import numpy as np

from climada.hazard.base import Hazard
from climada.util.forecast import Forecast

LOGGER = logging.getLogger(__name__)


class HazardForecast(Forecast, Hazard):

def __init__(
self,
lead_time: np.ndarray | None = None,
member: np.ndarray | None = None,
**hazard_kwargs,
):
"""
Initialize a HazardForecast object.

Parameters
----------
lead_time : np.ndarray of np.datetime64 or None, optional
Forecast lead times. Default is empty array.
member : np.ndarray or None, optional
Ensemble member identifiers as integers. Default is empty array.
**hazard_kwargs
keyword arguments to pass to Hazard.__init__. See Hazard.__init__
docstring for details.
"""
super().__init__(lead_time=lead_time, member=member, **hazard_kwargs)
Comment thread
peanutfun marked this conversation as resolved.
Outdated

@classmethod
def from_hazard(cls, hazard: Hazard, lead_time: np.ndarray, member: np.ndarray):
"""
Create a HazardForecast object from a Hazard object.

Parameters
----------
hazard : Hazard
Hazard object to convert into a HazardForecast.

Returns
-------
HazardForecast
A HazardForecast object with the same attributes as the input hazard,
but with lead_time and member attributes set from instance of HazardForecast.
"""
return cls(
lead_time=lead_time,
member=member,
haz_type=hazard.haz_type,
pool=hazard.pool,
units=hazard.units,
centroids=hazard.centroids,
event_id=hazard.event_id,
frequency=hazard.frequency,
frequency_unit=hazard.frequency_unit,
event_name=hazard.event_name,
date=hazard.date,
orig=hazard.orig,
intensity=hazard.intensity,
fraction=hazard.fraction,
)
42 changes: 22 additions & 20 deletions climada/hazard/test/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,29 @@
"""


def hazard_kwargs():
return {
"haz_type": "TC",
"pool": None,
"intensity": sparse.csr_matrix(
[[0.2, 0.3, 0.4], [0.1, 0.1, 0.01], [4.3, 2.1, 1.0], [5.3, 0.2, 0.0]]
),
"fraction": sparse.csr_matrix(
[[0.02, 0.03, 0.04], [0.01, 0.01, 0.01], [0.3, 0.1, 0.0], [0.3, 0.2, 0.0]]
),
"centroids": Centroids(lat=np.array([1, 3, 5]), lon=np.array([2, 4, 6])),
"event_id": np.array([1, 2, 3, 4]),
"event_name": ["ev1", "ev2", "ev3", "ev4"],
"date": np.array([1, 2, 3, 4]),
"orig": np.array([True, False, False, True]),
"frequency": np.array([0.1, 0.5, 0.5, 0.2]),
"frequency_unit": "1/week",
"units": "m/s",
}


def dummy_hazard():
fraction = sparse.csr_matrix(
[[0.02, 0.03, 0.04], [0.01, 0.01, 0.01], [0.3, 0.1, 0.0], [0.3, 0.2, 0.0]]
)
intensity = sparse.csr_matrix(
[[0.2, 0.3, 0.4], [0.1, 0.1, 0.01], [4.3, 2.1, 1.0], [5.3, 0.2, 0.0]]
)

return Hazard(
"TC",
intensity=intensity,
fraction=fraction,
centroids=Centroids(lat=np.array([1, 3, 5]), lon=np.array([2, 4, 6])),
event_id=np.array([1, 2, 3, 4]),
event_name=["ev1", "ev2", "ev3", "ev4"],
date=np.array([1, 2, 3, 4]),
orig=np.array([True, False, False, True]),
frequency=np.array([0.1, 0.5, 0.5, 0.2]),
frequency_unit="1/week",
units="m/s",
)
return Hazard(**hazard_kwargs())


class TestLoader(unittest.TestCase):
Expand Down
77 changes: 76 additions & 1 deletion climada/hazard/test/test_forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,88 @@
Tests for Hazard Forecast.
"""

import numpy as np
import numpy.testing as npt
import pytest

from climada.hazard import Hazard
from climada.hazard.base import Hazard
from climada.hazard.forecast import HazardForecast
from climada.hazard.test.test_base import hazard_kwargs

# --- Examples for fixtures and test organization --- #


@pytest.fixture
def haz_kwargs():
return hazard_kwargs()


@pytest.fixture
def dummy_hazard(haz_kwargs):
return Hazard(**haz_kwargs)


def test_init_hazard_forecast(haz_kwargs):
haz_fc = HazardForecast(
lead_time=np.array(
["2024-01-01T00:00:00", "2024-01-01T00:01:00"], dtype="datetime64[s]"
),
member=np.array([0, 1]),
**haz_kwargs,
)
assert isinstance(haz_fc, HazardForecast)
npt.assert_array_equal(
haz_fc.lead_time,
np.array(["2024-01-01T00:00:00", "2024-01-01T00:01:00"], dtype="datetime64[s]"),
)
assert haz_fc.lead_time.dtype == "datetime64[s]"
npt.assert_array_equal(haz_fc.member, np.array([0, 1]))
assert haz_fc.haz_type == haz_kwargs["haz_type"]
assert haz_fc.pool == haz_kwargs["pool"]
assert haz_fc.units == haz_kwargs["units"]
assert haz_fc.centroids == haz_kwargs["centroids"]
npt.assert_array_equal(haz_fc.event_id, haz_kwargs["event_id"])
npt.assert_array_equal(haz_fc.frequency, haz_kwargs["frequency"])
assert haz_fc.frequency_unit == haz_kwargs["frequency_unit"]
npt.assert_array_equal(haz_fc.event_name, haz_kwargs["event_name"])
npt.assert_array_equal(haz_fc.date, haz_kwargs["date"])
npt.assert_array_equal(haz_fc.orig, haz_kwargs["orig"])
npt.assert_array_equal(
haz_fc.intensity.todense(), haz_kwargs["intensity"].todense()
)
npt.assert_array_equal(haz_fc.fraction.todense(), haz_kwargs["fraction"].todense())


def test_from_hazard(dummy_hazard):
lead_time = np.array(
["2024-01-01T00:00:00", "2024-01-01T00:01:00"], dtype="datetime64[s]"
)
member = np.array([0, 1])
haz_fc_from_haz = HazardForecast.from_hazard(
dummy_hazard, lead_time=lead_time, member=member
)

assert isinstance(haz_fc_from_haz, HazardForecast)
npt.assert_array_equal(haz_fc_from_haz.lead_time, lead_time)
npt.assert_array_equal(haz_fc_from_haz.member, member)
assert haz_fc_from_haz.haz_type == dummy_hazard.haz_type
assert haz_fc_from_haz.pool == dummy_hazard.pool
assert haz_fc_from_haz.units == dummy_hazard.units
assert haz_fc_from_haz.centroids == dummy_hazard.centroids
npt.assert_array_equal(haz_fc_from_haz.event_id, dummy_hazard.event_id)
npt.assert_array_equal(haz_fc_from_haz.frequency, dummy_hazard.frequency)
assert haz_fc_from_haz.frequency_unit == dummy_hazard.frequency_unit
npt.assert_array_equal(haz_fc_from_haz.event_name, dummy_hazard.event_name)
npt.assert_array_equal(haz_fc_from_haz.date, dummy_hazard.date)
npt.assert_array_equal(haz_fc_from_haz.orig, dummy_hazard.orig)
npt.assert_array_equal(
haz_fc_from_haz.intensity.todense(), dummy_hazard.intensity.todense()
)
npt.assert_array_equal(
haz_fc_from_haz.fraction.todense(), dummy_hazard.fraction.todense()
)


@pytest.fixture
def hazard():
return Hazard()
Expand Down
Loading