From e396f6aa7ce0828c1cd40f1bd2d19dadd66761cf Mon Sep 17 00:00:00 2001 From: dgboss Date: Fri, 11 Oct 2024 13:12:11 -0700 Subject: [PATCH] RDPS precip dif can't be negative (#4001) --- .../weather_models/test_precip_rdps_model.py | 22 +++++++++++++++++++ api/app/weather_models/precip_rdps_model.py | 13 ++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/api/app/tests/weather_models/test_precip_rdps_model.py b/api/app/tests/weather_models/test_precip_rdps_model.py index 1ed27c61b..d2b8bdc2c 100644 --- a/api/app/tests/weather_models/test_precip_rdps_model.py +++ b/api/app/tests/weather_models/test_precip_rdps_model.py @@ -32,6 +32,28 @@ def test_difference_identity(): assert np.allclose(res, np.zeros(precip_raster.shape)) +def test_negative_precip_diff_raises_value_error(): + """ + Verify ValueError raised if raster subtraction contains a negative value. + """ + later_precip = TemporalPrecip(datetime.fromisoformat("2024-06-10T18:42:49"), np.zeros(1)) + earlier_precip = TemporalPrecip(datetime.fromisoformat("2024-06-09T18:42:49"), np.ones(1)) + with pytest.raises(ValueError): + compute_precip_difference(later_precip, earlier_precip) + + +def test_trivial_negative_precip_diff_returns_zero(): + """ + Verify that a negative precip dif between -0.01 and 0 returns 0. + """ + early_array = np.empty(1) + early_array[0] = 0.005 + later_precip = TemporalPrecip(datetime.fromisoformat("2024-06-10T18:42:49"), np.zeros(1)) + earlier_precip = TemporalPrecip(datetime.fromisoformat("2024-06-09T18:42:49"), early_array) + result = compute_precip_difference(later_precip, earlier_precip) + assert result[0] == 0 + + @pytest.mark.parametrize( "later_datetime,earlier_datetime", [ diff --git a/api/app/weather_models/precip_rdps_model.py b/api/app/weather_models/precip_rdps_model.py index 6bb252118..c1e2bccc6 100644 --- a/api/app/weather_models/precip_rdps_model.py +++ b/api/app/weather_models/precip_rdps_model.py @@ -141,7 +141,18 @@ def compute_precip_difference(later_precip: TemporalPrecip, earlier_precip: Temp def _diff(value_a: float, value_b: float): - return value_a - value_b + """ + Subtract value_a from value_b. + :param value_a: The first value + :param value_b: The second value + :raises ValueError: If difference is less than -0.01 (ie. negative precip not allowed) + :return: Return value_a minus value_b if the value is >= 0. If the difference is slightly negative (-0.01 <= value < 0), due to floating + point math for example, return 0. If the value is truly negative, raise an error. + """ + result = value_a - value_b + if result < -0.01: + raise ValueError("Precip difference cannot be negative") + return result if result > 0 else 0 vectorized_diff = vectorize(_diff)