diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4db5959b..0bc1cc9c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,5 +3,4 @@ - [ ] Closes #xxxx - [ ] Tests added - [ ] Tests passed - - [ ] Passes ``git diff origin/main **/*py | flake8 --diff`` - [ ] Fully documented diff --git a/pyresample/geometry.py b/pyresample/geometry.py index 0a0250b0..9463fb6e 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -2696,6 +2696,15 @@ def geocentric_resolution(self, ellps='WGS84', radius=None): edge averages. """ + def _safe_bin_edges(arr): + try: + return np.histogram_bin_edges(arr, bins=10)[:2] + except ValueError: + # numpy 2.1.0+ produces a ValueError if it can't fill + # all bins due to a small data range + # we just arbitrarily use the first 2 elements as all elements + # should be within floating point precision for our use case + return arr[:2] from pyproj.transformer import Transformer rows, cols = self.shape mid_row = rows // 2 @@ -2726,9 +2735,9 @@ def geocentric_resolution(self, ellps='WGS84', radius=None): # Very useful near edge of disk geostationary areas. hor_res = vert_res = 0 if hor_dist.size: - hor_res = np.mean(np.histogram_bin_edges(hor_dist)[:2]) + hor_res = np.mean(_safe_bin_edges(hor_dist)) if vert_dist.size: - vert_res = np.mean(np.histogram_bin_edges(vert_dist)[:2]) + vert_res = np.mean(_safe_bin_edges(vert_dist)) # Use the maximum distance between the two midlines instead of # binning both of them together. If we binned them together then # we are highly dependent on the shape of the area (more rows in diff --git a/pyresample/test/test_geometry/test_area.py b/pyresample/test/test_geometry/test_area.py index 4cb03c96..ce29e9e0 100644 --- a/pyresample/test/test_geometry/test_area.py +++ b/pyresample/test/test_geometry/test_area.py @@ -1062,6 +1062,21 @@ def test_area_def_geocentric_resolution(self, create_test_area): geo_res = area_def.geocentric_resolution() np.testing.assert_allclose(298.647232, geo_res, atol=1e-1) + def test_area_def_geocentric_resolution_close_dist(self, create_test_area): + """Test geocentric resolution when distance range isn't big enough for histogram bins. + + The method currently uses `np.histogram_bin_edges`. Starting in numpy + 2.1.0, if the number of bins requested (10 in this default case) can't + be created because the range of the data is too small, it will raise an + exception. This test makes sure that geocentric_resolution doesn't + error out when this case is encountered. + + """ + # this area is known to produce horizontal distances of ~999.9999989758 + # and trigger the error in numpy 2.1.0 + ar = create_test_area(4087, 5, 5, (-2500.0, -2500.0, 2500.0, 2500.0)) + np.testing.assert_allclose(ar.geocentric_resolution(), 999.999999, atol=1e-2) + def test_area_def_geocentric_resolution_latlong(self, create_test_area): """Test the AreaDefinition.geocentric_resolution method on a latlong projection.""" area_extent = (-110.0, 45.0, -95.0, 55.0)