Deltares / xugrid

Xarray and unstructured grids
https://deltares.github.io/xugrid/
MIT License
53 stars 8 forks source link

Add support for x/y variables with different names in `xu.DataArray.from_structured` #222

Open veenstrajelmer opened 3 months ago

veenstrajelmer commented 3 months ago

xu.UgridDataArray.from_structured has x and y arguments. This implies that dimension/variable names like "longitude" and "latitude" are also supported. This is not the case however. The workaround is easy, but I guess it was intended to add support for xy variables/dimesions with different names. The example below raises "ValueError: Last two dimensions of da must be ("y", "x")"

A reproducible example:

import xarray as xr
import xugrid as xu

file_nc = "cmems_so_2022-11-02.nc"

ds = xr.open_dataset(file_nc)

# xy args are not supported, raises 'ValueError: Last two dimensions of da must be ("y", "x")'
uda = xu.UgridDataArray.from_structured(ds.so, x="longitude", y="latitude")

# this does work
ds_renamed = ds.rename({"longitude":"x", "latitude":"y"})
uda = xu.UgridDataArray.from_structured(ds_renamed.so)

Example dataset (extension changed to enable uploading): cmems_so_2022-11-02.nc.txt

Furthermore, the resulting uda is not a xugrid.UgridDataArray, but a xarray.DataArray instead.

Huite commented 3 months ago

Indeed, looks like I wasn't quite thorough here.

I added the x and y keywords so that you can also supply rotated grids, where x_c and y_c are 2D, depend on (y, x). In that case, the dimension ordering is still important for the layout of the actual data variable. If both x and y are provided, it should stilll be checked whether the dimension order is appropriate; alternatively, this function should automatically call a transpose. I'm a bit wary of calling transposes because it can have bad effects on performance. Letting the user fix it themselves ensures that they become aware that a transpose is going on.

Anyway, if no x and y are provided, we can infer them. There's x, y = conversion.infer_xy_coords(data) inside of Ugrid2d.from_structured, which we can just use here.

We can also infer the x dimension and y dimension in case the x and y coordinates are 2D. I haven't fully thought this through, but I think we can always assume that both the coords and data must have (y, x) as dimension order.