From b727f48f794bd33754743ce473e302e24b67c0e5 Mon Sep 17 00:00:00 2001 From: zbruick Date: Wed, 21 Aug 2019 13:22:40 -0600 Subject: [PATCH 1/2] Add unit support for `reduce_point_density`. Assumes meters if none are provided. --- metpy/calc/tests/test_calc_tools.py | 15 +++++++++++++++ metpy/calc/tools.py | 11 ++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/metpy/calc/tests/test_calc_tools.py b/metpy/calc/tests/test_calc_tools.py index ac222ac782d..b9f46f41fbf 100644 --- a/metpy/calc/tests/test_calc_tools.py +++ b/metpy/calc/tests/test_calc_tools.py @@ -158,6 +158,21 @@ def test_reduce_point_density(thin_point_data, radius, truth): assert_array_equal(reduce_point_density(thin_point_data, radius=radius), truth) +@pytest.mark.parametrize('radius, truth', + [(2.0, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), + (1.0, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), + (0.3, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), + (0.1, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], dtype=np.bool)) + ]) +def test_reduce_point_density_units(thin_point_data, radius, truth): + r"""Test that reduce_point_density works with units.""" + assert_array_equal(reduce_point_density(thin_point_data, radius=radius * units.dam), truth) + + @pytest.mark.parametrize('radius, truth', [(2.0, np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], dtype=np.bool)), diff --git a/metpy/calc/tools.py b/metpy/calc/tools.py index f3997465f39..1981ad51dbb 100644 --- a/metpy/calc/tools.py +++ b/metpy/calc/tools.py @@ -259,14 +259,15 @@ def reduce_point_density(points, radius, priority=None): data), returning a mask that can be used to select the points from one or more arrays (e.g. arrays of temperature and dew point). The points selected can be controlled by providing an array of ``priority`` values (e.g. rainfall totals to ensure that - stations with higher precipitation remain in the mask). + stations with higher precipitation remain in the mask). The radius can be specified + as a `pint.Quantity` with units. If none are provided, meters are assumed. Parameters ---------- points : (N, K) array-like N locations of the points in K dimensional space - radius : float - minimum radius allowed between points + radius : `pint.Quantity` or float + Minimum radius allowed between points. If units are not provided, meters is assumed. priority : (N, K) array-like, optional If given, this should have the same shape as ``points``; these values will be used to control selection priority for points. @@ -285,6 +286,10 @@ def reduce_point_density(points, radius, priority=None): array([False, True, False]) """ + # Handle a radius with units. Assume meters if units are not specified + if hasattr(radius, 'units'): + radius = radius.to('m').m + # Handle 1D input if points.ndim < 2: points = points.reshape(-1, 1) From ce0f3565d771e4f0c6886796152d67571992d695 Mon Sep 17 00:00:00 2001 From: zbruick Date: Mon, 26 Aug 2019 09:30:09 -0600 Subject: [PATCH 2/2] Add unit support for point in reduce_point_density --- metpy/calc/tests/test_calc_tools.py | 13 +++++++------ metpy/calc/tools.py | 13 ++++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/metpy/calc/tests/test_calc_tools.py b/metpy/calc/tests/test_calc_tools.py index b9f46f41fbf..96308ff13bc 100644 --- a/metpy/calc/tests/test_calc_tools.py +++ b/metpy/calc/tests/test_calc_tools.py @@ -162,15 +162,16 @@ def test_reduce_point_density(thin_point_data, radius, truth): [(2.0, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), (1.0, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), - (0.3, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool)), - (0.1, np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], dtype=np.bool)) + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], dtype=np.bool)), + (0.3, np.array([1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], dtype=np.bool)), + (0.1, np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=np.bool)) ]) def test_reduce_point_density_units(thin_point_data, radius, truth): r"""Test that reduce_point_density works with units.""" - assert_array_equal(reduce_point_density(thin_point_data, radius=radius * units.dam), truth) + assert_array_equal(reduce_point_density(thin_point_data * units.dam, + radius=radius * units.dam), truth) @pytest.mark.parametrize('radius, truth', diff --git a/metpy/calc/tools.py b/metpy/calc/tools.py index 1981ad51dbb..339892499b7 100644 --- a/metpy/calc/tools.py +++ b/metpy/calc/tools.py @@ -259,8 +259,8 @@ def reduce_point_density(points, radius, priority=None): data), returning a mask that can be used to select the points from one or more arrays (e.g. arrays of temperature and dew point). The points selected can be controlled by providing an array of ``priority`` values (e.g. rainfall totals to ensure that - stations with higher precipitation remain in the mask). The radius can be specified - as a `pint.Quantity` with units. If none are provided, meters are assumed. + stations with higher precipitation remain in the mask). The points and radius can be + specified with units. If none are provided, meters are assumed. Parameters ---------- @@ -280,16 +280,19 @@ def reduce_point_density(points, radius, priority=None): Examples -------- >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.) - array([ True, False, True]) + array([ True, False, True]) >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1., ... priority=np.array([0.1, 0.9, 0.3])) - array([False, True, False]) + array([False, True, False]) """ - # Handle a radius with units. Assume meters if units are not specified + # Handle input with units. Assume meters if units are not specified if hasattr(radius, 'units'): radius = radius.to('m').m + if hasattr(points, 'units'): + points = points.to('m').m + # Handle 1D input if points.ndim < 2: points = points.reshape(-1, 1)