diff --git a/docs/user_guide/examples/tutorial_diffusion.ipynb b/docs/user_guide/examples/tutorial_diffusion.ipynb index f9a60fef1..a0aeac6b8 100644 --- a/docs/user_guide/examples/tutorial_diffusion.ipynb +++ b/docs/user_guide/examples/tutorial_diffusion.ipynb @@ -194,7 +194,6 @@ "\n", "ds = simple_UV_dataset(dims=(1, 1, Ny, 1), mesh=\"flat\")\n", "ds[\"lat\"][:] = np.linspace(-0.01, 1.01, Ny)\n", - "ds[\"lon\"][:] = np.ones(len(ds.XG))\n", "ds[\"Kh_meridional\"] = ([\"YG\", \"XG\"], Kh_meridional[:, None])\n", "ds" ] diff --git a/docs/user_guide/examples/tutorial_interpolation.ipynb b/docs/user_guide/examples/tutorial_interpolation.ipynb index afced17c9..8616b5d16 100644 --- a/docs/user_guide/examples/tutorial_interpolation.ipynb +++ b/docs/user_guide/examples/tutorial_interpolation.ipynb @@ -50,7 +50,7 @@ "ds[\"lat\"][:] = np.linspace(0.0, 1.0, len(ds.YG))\n", "ds[\"lon\"][:] = np.linspace(0.0, 1.0, len(ds.XG))\n", "dx, dy = 1.0 / len(ds.XG), 1.0 / len(ds.YG)\n", - "ds[\"P\"] = ds[\"U\"] + np.random.rand(5, 4) + 0.1\n", + "ds[\"P\"] = ds[\"U\"] + np.random.rand(1, 1, 5, 4) + 0.1\n", "ds[\"P\"][:, :, 1, 1] = 0\n", "ds" ] @@ -59,7 +59,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "From this dataset we create a {py:obj}`parcels.FieldSet` using the {py:meth}`parcels.FieldSet.from_sgrid_conventions` constructor, which automatically sets up the grid and fields according to Parcels' s-grid conventions." + "From this dataset we create a {py:obj}`parcels.FieldSet` using the {py:meth}`parcels.FieldSet.from_sgrid_conventions` constructor, which automatically sets up the grid and fields according to Parcels' s-grid conventions.\n", + "\n", + "The default interpolator for fields on structured A-grid grids is (tri)linear interpolation, implemented in `parcels.interpolators.XLinear`." ] }, { @@ -68,7 +70,9 @@ "metadata": {}, "outputs": [], "source": [ - "fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"flat\")" + "fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"flat\")\n", + "\n", + "assert fieldset.P.interp_method == parcels.interpolators.XLinear" ] }, { diff --git a/docs/user_guide/examples/tutorial_unitconverters.ipynb b/docs/user_guide/examples/tutorial_unitconverters.ipynb index 6393af839..ed959c135 100644 --- a/docs/user_guide/examples/tutorial_unitconverters.ipynb +++ b/docs/user_guide/examples/tutorial_unitconverters.ipynb @@ -53,7 +53,9 @@ "ds[\"temperature\"] = ds[\"U\"] + 20 # add temperature field of 20 deg\n", "ds[\"U\"].data[:] = 1.0 # set U to 1 m/s\n", "ds[\"V\"].data[:] = 1.0 # set V to 1 m/s\n", - "ds" + "display(ds)\n", + "\n", + "fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"spherical\")" ] }, { @@ -61,12 +63,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To create a `parcels.FieldSet` object, we use the `parcels.FieldSet.from_sgrid_conventions` constructor. We add the argument `mesh='spherical'` to signal that all longitudes and latitudes are in degrees.\n", - "\n", - "```{note}\n", - "When using a `FieldSet` method for a specific dataset, such as `from_copernicusmarine()`, the grid information is known and parsed by Parcels, so we do not have to add the `mesh` argument.\n", - "```\n", - "\n", "Plotting the `U` field indeed shows a uniform 1 m/s eastward flow.\n" ] }, @@ -76,8 +72,6 @@ "metadata": {}, "outputs": [], "source": [ - "fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"spherical\")\n", - "\n", "plt.pcolormesh(\n", " fieldset.U.grid.lon,\n", " fieldset.U.grid.lat,\n", diff --git a/src/parcels/_core/utils/sgrid.py b/src/parcels/_core/utils/sgrid.py index 82ae0d727..4e671e822 100644 --- a/src/parcels/_core/utils/sgrid.py +++ b/src/parcels/_core/utils/sgrid.py @@ -461,6 +461,18 @@ def _metadata_rename_dims(grid: Grid2DMetadata, dims_dict: dict[str, str]) -> Gr def _metadata_rename_dims(grid: Grid3DMetadata, dims_dict: dict[str, str]) -> Grid3DMetadata: ... +def _attach_sgrid_metadata(ds, grid: Grid2DMetadata | Grid3DMetadata): + """Copies the dataset and attaches the SGRID metadata in 'grid' variable. Modifies 'conventions' attribute.""" + ds = ds.copy() + ds["grid"] = ( + [], + 0, + grid.to_attrs(), + ) + ds.attrs["Conventions"] = "SGRID" + return ds + + def _metadata_rename_dims(grid, dims_dict): """ Renames dimensions in SGrid metadata. diff --git a/src/parcels/_datasets/structured/generated.py b/src/parcels/_datasets/structured/generated.py index 20440717c..5bcf00c9c 100644 --- a/src/parcels/_datasets/structured/generated.py +++ b/src/parcels/_datasets/structured/generated.py @@ -7,6 +7,7 @@ DimDimPadding, Grid2DMetadata, Padding, + _attach_sgrid_metadata, ) from parcels._core.utils.time import timedelta_to_float from parcels._datasets.utils import _attach_sgrid_metadata @@ -24,7 +25,7 @@ def simple_UV_dataset(dims=(360, 2, 30, 4), maxdepth=1, mesh="spherical"): "YG": (["YG"], np.arange(dims[2]), {"axis": "Y", "c_grid_axis_shift": -0.5}), "XC": (["XC"], np.arange(dims[3]) + 0.5, {"axis": "X"}), "XG": (["XG"], np.arange(dims[3]), {"axis": "X", "c_grid_axis_shift": -0.5}), - "lat": (["YG"], np.linspace(-90, 90, dims[2]), {"axis": "Y", "c_grid_axis_shift": 0.5}), + "lat": (["YG"], np.linspace(-90, 90, dims[2]), {"axis": "Y", "c_grid_axis_shift": -0.5}), "lon": (["XG"], np.linspace(-max_lon, max_lon, dims[3]), {"axis": "X", "c_grid_axis_shift": -0.5}), }, ).pipe( diff --git a/src/parcels/_datasets/structured/generic.py b/src/parcels/_datasets/structured/generic.py index 43302635d..628e790ed 100644 --- a/src/parcels/_datasets/structured/generic.py +++ b/src/parcels/_datasets/structured/generic.py @@ -5,6 +5,7 @@ DimDimPadding, Grid2DMetadata, Padding, + _attach_sgrid_metadata, ) from parcels._core.utils.sgrid import ( rename_dims as sgrid_rename_dims,