Skip to content

Commit

Permalink
Merge #1959 into 1.6.x branch (#1963)
Browse files Browse the repository at this point in the history
* Loosen dz scaling application to use the longest forecast period scaling coefficient available if no forecast period has a greater length than the forecast itself.

* Adjustments to doc-strings as per review.
  • Loading branch information
bayliffe authored Nov 3, 2023
1 parent ac901c4 commit 0419260
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 20 deletions.
18 changes: 8 additions & 10 deletions improver/calibration/dz_rescaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,9 @@ def _create_forecast_period_constraint(
"""Create a forecast period constraint to identify the most appropriate
forecast period from the scaled_dz to extract. The most appropriate scaled dz
is selected by choosing the nearest forecast period that is greater than or
equal to the forecast period of the forecast.
equal to the forecast period of the forecast. If no forecast periods in the
scaled dz cube are greater than the forecast period of the forecast, the
longest available forecast period is used.
Args:
forecast: Forecast to be adjusted using dz rescaling.
Expand All @@ -391,16 +393,12 @@ def _create_forecast_period_constraint(
- forecast.coord("forecast_period").points
)

if not any(fp_diff >= 0):
(fp_hour,) = forecast.coord("forecast_period").points / SECONDS_IN_HOUR
msg = (
"There is no scaled version of the difference in altitude for "
f"a forecast period greater than or equal to {fp_hour}"
)
raise ValueError(msg)
if any(fp_diff >= 0):
fp_index = np.argmax(fp_diff >= 0)
chosen_fp = scaled_dz.coord("forecast_period").points[fp_index]
else:
chosen_fp = scaled_dz.coord("forecast_period").points[-1]

fp_index = np.argmax(fp_diff >= 0)
chosen_fp = scaled_dz.coord("forecast_period").points[fp_index]
return iris.Constraint(forecast_period=chosen_fp)

@staticmethod
Expand Down
6 changes: 4 additions & 2 deletions improver/cli/apply_dz_rescaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ def process(
forecast period and forecast reference_time_hour pair within the
rescaling cube are chosen using the forecast reference time hour from
the forecast and the nearest forecast period that is greater than or
equal to the forecast period of the forecast. This cube is generated
using the estimate_dz_rescaling CLI.
equal to the forecast period of the forecast. However, if the forecast
period of the forecast exceeds all forecast periods within the rescaling
cube, the scaling factor from the maximum forecast period is used.
This cube is generated using the estimate_dz_rescaling CLI.
site_id_coord (str):
The name of the site ID coordinate. This defaults to 'wmo_id'.
Expand Down
18 changes: 10 additions & 8 deletions improver_tests/calibration/dz_rescaling/test_apply_dz_rescaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def _create_scaling_factor_cube(


@pytest.mark.parametrize("wmo_id", [True, False])
@pytest.mark.parametrize("forecast_period", [6, 18])
@pytest.mark.parametrize("forecast_period", [6, 18, 30])
@pytest.mark.parametrize("frt_hour", [3, 12])
@pytest.mark.parametrize("scaling_factor", [0.99, 1.01])
@pytest.mark.parametrize("forecast_period_offset", [0, -1, -5])
Expand All @@ -177,9 +177,11 @@ def test_apply_dz_rescaling(
contains the scaling_factor value.
forecast_period_offset (hours) adjusts the forecast period coord on the forecast
cube to ensure the plugin always snaps to the next largest forecast_time when the
precise point is not available.
precise point is not available except when the forecast period of the forecast
exceeds all forecast periods within the scaling factor cube. In this case, the
last forecast period within the scaling factor cube will be used.
frt_hour_offset (hours) alters the forecast reference time hour within the forecast
whilst the forececast reference time hour of the scaling factor remains the same.
whilst the forecast reference time hour of the scaling factor remains the same.
This checks that the a mismatch in the forecast reference time hour can still
result in a match, if a leniency is specified.
"""
Expand All @@ -199,8 +201,11 @@ def test_apply_dz_rescaling(
forecast_period + forecast_period_offset,
forecast,
)
# Use min(fp, 24) here to ensure that the scaling cube contains
# the scaling factor for the last forecast_period if the specified
# forecast period is beyond the T+24 limit of the scaling cube.
scaling_factor = _create_scaling_factor_cube(
frt_hour, forecast_period, scaling_factor
frt_hour, min(forecast_period, 24), scaling_factor
)

kwargs = {}
Expand Down Expand Up @@ -275,10 +280,7 @@ def test_mismatching_sites():

@pytest.mark.parametrize(
"forecast_period,frt_hour,exception",
[
(25, 3, "forecast period greater than or equal to 25"),
(7, 1, "forecast reference time hour equal to 1"),
],
[(7, 1, "forecast reference time hour equal to 1")],
)
def test_no_appropriate_scaled_dz(forecast_period, frt_hour, exception):
"""Test an exception is raised if no appropriate scaled version of the difference
Expand Down

0 comments on commit 0419260

Please sign in to comment.