Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial on defining grid topology + fitting data into the data model #976

Open
mgrover1 opened this issue Sep 27, 2024 · 4 comments
Open
Labels
new feature New feature or request

Comments

@mgrover1
Copy link

Proposed new feature or change:

I am interested in fitting xradar datasets/datatrees (radar data in radial coordinates) into the uxarray data model! This would allow us to represent the data more accurately in-memory, with proper edges to the native coordinates.

Reading through the docs for uxarray, I am looking for a tutorial on how to take an existing xarray dataset and transform it into a uxarray dataset with proper grid topology + conventions that would enable the use of the full functionality in this library.

Do you have any recommendations on where to get started? This is something I would be willing to help with if I can figure out how to get started here 👍

At a first glance, I am guessing to start somewhere related to this https://uxarray.readthedocs.io/en/latest/user_api/generated/uxarray.Grid.from_dataset.html

But I am not sure of the variable/coordinate names I need to transform before feeding the dataset into this function. Any help here would be greatly appreciated!

@rajeeja
Copy link
Contributor

rajeeja commented Sep 27, 2024

Thanks for the issue. This is very doable: xradar data needs be represented in the UGRID framework. This would require defining how the radial coordinates and associated metadata map onto the UGRID concepts.

Initial implementation could extend open_grid and follow style of this reader

@philipc2
Copy link
Member

Hi @mgrover1

There are a few ways we could handle this, and this is with me making the assumption that the data provided can be easily converted to spherical or Cartesian coordinates.

Triangulation or Tessellation

We could run scipy.spatial.Delaunay or scipy.spatial.SphericalVoronoi to create a UGRID compatible grid. For reference, a minimal grid to be read in using uxarray.Grid.from_topology() requires the following variables

  • node_lon & node_lat: The longitude and lattitude of the corner nodes of each cell
  • face_node_connectivity: The indices of the nodes that surround each face

Remapping

As part of #892, I can add an option to remap arbitrary coordinate onto a structured grid. This would require the user to provide a destination grid, but makes me lean towards the first option.

@classmethod
def from_topology(
cls,
node_lon: np.ndarray,
node_lat: np.ndarray,
face_node_connectivity: np.ndarray,
fill_value: Optional = None,
start_index: Optional[int] = 0,
dims_dict: Optional[dict] = None,
**kwargs,
):
"""Constructs a ``Grid`` object from user-defined topology variables
provided in the UGRID conventions.
Note
----
To construct a UGRID-complient grid, the user must provide at least ``node_lon``, ``node_lat`` and ``face_node_connectivity``
Parameters
----------
node_lon : np.ndarray
Longitude of node coordinates
node_lat : np.ndarray
Latitude of node coordinates
face_node_connectivity : np.ndarray
Face node connectivity, mapping each face to the nodes that surround them
fill_value: Optional
Value used for padding connectivity variables when the maximum number of elements in a row is less than the maximum.
start_index: Optional, default=0
Start index (typically 0 or 1)
dims_dict : Optional, dict
Dictionary of dimension names mapped to the ugrid conventions (i.e. {"nVertices": "n_node})
**kwargs :
Usage
-----
>>> import uxarray as ux
>>> node_lon, node_lat, face_node_connectivity, fill_value = ...
>>> uxgrid = ux.Grid.from_ugrid(node_lon, node_lat, face_node_connectivity, fill_value)
"""
if dims_dict is None:
dims_dict = {}
grid_ds = _read_topology(
node_lon,
node_lat,
face_node_connectivity,
fill_value,
start_index,
**kwargs,
)
grid_spec = "User Defined Topology"
return cls(grid_ds, grid_spec, dims_dict)

@mgrover1
Copy link
Author

Thanks for the quick response @rajeeja and @philipc2 👍

Here is an example of what a plan position indicator (PPI) plot usually look like with proper grid edges defined and plotting with matplotlib
https://arm-doe.github.io/pyart/examples/plotting/plot_ppi_cfradial.html

We currently extract the edges in this function
https://github.com/ARM-DOE/pyart/blob/main/pyart/core/transforms.py#L149

I am not sure if this would help with the triangulation then or if we could feed this manually-defined cell edge information into the function(s) here

@erogluorhan
Copy link
Member

erogluorhan commented Sep 27, 2024

Hi @mgrover1 , thanks for the issue!

To make sure I am understanding the geometry the radar data can have correctly: There are point clouds (gate centers?) on arbitrary geolocations (maybe not that arbitrary because of the radar sweeps?), and there are edges that are consisting of pairs of those gate centers, which is already generated by pyart, right? Also, pyart doesn't care about any faces/cells that could consist of groups of those edges, also several gate centers, correct?

In UXarray though, we need faces to be also defined for a grid topology to be represented. We need to know (or generate through triangulation as @philipc2 pointed out) face-to-node connectivity at the least (our "node"s correspond to your gate centers I believe?). Regardless, UXarray will eventually need to generate a grid out of point clouds, i.e. defining faces (most likely triangles through Delaunay) out of point clouds and the face-node connectivity, since this seems to be much needed anyways. In the pyart case though, since you are already generating edges out of points, we'd need to use those edges to generate faces rather than making a simple triangulation of the points disregarding your edges. @rajeeja @philipc2 feel free to correct any points.

If we can do that, I think radar applications can benefit much from UXarray's existing and future edge-based plotting and analysis functions (if I am correct with my above understanding of the radar geometry). I am not sure though if UXarray grids' faces/cells, triangles in this case, can be of any use for analysis (they can still be helpful with visualization funcs like rasterized plots for instance).

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request
Projects
Status: 📚 Backlog
Development

No branches or pull requests

4 participants