From cb9fa86038ce8110ce08e435b6b24c77bbeba84f Mon Sep 17 00:00:00 2001 From: Facundo Sapienza Date: Mon, 31 Aug 2020 08:08:47 -0700 Subject: [PATCH] Validate input numpy (#105) * Add numpy class of variable to conditional in spatial extent validation * numpy scalars now available for the case where the spatial extent consists of a polygon and it is given by a single list * I added some modification in the case where spatial_extent consists on a list of tuples in order to accept np.scalars as valid inptus * I modified line 117 in order that now _spat_extent is a list of floats, just as all the other cases. Without this line, sometimes we will have cases of numpy arrays and it is easier if all the _spatial_extent are list of floats * I added test_numpyfloatlist_bbox and test_numpfloatarray_bbox --- CONTRIBUTORS.rst | 1 + icepyx/core/validate_inputs.py | 20 ++++++++++++++------ icepyx/tests/test_validate_inputs.py | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index da8dd4ef4..1776170ff 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -12,6 +12,7 @@ order by last name) and are considered "The icepyx Developers": * `Zheng Liu `_ - University of Washington * `Joachim Meyer `_ - University of Utah * `Fernando Perez `_ - University of California, Berkeley +* `Facundo Sapienza `_ - University of California, Berkeley * `Jessica Scheick `_ - Unaffiliated (ORCID: `0000-0002-3421-4459 `_) * `David Shean `_ - University of Washington * `Ben Smith `_ - University of Washington diff --git a/icepyx/core/validate_inputs.py b/icepyx/core/validate_inputs.py index 0a4a30751..7e6ccd274 100644 --- a/icepyx/core/validate_inputs.py +++ b/icepyx/core/validate_inputs.py @@ -88,10 +88,14 @@ def spatial(spatial_extent): """ Validate the input spatial extent and return the needed parameters to the query object. """ - if isinstance(spatial_extent, list): + + scalar_types = (np.int, np.float, np.int64) + + if isinstance(spatial_extent, (list, np.ndarray)): + # bounding box if len(spatial_extent) == 4 and all( - type(i) in [int, float] for i in spatial_extent + isinstance(i, scalar_types) for i in spatial_extent ): assert -90 <= spatial_extent[1] <= 90, "Invalid latitude value" assert -90 <= spatial_extent[3] <= 90, "Invalid latitude value" @@ -110,11 +114,15 @@ def spatial(spatial_extent): assert ( spatial_extent[1] <= spatial_extent[3] ), "Invalid bounding box latitudes" - _spat_extent = spatial_extent + _spat_extent = [float(x) for x in spatial_extent] extent_type = "bounding_box" # user-entered polygon as list of lon, lat coordinate pairs - elif all(type(i) in [list, tuple] for i in spatial_extent): + elif all(type(i) in [list, tuple, np.ndarray] for i in spatial_extent) and all( + all( isinstance(i[j], scalar_types) for j in range(len(i)) ) for i in spatial_extent + ): + if any( len(i) != 2 for i in spatial_extent): + raise ValueError("Each element in spatial_extent should be a list or tuple of length 2") assert ( len(spatial_extent) >= 4 ), "Your spatial extent polygon has too few vertices" @@ -140,7 +148,7 @@ def spatial(spatial_extent): # warnings.warn("this type of input is not yet well handled and you may not be able to find data") # user-entered polygon as a single list of lon and lat coordinates - elif all(type(i) in [int, float] for i in spatial_extent): + elif all( isinstance(i, scalar_types) for i in spatial_extent): assert ( len(spatial_extent) >= 8 ), "Your spatial extent polygon has too few vertices" @@ -162,7 +170,7 @@ def spatial(spatial_extent): # _spat_extent = polygon else: - raise ValueError("Your spatial extent does not meet minimum input criteria") + raise ValueError("Your spatial extent does not meet minimum input criteria or the input format is not correct") # DevGoal: write a test for this? # make sure there is nothing set to _geom_filepath since its existence determines later steps diff --git a/icepyx/tests/test_validate_inputs.py b/icepyx/tests/test_validate_inputs.py index c0da6a764..55af1bb8b 100644 --- a/icepyx/tests/test_validate_inputs.py +++ b/icepyx/tests/test_validate_inputs.py @@ -50,7 +50,21 @@ def test_floatlist_bbox(): expected = ["bounding_box", [-64.2, 66.2, -55.5, 72.5], None] for i in range(len(expected)): assert obs[i] == expected[i] + +def test_numpyfloatarray_bbox(): + obs = val.spatial(np.array([-64.2, 66.2, -55.5, 72.5])) + expected = ["bounding_box", [-64.2, 66.2, -55.5, 72.5], None] + for i in range(len(expected)): + assert obs[i] == expected[i] + + +def test_numpyfloatlist_bbox(): + obs = val.spatial(list(np.array([-64.2, 66.2, -55.5, 72.5]))) + expected = ["bounding_box", [-64.2, 66.2, -55.5, 72.5], None] + for i in range(len(expected)): + assert obs[i] == expected[i] + def test_list_latlon_pairs(): out = val.spatial([[-55, 68], [-55, 71], [-48, 71], [-48, 68], [-55, 68]])