Skip to content

Instantly share code, notes, and snippets.

@Datseris
Created October 27, 2020 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Datseris/f52926b513b788ae103aa5978b8a3d09 to your computer and use it in GitHub Desktop.
Save Datseris/f52926b513b788ae103aa5978b8a3d09 to your computer and use it in GitHub Desktop.
xarray to ClimArray
using ClimateBase, Dates
# This needs to numpy, xarray and dask installed from Conda
using PyCall
xr = pyimport("xarray")
np = pyimport("numpy")
"""
climarray_from_xarray(xa, fieldname, name = Symbol(fieldname))
Load underlying field with given `fieldname` from the given xarray instance `xa`,
optionally providing a name for it. This `xa` can be loaded with commands like
```julia
using PyCall
xr = pyimport("xarray")
ERA5_files = "T_W_F_*.nc"
xa = xr.open_mfdataset(ERA5_files)
X = climarray_from_xarray(xa, "w", "vertical velocity")
```
"""
function climarray_from_xarray(xa, fieldname, name = Symbol(fieldname))
w = getproperty(xa, Symbol(fieldname))
raw_data = Array(w.values)
dnames = collect(w.dims) # dimensions in string name
dim_values = []
for d in dnames
x = getproperty(w, d).values
if d ≠ "time"
push!(dim_values, x)
else
# This date specification assumes up to day sampling (hence the 1:10)
dates = [np.datetime_as_string(y)[1:10] for y in x]
dates = Date.(dates)
push!(dim_values, dates)
end
end
@assert collect(size(raw_data)) == length.(dim_values)
actual_dims = Tuple(create_dims_xarray(dnames, dim_values))
ca = ClimArray(raw_data, actual_dims, name; attrib = w.attrs)
end
function create_dims_xarray(dnames, dim_values)
true_dims = ClimateBase.to_proper_dimensions(dnames)
optimal_values = ClimateBase.vector2range.(dim_values)
return optimal_values .|> true_dims
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment