def format_axis(axis, name=None, force=True, recreate=False, format_subaxes=True, nodef=True, mode='warn', **kwargs): """Format a MV2 axis according to its generic name :Params: - **axis**: A :mod:`numpy` or :mod:`MV2` variabe. - **name**: Single or list of generic axis names. It should be one of those listed by :attr:`CF_AXIS_SPECS`.If None, it is guessed with :func:`match_known_axis`. - **force**, optional: Overwrite attributes in all cases. - **nodef**, optional: Remove location specification when it refers to the default location (:attr:`DEFAULT_LOCATION`). - **axes2d_<param>**, optional: <param> is passed to :func:`~vacumm.misc.grid.misc.create_axes2d` for 2D axes. - **recreate**, optional: Force recreation of axes using either - Other parameters are passed as attributes. :Examples: >>> axis1d = format_axis(array1d, 'lon') >>> axis2d = format_axis(array2d, 'lon_u', axes2d_iid = 'xi', axes2d_jid = 'xi', recreate=True) """ # Guess best generic name from a list if name is None: return axis if isinstance(name, (list, tuple)): for nm in name: if match_obj(axis, nm): name = nm break # Check specs if name is None: # guess it name = match_known_axis(axis) if not name: if mode == 'warn': warn("Can't guess CF axis name") return axis elif mode == 'silent': return axis else: raise KeyError("Variable does not match any CF axis") elif name not in CF_AXIS_SPECS: if mode == 'warn': warn("Generic axis name not found '%s'." % name) return axis elif mode == 'silent': return axis else: raise KeyError( "Generic axis name not found '%s'. Please choose one of: %s" % (name, ', '.join(CF_AXIS_SPECS.keys()))) specs = CF_AXIS_SPECS[name] # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # Always a MV2 axis (1D or 2D) axis._oldid = axis.id kwaxed2d = kwfilter(kwargs, 'axes2d_') if not isaxis(axis) or recreate: if len(axis.shape) == 1: axis = cdms2.createAxis(axis) else: xy = specs['axis'].lower() kwaxed2d[xy] = axis axis = create_axes2d(**kwaxed2d) return axis axis2d = len(axis.shape) == 2 # Apply specs # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # - remove default location if nodef: for att in 'id', 'long_name', 'standard_name': # sname = stype+'s' if att not in specs: continue if get_loc(specs[att], att) == DEFAULT_LOCATION: specs[att] = [no_loc_single(specs[att][0], att)] # - id if force or axis.id.startswith('variable_') or axis.id.startswith('axis_'): axis.id = specs['id'][0] # - attributes for att, val in cf2atts(specs, exclude=['axis'] if axis2d else None, **kwargs).items(): if force or not getattr(axis, att, ''): setattr(axis, att, val) # - store cf name axis._vacumm_cf_name = axis.id # Sub-axes for 2D axes if axis2d and format_subaxes: format_axis(axis.getAxis(-1), specs['iaxis']) format_axis(axis.getAxis(-2), specs['jaxis']) return axis
def get_spec(var1, var2=None, dx=None, dy=None, verbose=False, fft=False, **kwargs): """Get the spectrum of a 2D variable :Return: specvar,nbwave,dk """ # Get the resolution in meters kwresol = kwfilter(kwargs, 'resol_') if None in [dx, dy]: if not cdms2.isVariable(var1): raise TypeError('var1 must be a MV2 array to compute dx and dy') kwresol.setdefault('proj', True) ldx, ldy = resol(var1, **kwresol) dx = dx or ldx dy = dy or ldy if N.ma.isMA(var1): var1= var1.filled(0.) if N.ma.isMA(var2): var2 = var2.filled(0.) # Part 1 - estimate of the wavenumbers [kx,ky,kkx,kky,kk,Lx,Ly] = get_kxky(var1, dx, dy, verbose=verbose) if verbose: print "dx = %s, fy = %s " %(dx,dy) print "kx = ",kx[0:3] print "ky = ",ky[0:3] print "kkx[0:3,2] = ",kkx[0:3,2] print "kky[0:3,1] = ",kky[0:3,1] print "kk[0:3,3] = ",kk[0:3,3] print "shape",kx.shape,ky.shape,kkx.shape,kky.shape,kk.shape # Part 2 - estimate of the spectrum # - fast fourier transform if fft: hat_phi1=N.fft.fft2(var1) hat_phi1=hat_phi1*hat_phi1.conj() hat_phi1=hat_phi1.real.copy() # useless else: hat_phi1 = var1 if var2 is not None: if fft: hat_phi2=N.fft.fft2(var2) hat_phi2=hat_phi2*hat_phi2.conj() hat_phi2=hat_phi2.real.copy() # useless else: hat_phi2 = var2 hat_spec = hat_phi1 + hat_phi2 else: hat_spec = hat_phi1 # - integration of the spectrum # shift to have values centered on the intervals dk = kx[1] - kx[0] dk_half = dk/2 # half of the interval k_= kx[0:min(var1.shape[1],var1.shape[0])/2] + dk specvar = k_*0 for i in range(len(k_)): # get indexes that satisfy two conditions # integration over a spectral width specvar[i] = ( hat_spec[ (kk<=k_[i]+dk_half) & (kk>k_[i]-dk_half) ] ).sum() # Normalisation (Danioux 2011) specvar /= (var1.shape[1]*var1.shape[0])**2 * dk # Dimensionalization to be able to compare with the litterature nbwave = k_*1000.0/2.0/N.pi # from rad/m to km/m dk *= 1000.0/2.0/N.pi specvar *= 2.0*N.pi/1000.0 if verbose: if var2 is not None: print "\n Normalized co-spectrum : \n",specvar else: print "\n Normalized spectrum : \n",specvar return specvar,nbwave,dk
def format_var(var, name=None, force=True, format_axes=True, order=None, nodef=True, mode='warn', **kwargs): """Format a MV2 variable according to its generic name :Params: - **var**: A :mod:`numpy` or :mod:`MV2` variabe. - **name**: Generic name of variable. It should be one of those listed by :attr:`CF_VAR_SPECS`. If None, it is guessed with :func:`match_known_var`. - **force**, optional: Overwrite attributes in all cases. - **format_axes**, optional: Also format axes. - **nodef**, optional: Remove location specification when it refers to the default location (:attr:`DEFAULT_LOCATION`). - **mode**: "silent", "warn" or "raise". - Other parameters are passed as attributes, except those: - present in specifications to allow overriding defaults, - starting with 'x', 'y', or 't' which are passed to :func:`format_axis`. :Examples: >>> var = format_var(myarray, 'sst', valid_min=-2, valid_max=100) """ # Filter keywords for axis formating axismeths = {'t': 'getTime', 'y': 'getLatitude', 'x': 'getLongitude'} kwaxes = {} for k in axismeths.keys(): kwaxes[k] = kwfilter(kwargs, k + '_') # Always a MV2 array if not cdms2.isVariable(var): var = MV2.asarray(var) # Check specs if name is None: # guess it name = match_known_var(var) if not name: if mode == 'warn': warn("Can't guess cf name") return var elif mode == 'silent': return var else: raise KeyError("Variable does not match any CF var") elif name not in CF_VAR_SPECS and name not in CF_AXIS_SPECS: if var.id in CF_VAR_SPECS or var.id in CF_AXIS_SPECS: name = var.id elif mode == 'warn': warn("Generic var name not found '%s'." % name) return var elif mode == 'silent': return var else: raise KeyError( "Generic var name not found '%s'. Please choose one of: %s" % (name, ', '.join(CF_VAR_SPECS.keys() + CF_AXIS_SPECS.keys()))) isaxis = name in CF_AXIS_SPECS if isaxis: specs = CF_AXIS_SPECS[name].copy() if 'axis' in specs: del specs['axis'] else: specs = CF_VAR_SPECS[name].copy() # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # - remove default location if nodef: refloc = specs.get('physloc', None) or DEFAULT_LOCATION for att in 'id', 'long_name', 'standard_name': if get_loc(specs[att], att) == refloc: specs[att] = [no_loc_single(specs[att][0], att)] name = specs['id'][0] # - id if ((force is True or force in [2, 'id', 'all']) or var.id.startswith('variable_') or (isaxis and var.id.startswith('axis_'))): # FIXME: use regexp var.id = name # - attributes forceatts = (force is True or force in ['atts', 'all'] or (isinstance(force, int) and force > 0)) for att, val in cf2atts(specs, **kwargs).items(): if forceatts or not getattr(var, att, ''): setattr(var, att, val) # - physical location loc = get_loc(var, mode='ext') if not loc and 'physloc' in specs: loc = specs['physloc'] if loc: if 'physloc' in specs and loc == specs['physloc']: var._vacumm_cf_physloc = loc.lower() set_loc(var, loc) # - store cf name var._vacumm_cf_name = name # Axes if format_axes: # Order order = var.getOrder() if not isinstance(order, basestring) else order if order is not None: if not re.match('^[xyzt-]+$', order): raise VACUMMError("Wrong cdms order type: " + order) if len(order) != var.ndim: raise VACUMMError( "Cdms order should be of length %s instead of %s" % (var.ndim, len(order))) # First check if 'axes' in specs: axspecs = specs['axes'] formatted = [] for key, meth in axismeths.items(): axis = getattr(var, meth)() if order is not None: order.replace(key, '-') if axis is not None: format_axis(axis, axspecs[key], **kwaxes[key]) formatted.append(key) # Check remaining simple axes (DOES NOT WORK FOR 2D AXES) if order is not None and order != '-' * len(order): for key in axismeths.keys(): if key in order and key not in formatted: axis = var.getAxis(order.index(key)) format_axis(axis, axspecs[key], **kwaxes[key]) return var
def plot(self, var=None, orig=True, tide=True, cotes=True, highs=True, lows=True, zeros=True, legend=True, title=None, savefig=None, savefigs=None, show=True, marker='o', **kwargs): # Which variable? vtypes = 'orig', 'tide', 'highs', 'lows', 'zeros', 'cotes' if var is not None: assert var in vtypes for vt in vtypes: exec "%s = %s"%(vt, vt==var) # Plot params # - specific kwplot = {} for vt in vtypes: kwplot[vt] = kwfilter(kwargs, vt) kwplot[vt].update(show=False) kwplot[vt].update(title=False) # - global nt = self.data['base'].shape[0] times = T.mpl(self.data['base'][0:nt:nt-1].getTime()) kwargs.setdefault('xmin', times[0]) kwargs.setdefault('xmax', times[1]) # - complete for vt in vtypes: tmp = kwargs.copy() tmp.update(kwplot[vt]) kwplot[vt] = tmp anom = not (orig or highs or lows or zeros) # Original signal if orig: kwplot['orig'].setdefault('color', '#888888') kwplot['orig'].setdefault('zorder', '10') curve(self.sea_level(), **kwplot['orig']) # High tides if highs: kwplot['highs'].setdefault('color', 'r') kwplot['highs'].setdefault('linewidth', 0) kwplot['highs'].setdefault('markersize', 5) kwplot['highs'].setdefault('zorder', '12') curve(self.highs(), marker, **kwplot['highs']) # Low tides if lows: kwplot['lows'].setdefault('color', 'b') kwplot['lows'].setdefault('linewidth', 0) kwplot['lows'].setdefault('markersize', 5) kwplot['lows'].setdefault('zorder', '12') curve(self.lows(), marker, **kwplot['lows']) # Zeros if zeros: kwplot['zeros'].setdefault('color', 'k') kwplot['zeros'].setdefault('linewidth', 0) kwplot['zeros'].setdefault('markersize', 5) kwplot['zeros'].setdefault('zorder', '12') curve(self.zeros(), marker, **kwplot['zeros']) # Tidal signal if tide: kwplot['orig'].setdefault('color', 'k') kwplot['orig'].setdefault('zorder', '11') curve(self.tide(anom=anom), **kwplot['tide']) # Surcote/decotes if cotes: kwplot['cotes'].setdefault('color', 'g') kwplot['cotes'].setdefault('zorder', '12') curve(self.cotes(anom=anom), **kwplot['cotes']) # Misc if title is None: if var is not None: title = var.title() else: title = 'Marigraph' if title: P.title(title) if savefig: P.savefig(savefig, **kwfilter(kwargs, 'savefig')) if savefigs: Savefigs(savefigs, **kwfilter(kwargs, 'savefigs')) if show: P.show()
def plot(self, var=None, orig=True, tide=True, cotes=True, highs=True, lows=True, zeros=True, legend=True, title=None, savefig=None, savefigs=None, show=True, marker='o', **kwargs): # Which variable? vtypes = 'orig', 'tide', 'highs', 'lows', 'zeros', 'cotes' if var is not None: assert var in vtypes for vt in vtypes: exec("%s = %s"%(vt, vt==var)) # Plot params # - specific kwplot = {} for vt in vtypes: kwplot[vt] = kwfilter(kwargs, vt) kwplot[vt].update(show=False) kwplot[vt].update(title=False) # - global nt = self.data['base'].shape[0] times = T.mpl(self.data['base'][0:nt:nt-1].getTime()) kwargs.setdefault('xmin', times[0]) kwargs.setdefault('xmax', times[1]) # - complete for vt in vtypes: tmp = kwargs.copy() tmp.update(kwplot[vt]) kwplot[vt] = tmp anom = not (orig or highs or lows or zeros) # Original signal if orig: kwplot['orig'].setdefault('color', '#888888') kwplot['orig'].setdefault('zorder', '10') curve(self.sea_level(), **kwplot['orig']) # High tides if highs: kwplot['highs'].setdefault('color', 'r') kwplot['highs'].setdefault('linewidth', 0) kwplot['highs'].setdefault('markersize', 5) kwplot['highs'].setdefault('zorder', '12') curve(self.highs(), marker, **kwplot['highs']) # Low tides if lows: kwplot['lows'].setdefault('color', 'b') kwplot['lows'].setdefault('linewidth', 0) kwplot['lows'].setdefault('markersize', 5) kwplot['lows'].setdefault('zorder', '12') curve(self.lows(), marker, **kwplot['lows']) # Zeros if zeros: kwplot['zeros'].setdefault('color', 'k') kwplot['zeros'].setdefault('linewidth', 0) kwplot['zeros'].setdefault('markersize', 5) kwplot['zeros'].setdefault('zorder', '12') curve(self.zeros(), marker, **kwplot['zeros']) # Tidal signal if tide: kwplot['orig'].setdefault('color', 'k') kwplot['orig'].setdefault('zorder', '11') curve(self.tide(anom=anom), **kwplot['tide']) # Surcote/decotes if cotes: kwplot['cotes'].setdefault('color', 'g') kwplot['cotes'].setdefault('zorder', '12') curve(self.cotes(anom=anom), **kwplot['cotes']) # Misc if title is None: if var is not None: title = var.title() else: title = 'Marigraph' if title: P.title(title) if savefig: P.savefig(savefig, **kwfilter(kwargs, 'savefig')) if savefigs: Savefigs(savefigs, **kwfilter(kwargs, 'savefigs')) if show: P.show()
def format_axis(axis, name, force=True, recreate=False, format_subaxes=True, nodef=True, **kwargs): """Format a MV2 axis according to its generic name :Params: - **var**: A :mod:`numpy` or :mod:`MV2` variabe. - **name**: Single or list of generic axis names. It should be one of those listed by :attr:`GENERIC_AXIS_NAMES`. - **force**, optional: Overwrite attributes in all cases. - **nodef**, optional: Remove location specification when it refers to the default location (:attr:`DEFAULT_LOCATION`). - **axes2d_<param>**, optional: <param> is passed to :func:`~vacumm.misc.grid.misc.create_axes2d` for 2D axes. - **recreate**, optional: Force recreation of axes using either - Other parameters are passed as attributes. :Examples: >>> axis1d = format_axis(array1d, 'lon') >>> axis2d = format_axis(array2d, 'lon_u', axes2d_iid = 'xi', axes2d_jid = 'xi', recreate=True) """ # Guess best generic name from a list if name is None: return axis if isinstance(name, (list, tuple)): for nm in name: if match_obj(axis, nm): name = nm break # Check specs if name not in GENERIC_AXIS_NAMES: raise KeyError("Generic axis name not found '%s'. Please choose one of: %s"%( name, ', '.join(GENERIC_AXIS_NAMES))) specs = AXIS_SPECS[name] # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # Always a MV2 axis (1D or 2D) axis._oldid = axis.id kwaxed2d = kwfilter(kwargs, 'axes2d_') if not isaxis(axis) or recreate: if len(axis.shape)==1: axis = cdms2.create_axis(axis) else: xy = specs['axis'].lower() kwaxed2d[xy] = axis axis = create_axes2d(**kwaxed2d) return axis axis2d = len(axis.shape)==2 # Apply specs # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # - remove default location if nodef: for stype in 'name', 'long_name', 'standard_name': sname = stype+'s' if sname not in specs: continue if get_loc(specs[sname], stype)==DEFAULT_LOCATION: specs[sname] = [no_loc_single(specs[sname][0], stype)] # - id if force or axis.id.startswith('variable_') or axis.id.startswith('axis_'): axis.id = specs['names'][0] # - attributes for att, val in cf2atts(specs, exclude=['axis'] if axis2d else None, **kwargs).items(): if force or not getattr(axis, att, ''): setattr(axis, att, val) # - store cf name axis._vacumm_cf_name = axis.id # Sub-axes for 2D axes if axis2d and format_subaxes: format_axis(axis.getAxis(-1), specs['iaxis'][0]) format_axis(axis.getAxis(-2), specs['jaxis'][0]) return axis
def format_var(var, name, force=True, format_axes=True, order=None, nodef=True, **kwargs): """Format a MV2 variable according to its generic name :Params: - **var**: A :mod:`numpy` or :mod:`MV2` variabe. - **name**: Generic name of variable. It should be one of those listed by :attr:`GENERIC_VAR_NAMES`. - **force**, optional: Overwrite attributes in all cases. - **format_axes**, optional: Also format axes. - **nodef**, optional: Remove location specification when it refers to the default location (:attr:`DEFAULT_LOCATION`). - Other parameters are passed as attributes, except those: - present in specifications to allow overriding defaults, - starting with 'x', 'y', or 't' which are passed to :func:`format_axis`. :Examples: >>> var = format_var(myarray, 'sst', valid_min=-2, valid_max=100) """ # Filter keywords for axis formating axismeths = {'t':'getTime', 'y':'getLatitude', 'x':'getLongitude'} kwaxes = {} for k in axismeths.keys(): kwaxes[k] = kwfilter(kwargs, k+'_') # Always a MV2 array var = MV2.asarray(var) # Check specs if name not in GENERIC_VAR_NAMES: if var.id in GENERIC_VAR_NAMES: name = var.id else: raise KeyError("Generic var name not found '%s'. Please choose one of: %s"%( name, ', '.join(GENERIC_VAR_NAMES))) specs = VAR_SPECS[name].copy() # - merge kwargs and specs for key, val in kwargs.items(): if val is None or key not in specs: continue # Check type if not isinstance(val, list) and isinstance(specs[key], list): val = [val] # Set specs[key] = val del kwargs[key] # - remove default location if nodef: refloc = specs.get('physloc', DEFAULT_LOCATION) for stype in 'name', 'long_name', 'standard_name': sname = stype+'s' if sname not in specs: continue if get_loc(specs[sname], stype)==refloc: specs[sname] = [no_loc_single(specs[sname][0], stype)] name = specs['names'][0] # - id if force or var.id.startswith('variable_'): var.id = name # - attributes for att, val in cf2atts(specs, **kwargs).items(): if force or not getattr(var, att, ''): setattr(var, att, val) # - physical location loc = get_loc(var, mode='ext') if not loc and 'physloc' in specs: loc = specs['physloc'] if loc: if 'physloc' in specs and loc in specs['physloc']: var._vacumm_cf_physloc = loc.lower() set_loc(var, loc) # - store cf name var._vacumm_cf_name = name # Axes if format_axes: # Order order = var.getOrder() if not isinstance(order, basestring) else order if order is not None: if not re.match('^[xyzt-]+$', order): raise VACUMMError("Wrong cdms order type: "+order) if len(order)!=var.ndim: raise VACUMMError("Cdms order should be of length %s instead of %s"%(var.ndim, len(order))) # First check axspecs = specs['axes'] formatted = [] for key, meth in axismeths.items(): axis = getattr(var, meth)() if order is not None: order.replace(key, '-') if axis is not None: format_axis(axis, axspecs[key], **kwaxes[key]) formatted.append(key) # Check remaining simple axes (DOES NOT WORK FOR 2D AXES) if order is not None and order!='-'*len(order): for key in axismeths.keys(): if key in order and key not in formatted: axis = var.getAxis(order.index(key)) format_axis(axis, axspecs[key], **kwaxes[key]) return var