Stream: xarray

Topic: Creating a CF-Compliant curvilinearly gridded file


view this post on Zulip Scott Pearse (Jan 31 2022 at 23:11):

I'm trying to convert a binary dataset into CF Compliant NetCDF. Thank you in advance for any thoughts, tips, and suggestions.

I have a file on glade that has float32 bit values for a single variable on a 120x120x14 grid.
/glade/scratch/pearse/marshall/coen/FLOAT/u.float.0212

I need to create a NetCDF file based on this 3D variable. It needs a vertical Coordinate Variable that has each vertical coordinate described as a function of X, Y, and Z, described by the array in following file:
/glade/scratch/pearse/marshall/coen/FLOAT/ELEVATION.float

The horizontal and vertical coordinate variables can be anything, as long as they're monotonically increasing.

So far I'm loading the file as follows. I'm not sure how to designate the ELEVATION values as a coordinate variable.

import xarray as xr
import numpy as np

u = np.fromfile("/glade/scratch/pearse/marshall/coen/FLOAT/u.float.0212", dtype=np.single)
u3d = u.reshape((120,120,14))

E = np.fromfile("/glade/scratch/pearse/marshall/coen/FLOAT/ELEVATION.float", dtype=np.single)
E3d = E.reshape((120,120,14))

... Create a dataset with coordainte variables and CF compliant attributes ...

Thanks again for any help - Scott

view this post on Zulip Scott Pearse (Feb 01 2022 at 15:26):

I have a typo in my above message - The horizontal Coordinate Variables can be anything - but the vertical Coordinate Variable must be defined by the 120x120x14 ELEVATION file. Thanks again.

view this post on Zulip Scott Pearse (Feb 01 2022 at 20:03):

Answering my open question:

zDim = 14
yDim = 120
xDim = 120
lats = np.linspace(start=0, stop=44444.4, num=yDim);
lons = np.linspace(start=0, stop=44444.4, num=xDim);
E = np.fromfile(dataDir + "/ELEVATION.float", dtype=np.single)
E3d = E.reshape((14,120,120))

timestep = 212
b = np.fromfile(dataDir + "/b.float.0" + str(timestep), dtype=np.single)
b3d = b.reshape(1,zDim,yDim,xDim)
t = pd.date_range("2021-12-30 10:00:00", periods=1) + timedelta(minutes=timestep)
ds = xr.DataArray(
name = "b",
data = b3d,
dims=["time","z","y","x"],
coords=dict(
lon=(["x"],lons),
lat=(["y"],lats),
ele=(["z","y","x"],E3d),
time=t,
)
)

ds.lon.attrs['axis'] = "X"
ds.lat.attrs['axis'] = "Y"
ds.ele.attrs['axis'] = "Z"
ds.time.attrs['axis'] = "T"

ds.lat.attrs['units'] = 'm'
ds.lon.attrs['units'] = 'm'
ds.ele.attrs['units'] = 'm'

ds.to_netcdf( dataDir + "/" + str(timestep) + ".nc")


Last updated: May 16 2025 at 17:14 UTC