def __call__(self, **kwargs) : # input : {axisName: condition, ...} # standardize the axisNames for axisName, condition in kwargs.iteritems() : del kwargs[axisName] if type(condition) == tuple : condition = tuple(sorted(condition[:2]))+condition[2:] kwargs[Axes.standardize(axisName)] = condition output = self.extract_data(**kwargs) # do we need to interpolate along an axis ? for axisName, condition in kwargs.iteritems() : # did we ask for a single value for an axis # yet still have this axis in the output variable ? # this signifies extract_data returned the neighbouring points # because this single value is not on the grid if type(condition) != tuple and axisName in output.axes : output.data # kludge for grib files firstSlice = [slice(None)]*len(output.shape) secondSlice = [slice(None)]*len(output.shape) firstSlice[output.axes.index(axisName)] = 0 secondSlice[output.axes.index(axisName)] = 1 # linear interpolation ! try : output = \ (output[secondSlice] - output[firstSlice])/\ (output.axes[axisName].data[1] - \ output.axes[axisName].data[0])\ *(condition - output.axes[axisName].data[0]) \ + output[firstSlice] except IndexError : # sometimes, due to rounding errors, extract_data will return one # value when two were expected, thus output...[1] fails output = output[firstSlice] output.metadata[axisName] = condition return output
def __init__(self, variables=None, axes=None) : if axes == None : self.axes = Axes() else : self.axes = axes if variables == None : self.variables = {} else : self.variables = variables
def mean(self, axisNames) : # input can either either be like 'zy' or like ['lev', 'lat'] # turn the 'zy' into ['z', 'y'] axisNames = list(axisNames) for i in range(len(axisNames)) : axisNames[i] = Axes.standardize(axisNames[i]) # levels must be averaged first # 'level' must be at the top of the list if axisNames[i] == 'level' : del axisNames[i] axisNames = ['level'] + axisNames return self.averager(axisNames)
def write(self, filePath) : from netCDF4 import Dataset # making sure the variable's axes are given # to the file is the user's responsability with Dataset(filePath, 'w') as output : for axisName, axis in self.axes.iteritems() : axisName = Axes.ncStandardize(axisName) output.createDimension(axisName, len(axis)) if axisName == 'time' : output.createVariable('time', int, ('time',)) output.variables['time'].units = 'seconds since 1970-1-1' from datetime import datetime epoch = datetime(1970, 1, 1) output.variables['time'][:] = [ (instant-epoch).total_seconds() for instant in axis.data] else : # this is a real axis with information worth recording if axis.units != 'indices' or len(axis) - 1 != axis[-1] : output.createVariable( axisName, type(np.asscalar(axis.data.ravel()[0])), (axisName,)) output.variables[axisName][:] = axis.data if axis.units != None : output.variables[axisName].units = axis.units # TODO metadata... for variableName, variable in self.variables.iteritems() : if variableName == '~' : variableName = 'unknown' output.createVariable( variableName, type(np.asscalar(variable.data.ravel()[0])), tuple( [Axes.ncStandardize(axisName) for axisName in variable.axes.keys()])) if 'units' in variable.metadata : output.variables[variableName].units = variable.units output.variables[variableName][:] = variable.data