From 503d45fdb881beec8766ba08b527c0bb7dca3a5c Mon Sep 17 00:00:00 2001 From: Joern Ungermann Date: Mon, 30 Mar 2020 12:43:12 +0200 Subject: [PATCH] Fixed a problem with diff'ing masked_arrays with units. The issue occurs only, when "x" in first_derivative is a masked array with units. As all arrays stemming from NetCDF access are basically masked arrays, we do not have non-masked arrays in our code, even though the mask is almost always 'False'. I added a test case demonstrating the problem, it fails without the contained fix. See issue #983 --- src/metpy/units.py | 2 +- tests/calc/test_calc_tools.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/metpy/units.py b/src/metpy/units.py index 1059ef42a62..f2e8a568bdc 100644 --- a/src/metpy/units.py +++ b/src/metpy/units.py @@ -175,7 +175,7 @@ def diff(x, **kwargs): # Can't just use units because of how things like temperature work it = x.flat true_units = (next(it) - next(it)).units - return ret * true_units + return true_units * ret else: return np.diff(x, **kwargs) diff --git a/tests/calc/test_calc_tools.py b/tests/calc/test_calc_tools.py index 3a9d502efe3..bd9419dc010 100644 --- a/tests/calc/test_calc_tools.py +++ b/tests/calc/test_calc_tools.py @@ -560,6 +560,20 @@ def test_first_derivative_masked(): assert_array_equal(df_dx.mask, truth.mask) +def test_first_derivative_masked_units(): + """Test that first_derivative properly propagates masks with units.""" + data = units('K') * np.ma.arange(7) + data[3] = np.ma.masked + x = units('m') * np.ma.arange(7) + df_dx = first_derivative(data, x=x) + + truth = units('K / m') * np.ma.array( + [1., 1., 1., 1., 1., 1., 1.], + mask=[False, False, True, True, True, False, False]) + assert_array_almost_equal(df_dx, truth) + assert_array_equal(df_dx.mask, truth.mask) + + def test_second_derivative(deriv_1d_data): """Test second_derivative with a simple 1D array.""" d2v_dx2 = second_derivative(deriv_1d_data.values, x=deriv_1d_data.x)