Skip to content

Commit

Permalink
Merge pull request #940 from UXARRAY/zedwick/deprecate_remap
Browse files Browse the repository at this point in the history
Deprecate Remapping Without Accessor
  • Loading branch information
rajeeja authored Sep 12, 2024
2 parents 921dd8f + 3fc8525 commit a626596
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 415 deletions.
23 changes: 18 additions & 5 deletions docs/user_api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,16 @@ Remapping
---------
.. autosummary::
:toctree: generated/
:template: autosummary/accessor.rst

UxDataArray.remap

.. autosummary::
:toctree: generated/
:template: autosummary/accessor.rst

UxDataset.nearest_neighbor_remap
UxDataset.inverse_distance_weighted_remap
UxDataset.remap.nearest_neighbor
UxDataset.remap.inverse_distance_weighted

Plotting
--------
Expand Down Expand Up @@ -132,10 +139,16 @@ Remapping
---------
.. autosummary::
:toctree: generated/
:template: autosummary/accessor.rst

UxDataArray.remap

.. autosummary::
:toctree: generated/
:template: autosummary/accessor_method.rst

UxDataArray.nearest_neighbor_remap
UxDataArray.inverse_distance_weighted_remap
UxDataArray.nodal_average
UxDataArray.remap.nearest_neighbor
UxDataArray.remap.inverse_distance_weighted

Plotting
--------
Expand Down
26 changes: 0 additions & 26 deletions test/test_dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,29 +113,3 @@ def test_geodataframe_caching(self):

# override will recompute the grid
assert gdf_start is not gdf_end

def test_nodal_average(self):

# test on a node-centered dataset
uxds = ux.open_dataset(gridfile_geoflow, dsfile_v1_geoflow)

v1_nodal_average = uxds['v1'].nodal_average()

# final dimension should match number of faces
self.assertEqual(v1_nodal_average.shape[-1], uxds.uxgrid.n_face)

# all other dimensions should remain unchanged
self.assertEqual(uxds['v1'].shape[0:-1], v1_nodal_average.shape[0:-1])

# test on a sample mesh with 4 verts
verts = [[[-170, 40], [180, 30], [165, 25], [-170, 20]]]
data = [1, 2, 3, 4]

uxgrid = ux.open_grid(verts, latlon=True)

uxda = ux.UxDataArray(uxgrid=uxgrid, data=data, dims=('n_node'))

uxda_nodal_average = uxda.nodal_average()

# resulting data should be the mean of the corner nodes of the single face
self.assertEqual(uxda_nodal_average, np.mean(data))
3 changes: 1 addition & 2 deletions test/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_node_centered_data(self):

uxds['v1'][0][0].plot.points(backend=backend)

uxds['v1'][0][0].nodal_average().plot.polygons(backend=backend)
uxds['v1'][0][0].topological_mean(destination='face').plot.polygons(backend=backend)


def test_clabel(self):
Expand All @@ -104,7 +104,6 @@ def test_dataset(self):
# plot.hist() is an xarray method
assert hasattr(uxds['v1'].plot, 'hist')


def test_dataarray(self):
"""Tests whether a Xarray Dataset method can be called through the
UxDataset plotting accessor."""
Expand Down
70 changes: 7 additions & 63 deletions test/test_remap.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_nn_remap(self):
uxgrid = ux.open_grid(gridfile_ne30)

uxda = uxds['v1']
out_da = uxda.remap.nearest_neighbor(destination_obj=uxgrid, remap_to="nodes")
out_da = uxda.remap.nearest_neighbor(destination_grid=uxgrid, remap_to="nodes")

# Assert the remapping was successful and the variable is populated
self.assertTrue(len(out_da) != 0)
Expand All @@ -112,41 +112,13 @@ def test_remap_return_types(self):

assert isinstance(remap_uxda_to_grid, UxDataArray)

remap_uxda_to_uxda = source_uxds['v1'].remap.nearest_neighbor(
destination_uxds['psi'])

# Dataset with two vars: original "psi" and remapped "v1"
assert isinstance(remap_uxda_to_uxda, UxDataset)
assert len(remap_uxda_to_uxda.data_vars) == 2

remap_uxda_to_uxds = source_uxds['v1'].remap.nearest_neighbor(
destination_uxds)

# Dataset with two vars: original "psi" and remapped "v1"
assert isinstance(remap_uxda_to_uxds, UxDataset)
assert len(remap_uxda_to_uxds.data_vars) == 2

remap_uxds_to_grid = source_uxds.remap.nearest_neighbor(
destination_uxds.uxgrid)

# Dataset with three vars: remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_grid, UxDataset)
assert len(remap_uxds_to_grid.data_vars) == 3

remap_uxds_to_uxda = source_uxds.remap.nearest_neighbor(
destination_uxds['psi'])

# Dataset with four vars: original "psi" and remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_uxda, UxDataset)
assert len(remap_uxds_to_uxda.data_vars) == 4

remap_uxds_to_uxds = source_uxds.remap.nearest_neighbor(
destination_uxds)

# Dataset with four vars: original "psi" and remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_uxds, UxDataset)
assert len(remap_uxds_to_uxds.data_vars) == 4

def test_edge_centers_remapping(self):
"""Tests the ability to remap on edge centers using Nearest Neighbor
Remapping."""
Expand All @@ -155,11 +127,11 @@ def test_edge_centers_remapping(self):
source_grid = ux.open_dataset(gridfile_geoflow, dsfile_v1_geoflow)
destination_grid = ux.open_dataset(mpasfile_QU, mpasfile_QU)

remap_to_edge_centers = source_grid['v1'].remap.nearest_neighbor(destination_obj=destination_grid,
remap_to_edge_centers = source_grid['v1'].remap.nearest_neighbor(destination_grid=destination_grid.uxgrid,
remap_to="edge centers")

# Assert the data variable lies on the "edge centers"
self.assertTrue(remap_to_edge_centers['v1']._edge_centered())
self.assertTrue(remap_to_edge_centers._edge_centered())

def test_overwrite(self):
"""Tests that the remapping no longer overwrites the dataset."""
Expand All @@ -169,7 +141,7 @@ def test_overwrite(self):
destination_dataset = ux.open_dataset(gridfile_geoflow, dsfile_v1_geoflow)

# Perform remapping
remap_to_edge_centers = source_grid['v1'].remap.nearest_neighbor(destination_obj=destination_dataset,
remap_to_edge_centers = source_grid['v1'].remap.nearest_neighbor(destination_grid=destination_dataset.uxgrid,
remap_to="nodes")

# Assert the remapped data is different from the original data
Expand Down Expand Up @@ -254,41 +226,13 @@ def test_remap_return_types(self):
assert isinstance(remap_uxda_to_grid, UxDataArray)
assert len(remap_uxda_to_grid) == 1

remap_uxda_to_uxda = source_uxds['v1'].remap.inverse_distance_weighted(
destination_uxds['psi'], power=3, k=10)

# Dataset with two vars: original "psi" and remapped "v1"
assert isinstance(remap_uxda_to_uxda, UxDataset)
assert len(remap_uxda_to_uxda.data_vars) == 2

remap_uxda_to_uxds = source_uxds['v1'].remap.inverse_distance_weighted(
destination_uxds, power=3, k=10)

# Dataset with two vars: original "psi" and remapped "v1"
assert isinstance(remap_uxda_to_uxds, UxDataset)
assert len(remap_uxda_to_uxds.data_vars) == 2

remap_uxds_to_grid = source_uxds.remap.inverse_distance_weighted(
destination_uxds.uxgrid)

# Dataset with three vars: remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_grid, UxDataset)
assert len(remap_uxds_to_grid.data_vars) == 3

remap_uxds_to_uxda = source_uxds.remap.inverse_distance_weighted(
destination_uxds['psi'])

# Dataset with four vars: original "psi" and remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_uxda, UxDataset)
assert len(remap_uxds_to_uxda.data_vars) == 4

remap_uxds_to_uxds = source_uxds.remap.inverse_distance_weighted(
destination_uxds)

# Dataset with four vars: original "psi" and remapped "v1, v2, v3"
assert isinstance(remap_uxds_to_uxds, UxDataset)
assert len(remap_uxds_to_uxds.data_vars) == 4

def test_edge_remapping(self):
"""Tests the ability to remap on edge centers using Inverse Distance
Weighted Remapping."""
Expand All @@ -299,11 +243,11 @@ def test_edge_remapping(self):

# Perform remapping to the edge centers of the dataset

remap_to_edge_centers = source_grid['v1'].remap.inverse_distance_weighted(destination_obj=destination_grid,
remap_to_edge_centers = source_grid['v1'].remap.inverse_distance_weighted(destination_grid=destination_grid.uxgrid,
remap_to="edge centers")

# Assert the data variable lies on the "edge centers"
self.assertTrue(remap_to_edge_centers['v1']._edge_centered())
self.assertTrue(remap_to_edge_centers._edge_centered())

def test_overwrite(self):
"""Tests that the remapping no longer overwrites the dataset."""
Expand All @@ -313,7 +257,7 @@ def test_overwrite(self):
destination_dataset = ux.open_dataset(gridfile_geoflow, dsfile_v1_geoflow)

# Perform Remapping
remap_to_edge_centers = source_grid['v1'].remap.inverse_distance_weighted(destination_obj=destination_dataset,
remap_to_edge_centers = source_grid['v1'].remap.inverse_distance_weighted(destination_grid=destination_dataset.uxgrid,
remap_to="nodes")

# Assert the remapped data is different from the original data
Expand Down
79 changes: 2 additions & 77 deletions uxarray/core/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np


from typing import TYPE_CHECKING, Optional, Union, Hashable, Literal
from typing import TYPE_CHECKING, Optional, Hashable, Literal

from uxarray.formatting_html import array_repr

Expand All @@ -20,8 +20,6 @@

from xarray.core.utils import UncachedAccessor

from warnings import warn


from uxarray.core.gradient import (
_calculate_grad_on_edge_from_faces,
Expand Down Expand Up @@ -285,65 +283,6 @@ def to_dataset(

return uxds

def nearest_neighbor_remap(
self,
destination_obj: Union[Grid, UxDataArray, UxDataset],
remap_to: str = "nodes",
coord_type: str = "spherical",
):
"""Nearest Neighbor Remapping between a source (``UxDataArray``) and
destination.`.
Parameters
---------
destination_obj : Grid, UxDataArray, UxDataset
Destination for remapping
remap_to : str, default="nodes"
Location of where to map data, either "nodes" or "face centers"
coord_type : str, default="spherical"
Indicates whether to remap using on spherical or cartesian coordinates
"""
warn(
"This usage of remapping will be deprecated in a future release. It is advised to use uxds.remap.nearest_neighbor() instead.",
DeprecationWarning,
)

return self.remap.nearest_neighbor(destination_obj, remap_to, coord_type)

def inverse_distance_weighted_remap(
self,
destination_obj: Union[Grid, UxDataArray, UxDataset],
remap_to: str = "nodes",
coord_type: str = "spherical",
power=2,
k=8,
):
"""Inverse Distance Weighted Remapping between a source
(``UxDataArray``) and destination.`.
Parameters
---------
destination_obj : Grid, UxDataArray, UxDataset
Destination for remapping
remap_to : str, default="nodes"
Location of where to map data, either "nodes" or "face centers"
coord_type : str, default="spherical"
Indicates whether to remap using on spherical or cartesian coordinates
power : int, default=2
Power parameter for inverse distance weighting. This controls how local or global the remapping is, a higher
power causes points that are further away to have less influence
k : int, default=8
Number of nearest neighbors to consider in the weighted calculation.
"""
warn(
"This usage of remapping will be deprecated in a future release. It is advised to use uxds.remap.inverse_distance_weighted() instead.",
DeprecationWarning,
)

return self.remap.inverse_distance_weighted(
destination_obj, remap_to, coord_type, power, k
)

def integrate(
self, quadrature_rule: Optional[str] = "triangular", order: Optional[int] = 4
) -> UxDataArray:
Expand Down Expand Up @@ -399,20 +338,6 @@ def integrate(

return uxda

def nodal_average(self):
"""Computes the Nodal Average of a Data Variable, which is the mean of
the nodes that surround each face.
Can be used for remapping node-centered data to each face.
"""

warnings.warn(
"This function will be deprecated in a future release. Please use uxda.mean(destination=`face`) instead.",
DeprecationWarning,
)

return self.topological_mean(destination="face")

def topological_mean(
self,
destination: Literal["node", "edge", "face"],
Expand Down Expand Up @@ -886,7 +811,7 @@ def gradient(
Face-centered variable
>>> uxds['var'].gradient()
Node-centered variable
>>> uxds['var'].nodal_average().gradient()
>>> uxds['var'].topological_mean(destination="face").gradient()
"""

if not self._face_centered():
Expand Down
Loading

0 comments on commit a626596

Please sign in to comment.