Skip to content

Commit

Permalink
Modifies LightningFromCapePrecip plugin to accept 3h precipitation-ra…
Browse files Browse the repository at this point in the history
…te-max data (metoppv#1568)

* Modifies LightningFromCapePrecip plugin to accept 3h precipitation-rate-max data

- We need this so we can generate data for days 6-8 when only 3h data are available.

* First review

- Improves tests and doc-strings

* Black
  • Loading branch information
MoseleyS authored Sep 28, 2021
1 parent fc407e9 commit a44c59e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
13 changes: 7 additions & 6 deletions improver/lightning.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ def _get_inputs(cubes: CubeList) -> Tuple[Cube, Cube]:
"""
Separates CAPE and precipitation rate cubes and checks that the following
match: forecast_reference_time, spatial coords, time-bound interval and
that CAPE time is exactly one hour older than precipitation rate time.
that CAPE time is at the lower bound of precipitation rate time.
The precipitation rate data must represent a period of 1 or 3 hours.
"""
cape = cubes.extract(
iris.Constraint(
Expand All @@ -100,14 +101,14 @@ def _get_inputs(cubes: CubeList) -> Tuple[Cube, Cube]:
raise ValueError(f"No cube named precipitation_rate_max found in {cubes}")
(cape_time,) = list(cape.coord("time").cells())
(precip_time,) = list(precip.coord("time").cells())
if cape_time.point + timedelta(hours=1) != precip_time.point:
if cape_time.point != precip_time.bound[0]:
raise ValueError(
f"CAPE cube time ({cape_time.point}) should be valid one hour earlier "
f"than precipitation_rate_max cube time ({precip_time.point})."
f"CAPE cube time ({cape_time.point}) should be valid at the "
f"precipitation_rate_max cube lower bound ({precip_time.bound[0]})."
)
if np.diff(precip_time.bound) != timedelta(hours=1):
if np.diff(precip_time.bound) not in [timedelta(hours=1), timedelta(hours=3)]:
raise ValueError(
f"Precipitation_rate_max cube time window must be one hour, "
f"Precipitation_rate_max cube time window must be one or three hours, "
f"not {np.diff(precip_time.bound)}."
)
if cape.coord("forecast_reference_time") != precip.coord(
Expand Down
29 changes: 20 additions & 9 deletions improver_tests/lightning/test_LightningFromCapePrecip.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ def test_basic(cape_cube, precip_cube, expected_cube):
assert np.allclose(result.data, expected_cube.data)


def test_3h_cubes(cape_cube, precip_cube, expected_cube):
"""Run the plugin again with 3h cubes"""
cape_cube.coord("time").points = cape_cube.coord("time").points - 2 * 3600
bounds = precip_cube.coord("time").bounds
precip_cube.coord("time").bounds = (bounds[0][0] - 2 * 3600, bounds[0][1])
precip_cube.rename("precipitation_rate_max-PT03H")
expected_cube.coord("time").bounds = (bounds[0][0] - 2 * 3600, bounds[0][1])
result = LightningFromCapePrecip()(CubeList([cape_cube, precip_cube]))
assert result.xml().splitlines(keepends=True) == expected_cube.xml().splitlines(
keepends=True
)
assert np.allclose(result.data, expected_cube.data)


def test_with_model_attribute(cape_cube, precip_cube, expected_cube):
"""Run the plugin with model_id_attr and check the result cube matches the expected_cube"""
expected_cube.attributes["mosg__model_configuration"] = "gl_ens"
Expand All @@ -142,21 +156,18 @@ def test_with_model_attribute(cape_cube, precip_cube, expected_cube):


def break_time_point(cape_cube, precip_cube):
"""Modifies precip_cube time points to be incremented by 1 second and
"""Modifies cape_cube time points to be incremented by 1 second and
returns the error message this will trigger"""
precip_cube.coord("time").points = precip_cube.coord("time").points + 1
return (
r"CAPE cube time .* should be valid one hour earlier than "
r"precipitation_rate_max cube time .*"
)
cape_cube.coord("time").points = cape_cube.coord("time").points + 1
return r"CAPE cube time .* should be valid at the precipitation_rate_max cube lower bound .*"


def break_time_bound(cape_cube, precip_cube):
"""Modifies lower bound on precip_cube time coord to be incremented by 1 second and
"""Modifies upper bound on precip_cube time coord to be incremented by 1 second and
returns the error message this will trigger"""
bounds = precip_cube.coord("time").bounds
precip_cube.coord("time").bounds = (bounds[0][0] + 1, bounds[0][1])
return r"Precipitation_rate_max cube time window must be one hour, not .*"
precip_cube.coord("time").bounds = (bounds[0][0], bounds[0][1] + 1)
return r"Precipitation_rate_max cube time window must be one or three hours, not .*"


def break_reference_time(cape_cube, precip_cube):
Expand Down

0 comments on commit a44c59e

Please sign in to comment.