Repository navigation
Error when number of vertical dimensions is not 1 or 4 - #3013
erikvansebille wants to merge 7 commits into
Conversation
VeckoTheGecko
left a comment
There was a problem hiding this comment.
Minor comment about test location and name
wyatt-fluidnumerics
left a comment
There was a problem hiding this comment.
This looks good, we probably want to add a similar check in from_ugrid_convention, but that can be a separate PR.
| assert_1D_or4D_vertical_dimensions(ds) | ||
|
|
There was a problem hiding this comment.
This looks good, we probably want to add a similar check in from_ugrid_convention, but that can be a separate PR.
It's here in this PR
There was a problem hiding this comment.
Missed that! In this case we need some kind of separate check for each since the UxGrid time varying z coordinate should only be 3 dimensions (time, node, depth).
There was a problem hiding this comment.
On second thought I am also now wondering what this check is catching that the checks in the XGrid and UxGrid constructors are not, is it maybe worth just making those more robust ?
Parcels/src/parcels/_core/xgrid.py
Lines 142 to 145 in d0212c5
Parcels/src/parcels/_core/uxgrid.py
Lines 51 to 52 in d0212c5
There was a problem hiding this comment.
Ah, good call! But then I'm surprised that the unit tests pass. Every 3D depth field should be throwing an Error.
@wyatt-fluidnumerics: could you dive in to see why these were not captured by this assert function? You have better feel for the code-flow on the UxGrid-side
There was a problem hiding this comment.
After some digging I am pretty sure none of the unit tests caught this because they all use sigma_coordinate_lattice_dataset, which doesn't assign any dimension attributes so ds.cf.axes.get("Z") always comes back none.
import numpy as np
from parcels._datasets.unstructured.generated import sigma_coordinate_lattice_dataset
nx = 5
eta = np.zeros((3, nx, nx))
ds = sigma_coordinate_lattice_dataset(nx, (0.0, 4e3), (0.0, 4e3), 4, 100.0, eta=eta)
print(f"zf dims: {ds['zf'].dims}, zf attrs: {ds['zf'].attrs}")
print(f'ds.cf.axes.get("Z"): {ds.cf.axes.get("Z")}')zf dims: ('time', 'zf', 'n_node'), zf attrs: {}
ds.cf.axes.get("Z"): None
It is also worth noting that the new test in this PR passes with all of the assert_1D_or4D_vertical_dimension calls commented out thanks to the checks in the XGrid constructor. So it is possible that this is unneeded. The constructor checks themself are new as of #2933 and may not have been merged into the version of parcels used in #2954, which was why the original bug happened.
There was a problem hiding this comment.
Hmm, even if I add
--- a/src/parcels/_datasets/unstructured/generated.py
+++ b/src/parcels/_datasets/unstructured/generated.py
@@ -403,4 +403,6 @@ def sigma_coordinate_lattice_dataset(nx, x_range, y_range, nz, bottom_depth, eta
ds = ux.UxDataset(xr.Dataset(velocities, coords={"time": time, **vertical_coords}), uxgrid=uxgrid)
ds.uxgrid.node_lon.attrs["units"] = "m"
ds.uxgrid.node_lat.attrs["units"] = "m"
+ ds.zf.attrs["axis"] = "Z"
+ ds.zc.attrs["axis"] = "Z"
return dsI still get that ds.cf.axes.get("Z") is None. That seems strange?
So it is possible that this is unneeded
But the tests in xgrid are still relevant and caching 2D and 3D depth arrays, so would they not be relevant for there? Or are you only suggest we remove this in from_ugrid_conventions()?
There was a problem hiding this comment.
That is strange, let me keep looking ... The tests are definitely relevant, I am just saying it is possible that all cases covered by assert_ 1D_or4D_vertical_dimensions are already covered by the constructor checks
There was a problem hiding this comment.
I believe this has to do with the way UxArray internals wrap on top of xarray, the short explanation is that ds.zf.attrs['axis'] = 'Z' doesn't actually assign the attribute to the underlying ds. Instead, since UxArray data is stored in underlying xarrays, when you do .zf you are getting a new UxArray.DataArray object that wraps the underlying xarray object, so changing the zf attributes doesn't actually adjust the UxArray.DataArray that lies within ds, it just changes the wrapped copy returned by ds.zf.
This can be most easily demonstrated by running ds.zf is ds.zf on the dataset in the generator, which returns False.
For your test case the workaround is to change the attribute using ds.variables['zf'] which returns the object in ds itself rather than a wrapped copy. When you assign the z axis as an attribute that way (i.e. ds.variables'[zf'].attrs['axis'] = "Z") you get:
zf dims: ('time', 'zf', 'n_node'), zf attrs: {'axis': 'Z'}
ds.cf.axes.get("Z"): ['zc', 'zf']
when running the same script from above.
There was a problem hiding this comment.
Thanks, this helped! I now patched the test and the assert function in a423c45. Could you review again?
And fixing unit test to properly set Z axis
wyatt-fluidnumerics
left a comment
There was a problem hiding this comment.
Only a few other comments!
| assert fset.context["c2"] == 2.0 | ||
|
|
||
|
|
||
| def test_fieldset_error_on_unsupported_depth_dimensionality(): |
There was a problem hiding this comment.
Would it be useful to parametrize this to reach the UxGrid path too?
| # Assert that vertical dimensions have allowed dimensionality. | ||
| if (vertical_dims := ds.cf.axes.get("Z")) is not None: | ||
| for vertical_dim in vertical_dims: | ||
| ndim = np.atleast_1d(ds[vertical_dim]).ndim # cast 0D to 1D |
There was a problem hiding this comment.
If the vertical dimension is time varying and loaded lazily could this not trigger an inadvertent large dask compute that instantly gets tossed?
There was a problem hiding this comment.
Fixed in d34c367. From the LLM: np.atleast_1d(DataArray) converts to a numpy array, which computes lazy data. .ndim is metadata on the DataArray and costs nothing
From the LLM: np.atleast_1d(DataArray) converts to a numpy array, which computes lazy data. .ndim is metadata on the DataArray and costs nothing
Description
Following the comment at #2954 (comment), this PR moves the check on number of vertical dimensions from
index_searchto the creation of theFieldSet.Comment by @VeckoTheGecko
Checklist
mainfor normal development,v3-supportfor v3 support)