Source code for envtoolkit.nc


""" Module that handles functions relative to NetCDF files """


[docs]def copy_ncstruct(fin, fout): """ Copy the internal structure of a NetCDF file. It copies the dimension names, variable names and attributes from a file to another file. :param netCDF4.Dataset fin: Source file :param netCDF4.Dataset fout: Destination file .. note :: The file contents are not copied! Only the structure of the file .. code-block :: python from netCDF4 import Dataset import envtoolkit.nc fin = Dataset("source_file.nc", "r") fout = Dataset("dest_file.nc", "w") # copy the dimensions/variables/attributes of # the source file into the dest file envtoolkit.nc.copy_ncstruct(fin, fout) # Fill in the variable of the destination file # closing the files fin.close() fout.close() :param netCDF4.Dataset fin: the source file :param netCDF4.Dataset fout: the destination file """ # Working on the dimensions dim = fin.dimensions for dimname, dimval in zip(dim.keys(), dim.values()): if dimval.isunlimited(): # If record dimension, then we also set # the output dimension to unlimited fout.createDimension(dimname, None) else: # len(v) is the way to recover the value of the dimension # cf. netCDF4 documentation fout.createDimension(dimname, len(dimval)) # Working on the variables var = fin.variables for varname, varval in zip(var.keys(), var.values()): # we create a variable of the same # type and dimensions as in the input file fout.createVariable(varname, varval.datatype, varval.dimensions) vout = fout.variables[varname] # we loop over the variable attributes # varval.ncattrs -> recover the attribute names ("units", etc) for attr in varval.ncattrs(): vout.setncattr(attr, getattr(varval, attr)) # We do the same thing for the global (file) attributes for attr in fin.ncattrs(): fout.setncattr(attr, getattr(fin, attr))
[docs]def extract_date(fin, timevar_name="time", units=None, calendar='gregorian', timeoff=0): """ Converts the time array of a NetCDF file into a date. :param netCDF4.Dataset fin: the NetCDF file :param str timevar_name: the name of the time variable :param str units: the time units (used only if no time units in the the file) :param str calendar: the time calendar (used only if no time units in the the file) :param float timeoff: A time offset that is *added* to the time array :return: an array of :py:class:`datetime.datetime` object :rtype: numpy.array """ from netcdftime import utime try: # try to extract the time variable from the file timevar = fin.variables[timevar_name] except: raise IOError("The %s variable does not exist in the input file" % timevar_name) # check the existence of the units attribute if "units" in timevar.ncattrs(): units = getattr(timevar, 'units') else: # if no time units, we check that the unit argument is set, and that it is in right format if units is None: raise IOError("No time units provided in the file. Provide the units as an argument") else: if not isinstance(units, str): raise ValueError("The units argument must be a string") # check the existence of the calendar attribute if "calendar" in timevar.ncattrs(): calendar = getattr(timevar, 'calendar') else: # if no time calendar, we check that the unit argument is set, and that it is in right format if calendar is None: print('No calendar provided. Gregorian calendar is used') calendar = 'gregorian' else: if not isinstance(calendar, str): raise ValueError("The calendar argument must be a string") # creates the utime object for conversion cdftime = utime(units, calendar=calendar) # conversion of numerics into date date = cdftime.num2date(timevar[:] + timeoff) return date