Skip to content

Instantly share code, notes, and snippets.

@lukecampbell
Last active August 29, 2015 14:16
Show Gist options
  • Save lukecampbell/6cbadcc9a8e9b722452f to your computer and use it in GitHub Desktop.
Save lukecampbell/6cbadcc9a8e9b722452f to your computer and use it in GitHub Desktop.
CDL Output in Python
def printify(attr):
'''
Returns a prettier version of the attribute
'''
if isinstance(attr, basestring):
return '"%s"' % attr
return attr
def dtype_to_cdl(dtype):
dtype_map = {
'S' : 'char',
'b' : 'byte',
'h' : 'short',
'i' : 'int',
'l' : 'int64',
'B' : 'ubyte',
'H' : 'ushort',
'I' : 'uint',
'L' : 'uint64',
'u' : 'uint',
'f' : 'float',
'd' : 'double'
}
return dtype_map[dtype]
def dump_cdl(nc):
'''
Returns a string dump of the CDL for a netCDF File
'''
buf = []
varnames = nc.variables.keys()
varnames.sort()
buf.append('dimensions:')
for dim in nc.dimensions:
if nc.dimensions[dim].isunlimited():
buf.append(' %s = UNLIMITED; // (%s currently)' % (dim, len(nc.dimensions[dim])))
else:
buf.append(' %s = %s;' % (dim, len(nc.dimensions[dim])))
buf.append('variables:')
for v in varnames:
datatype = nc.variables[v].dtype.char
if nc.variables[v].dimensions:
dims = '(%s)' % ', '.join(nc.variables[v].dimensions)
else:
dims = ''
s = ' %s %s%s;' % (dtype_to_cdl(datatype), v, dims)
buf.append(s)
for attrname in vars(nc.variables[v]):
buf.append(' %s:%s = %s;' % (v, attrname, printify(getattr(nc.variables[v], attrname))))
buf.append('// global attributes:')
for attr in vars(nc):
buf.append(' :%s = %s;' % (attr, printify(getattr(nc, attr))))
return '\n'.join(buf)
def copy_var(nc, nc_out, var, rename=None, new_dims=None, new_dtype=None, copy_data=True):
'''
Copies the variable var from nc to nc_out
Optionally accepts a rename parameter, a new set of dimensions and a new
dtype, if any of these are set the variable data will not be copied over
'''
# Should we copy the data?
copy_data = copy_data and rename is None and new_dims is None and new_dtype is None
rename = rename or var
new_dims = new_dims or nc.variables[var].dimensions
new_dtype = new_dtype or nc.variables[var].dtype
fill_value = getattr(nc.variables[var],"_FillValue", None)
nc_out.createVariable(rename, new_dtype, new_dims, fill_value=fill_value)
for varattr in vars(nc.variables[var]):
if varattr == '_FillValue':
continue
setattr(nc_out.variables[rename], varattr, getattr(nc.variables[var], varattr))
if copy_data:
nc_out.variables[rename][:] = nc.variables[var][:]
def copy_dim(nc, nc_out, dim):
'''
Copies the dimension dim from nc to nc_out
'''
if nc.dimensions[dim].isunlimited():
nc_out.createDimension(dim)
else:
nc_out.createDimension(dim, len(nc.dimensions[dim]))
def copy_dataset(nc, nc_out, var_skip=None):
'''
Copies a dataset from one netCDF Dataset instance to another
accepts a list of variables to skip
'''
var_skip = var_skip or []
# Dimensions
for dim in nc.dimensions:
copy_dim(nc, nc_out, dim)
# Global Attributes
for attr in vars(nc):
setattr(nc_out, attr, getattr(nc, attr))
# Variables
for var in nc.variables:
if var in var_skip:
continue
copy_var(nc, nc_out, var)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment