SFBOFS (Regular Grid 2D)¶
NOTE: currently Broken – seems not to be auto-detecting the grid?
# Install required libraries
# !pip install -q xarray_subset_grid@git+https://github.com/asascience-open/xarray-subset-grid.git
# !pip install -q s3fs cftime xarray cf-xarray fsspec dask h5netcdf
import cf_xarray #noqa
import fsspec
import numpy as np
import xarray as xr
# Open the dataset from NODD s3 bucket directly
fs = fsspec.filesystem("s3", anon=True)
ds = xr.open_dataset(
fs.open(
"s3://noaa-nos-ofs-pds/sfbofs/netcdf/202407/sfbofs.t21z.20240722.regulargrid.f040.nc"
),
chunks={},
drop_variables=[]
)
ds
<xarray.Dataset> Size: 68MB
Dimensions: (Depth: 21, ny: 329, nx: 553, time: 1)
Coordinates:
* Depth (Depth) float64 168B 0.0 1.0 2.0 4.0 ... 70.0 80.0 90.0 100.0
Latitude (ny, nx) float64 1MB dask.array<chunksize=(329, 553), meta=np.ndarray>
Longitude (ny, nx) float64 1MB dask.array<chunksize=(329, 553), meta=np.ndarray>
* time (time) datetime64[ns] 8B 2024-07-24T12:59:59.999999744
Dimensions without coordinates: ny, nx
Data variables:
h (ny, nx) float64 1MB dask.array<chunksize=(329, 553), meta=np.ndarray>
mask (ny, nx) float64 1MB dask.array<chunksize=(329, 553), meta=np.ndarray>
Times (time) |S26 26B dask.array<chunksize=(1,), meta=np.ndarray>
zeta (time, ny, nx) float32 728kB dask.array<chunksize=(1, 329, 553), meta=np.ndarray>
zetatomllw (time, ny, nx) float32 728kB dask.array<chunksize=(1, 329, 553), meta=np.ndarray>
u_eastward (time, Depth, ny, nx) float32 15MB dask.array<chunksize=(1, 11, 165, 277), meta=np.ndarray>
v_northward (time, Depth, ny, nx) float32 15MB dask.array<chunksize=(1, 11, 165, 277), meta=np.ndarray>
temp (time, Depth, ny, nx) float32 15MB dask.array<chunksize=(1, 11, 165, 277), meta=np.ndarray>
salt (time, Depth, ny, nx) float32 15MB dask.array<chunksize=(1, 11, 165, 277), meta=np.ndarray>
Attributes: (12/14)
title: SFBOFS
institution: School for Marine Science and Technology
source: FVCOM_4.4.7
history: model started at: 22/07/2024 21:33
references: http://fvcom.smast.umassd.edu, https://githu...
Conventions: CF-1.0
... ...
Tidal_Forcing: Tidal Forcing Time Series Title: sfbofs late...
River_Forcing: THERE ARE 9 RIVERS IN THIS MODEL.\nRIVER INF...
GroundWater_Forcing: GROUND WATER FORCING IS OFF!
Surface_Heat_Forcing: FVCOM variable surface heat forcing file:\nF...
Surface_Wind_Forcing: FVCOM variable surface Wind forcing:\nFILE N...
Surface_PrecipEvap_Forcing: SURFACE PRECIPITATION FORCING IS OFFFirst, check to make sure the dataset is recognized as a 2d regular grid
ds.xsg.grid.name
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[3], line 1
----> 1 ds.xsg.grid.name
File ~/Hazmat/ThirdPartyPackages/xarray-subset-grid/.pixi/envs/all/lib/python3.12/site-packages/xarray/core/common.py:300, in AttrAccessMixin.__getattr__(self, name)
298 with suppress(KeyError):
299 return source[name]
--> 300 raise AttributeError(
301 f"{type(self).__name__!r} object has no attribute {name!r}"
302 )
AttributeError: 'Dataset' object has no attribute 'xsg'
We can subset down to the variables we care about, while keeping the grid information for later analysis
ds_currents = ds.xsg.subset_vars(['u_eastward', 'v_northward'])
ds_currents
Now subset to the surface
ds_surface_currents = ds_currents.xsg.subset_vertical_level(0)
ds_surface_currents
Finally subset to the target region

polygon = np.array(
[
[-122.68750983577246, 37.8236386694975],
[-122.68750983577246, 37.65884889475059],
[-122.44817616264763, 37.65884889475059],
[-122.44817616264763, 37.8236386694975],
[-122.68750983577246, 37.8236386694975],
]
)
ds_currents_surface_subset = ds_surface_currents.xsg.subset_polygon(polygon)
ds_currents_surface_subset
Plot and see the result!
ds_currents_surface_subset.u_eastward.cf.isel(time=0).cf.plot(
x="longitude", y="latitude", cmap="viridis"
)
f"Subset dataset size: {ds_currents_surface_subset.nbytes * 1.0e-6} Mb"