From 83faf11d151b836f6b0dc7c00cae9923f4257171 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Fri, 7 Feb 2025 06:59:05 -0600 Subject: [PATCH 1/4] add tests for subset and cross-section --- test/test_cross_sections.py | 39 ++++++++++++++++++++ test/test_subset.py | 18 +++++++++ uxarray/cross_sections/dataarray_accessor.py | 6 --- uxarray/cross_sections/grid_accessor.py | 3 -- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/test/test_cross_sections.py b/test/test_cross_sections.py index 4942c86fb..dbf02108d 100644 --- a/test/test_cross_sections.py +++ b/test/test_cross_sections.py @@ -10,10 +10,31 @@ current_path = Path(__file__).resolve().parent quad_hex_grid_path = current_path / 'meshfiles' / "ugrid" / "quad-hexagon" / 'grid.nc' quad_hex_data_path = current_path / 'meshfiles' / "ugrid" / "quad-hexagon" / 'data.nc' +quad_hex_node_data = current_path / 'meshfiles' / "ugrid" / "quad-hexagon" / 'random-node-data.nc' cube_sphere_grid = current_path / "meshfiles" / "ugrid" / "outCSne30" / "outCSne30.ug" from uxarray.grid.intersections import constant_lat_intersections_face_bounds + +def test_repr(): + uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) + + # grid repr + grid_repr = uxds.uxgrid.cross_section.__repr__() + assert "constant_latitude" in grid_repr + assert "constant_longitude" in grid_repr + assert "constant_latitude_interval" in grid_repr + assert "constant_longitude_interval" in grid_repr + + # data array repr + da_repr = uxds['t2m'].cross_section.__repr__() + assert "constant_latitude" in da_repr + assert "constant_longitude" in da_repr + assert "constant_latitude_interval" in da_repr + assert "constant_longitude_interval" in da_repr + + + def test_constant_lat_cross_section_grid(): uxgrid = ux.open_grid(quad_hex_grid_path) @@ -120,6 +141,24 @@ def test_constant_lat_out_of_bounds(): assert len(candidate_faces) == 0 + +def test_const_lat_interval(): + uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) + uxds.uxgrid.normalize_cartesian_coordinates() + + res = uxds['t2m'].cross_section.constant_latitude_interval(lats=(-10, 10)) + + assert len(res) == 4 + +def test_const_lon_interval(): + uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) + uxds.uxgrid.normalize_cartesian_coordinates() + + res = uxds['t2m'].cross_section.constant_longitude_interval(lons=(-10, 10)) + + assert len(res) == 4 + + class TestArcs: def test_latitude_along_arc(self): node_lon = np.array([-40, -40, 40, 40]) diff --git a/test/test_subset.py b/test/test_subset.py index 71be6dff5..a4b9b29a4 100644 --- a/test/test_subset.py +++ b/test/test_subset.py @@ -19,6 +19,24 @@ current_path / "meshfiles" / "ugrid" / "outCSne30" / "var2.nc" ] +quad_hex_grid_path = current_path / 'meshfiles' / "ugrid" / "quad-hexagon" / 'grid.nc' +quad_hex_data_path = current_path / 'meshfiles' / "ugrid" / "quad-hexagon" / 'data.nc' + +def test_repr(): + uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) + + # grid repr + grid_repr = uxds.uxgrid.subset.__repr__() + assert "bounding_box" in grid_repr + assert "bounding_circle" in grid_repr + assert "nearest_neighbor" in grid_repr + + # data array repr + da_repr = uxds['t2m'].subset.__repr__() + assert "bounding_box" in da_repr + assert "bounding_circle" in da_repr + assert "nearest_neighbor" in da_repr + def test_grid_face_isel(): for grid_path in GRID_PATHS: diff --git a/uxarray/cross_sections/dataarray_accessor.py b/uxarray/cross_sections/dataarray_accessor.py index 43365b79f..15e500370 100644 --- a/uxarray/cross_sections/dataarray_accessor.py +++ b/uxarray/cross_sections/dataarray_accessor.py @@ -215,9 +215,3 @@ def constant_longitude_interval( faces = self.uxda.uxgrid.get_faces_between_longitudes(lons) return self.uxda.isel(n_face=faces, inverse_indices=inverse_indices) - - def gca(self, *args, **kwargs): - raise NotImplementedError - - def gca_gca(self, *args, **kwargs): - raise NotImplementedError diff --git a/uxarray/cross_sections/grid_accessor.py b/uxarray/cross_sections/grid_accessor.py index 921a6060a..26638030d 100644 --- a/uxarray/cross_sections/grid_accessor.py +++ b/uxarray/cross_sections/grid_accessor.py @@ -284,6 +284,3 @@ def constant_longitude_interval( return grid_between_lons, faces else: return grid_between_lons - - def gca_gca(self, *args, **kwargs): - raise NotImplementedError From 5629bd8ae8c541626d0ada327df36b392e392295 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Fri, 7 Feb 2025 07:04:17 -0600 Subject: [PATCH 2/4] fix parameter and add test for da subset --- test/test_subset.py | 10 ++++++++++ uxarray/subset/dataarray_accessor.py | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/test_subset.py b/test/test_subset.py index a4b9b29a4..26bc79b55 100644 --- a/test/test_subset.py +++ b/test/test_subset.py @@ -173,3 +173,13 @@ def test_inverse_indices(): # Test isel directly subset = grid.isel(n_face=[1], inverse_indices=True) assert subset.inverse_indices.face.values == 1 + + +def test_da_subset(): + uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) + + res1 = uxds['t2m'].subset.bounding_box(lon_bounds=(-10, 10), lat_bounds=(-10, 10)) + res2 = uxds['t2m'].subset.bounding_circle(center_coord=(0,0), r=10) + res3 = uxds['t2m'].subset.nearest_neighbor(center_coord=(0, 0), k=4) + + assert len(res1) == len(res2) == len(res3) == 4 diff --git a/uxarray/subset/dataarray_accessor.py b/uxarray/subset/dataarray_accessor.py index f5f64d9f0..0c2279e48 100644 --- a/uxarray/subset/dataarray_accessor.py +++ b/uxarray/subset/dataarray_accessor.py @@ -59,9 +59,11 @@ def bounding_box( - List/Set of strings: Stores specified index types (valid values: "face", "edge", "node") - False: No index storage (default) """ - grid = self.uxda.uxgrid.subset.bounding_box(lon_bounds, lat_bounds) + grid = self.uxda.uxgrid.subset.bounding_box( + lon_bounds, lat_bounds, inverse_indices=inverse_indices + ) - return self.uxda._slice_from_grid(grid, inverse_indices=inverse_indices) + return self.uxda._slice_from_grid(grid) def bounding_circle( self, From 9efdb561957e618d0afebebe9cde3358454e599f Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Fri, 7 Feb 2025 07:25:16 -0600 Subject: [PATCH 3/4] add test for inverse indices --- test/test_cross_sections.py | 28 ++++++++++++++++++-- uxarray/cross_sections/dataarray_accessor.py | 5 ---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/test/test_cross_sections.py b/test/test_cross_sections.py index dbf02108d..1cf602de5 100644 --- a/test/test_cross_sections.py +++ b/test/test_cross_sections.py @@ -142,7 +142,7 @@ def test_constant_lat_out_of_bounds(): -def test_const_lat_interval(): +def test_const_lat_interval_da(): uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) uxds.uxgrid.normalize_cartesian_coordinates() @@ -150,7 +150,19 @@ def test_const_lat_interval(): assert len(res) == 4 -def test_const_lon_interval(): + +def test_const_lat_interval_grid(): + uxgrid = ux.open_grid(quad_hex_grid_path) + + res = uxgrid.cross_section.constant_latitude_interval(lats=(-10, 10)) + + assert res.n_face == 4 + + res, indices = uxgrid.cross_section.constant_latitude_interval(lats=(-10, 10), return_face_indices=True) + + assert len(indices) == 4 + +def test_const_lon_interva_da(): uxds = ux.open_dataset(quad_hex_grid_path, quad_hex_data_path) uxds.uxgrid.normalize_cartesian_coordinates() @@ -159,6 +171,18 @@ def test_const_lon_interval(): assert len(res) == 4 +def test_const_lon_interval_grid(): + uxgrid = ux.open_grid(quad_hex_grid_path) + + res = uxgrid.cross_section.constant_longitude_interval(lons=(-10, 10)) + + assert res.n_face == 4 + + res, indices = uxgrid.cross_section.constant_longitude_interval(lons=(-10, 10), return_face_indices=True) + + assert len(indices) == 4 + + class TestArcs: def test_latitude_along_arc(self): node_lon = np.array([-40, -40, 40, 40]) diff --git a/uxarray/cross_sections/dataarray_accessor.py b/uxarray/cross_sections/dataarray_accessor.py index 15e500370..7d7610db7 100644 --- a/uxarray/cross_sections/dataarray_accessor.py +++ b/uxarray/cross_sections/dataarray_accessor.py @@ -133,9 +133,6 @@ def constant_latitude_interval( lats : Tuple[float, float] The latitude interval (min_lat, max_lat) at which to extract the cross-section, in degrees. Values must be between -90.0 and 90.0 - return_face_indices : bool, optional - If True, also returns the indices of the faces that intersect with the - latitude interval. inverse_indices : Union[List[str], Set[str], bool], optional Controls storage of original grid indices. Options: - True: Stores original face indices @@ -181,8 +178,6 @@ def constant_longitude_interval( lons : Tuple[float, float] The longitude interval (min_lon, max_lon) at which to extract the cross-section, in degrees. Values must be between -180.0 and 180.0 - return_face_indices : bool, optional - If True, also returns the indices of the faces that intersect are within a specifed longitude interval. inverse_indices : Union[List[str], Set[str], bool], optional Controls storage of original grid indices. Options: - True: Stores original face indices From da191cbf401540555a1fc074b7d7383a61309593 Mon Sep 17 00:00:00 2001 From: Philip Chmielowiec <67855069+philipc2@users.noreply.github.com> Date: Fri, 7 Feb 2025 07:28:17 -0600 Subject: [PATCH 4/4] remove unused func dec --- uxarray/cross_sections/grid_accessor.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/uxarray/cross_sections/grid_accessor.py b/uxarray/cross_sections/grid_accessor.py index 26638030d..b4fed76db 100644 --- a/uxarray/cross_sections/grid_accessor.py +++ b/uxarray/cross_sections/grid_accessor.py @@ -159,9 +159,6 @@ def constant_longitude( else: return grid_at_constant_lon - def gca(self, *args, **kwargs): - raise NotImplementedError - def constant_latitude_interval( self, lats: Tuple[float, float],