Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge #1959 into 1.6.x branch #1963

Merged
merged 2 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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