def coriolis_parameter(lat, gravity=default_gravity, fromvar=False, format_axes=False): """Get the coriolis parameters computed at each latitude :Params: - **lat**: Latitude or a variable with latitude coordinates. - **gravity**, optional: Gravity. - **fromvar**, optional: If True, lat is supposed to be a MV2 array with latitude coordinates. """ # Latitude if fromvar: if not cdms2.isVariable(lat): raise VACUMMError('lat must a MV2 array because fromvar is True') latv = lat * 0 lat = lat.getLatitude() if lat is None: raise VACUMMError( 'lat must a MV2 array with a latitude axis because fromvar is True' ) if cdms2.isVariable(lat): lat = lat.asma() # 2D axes if lat.shape != latv.shape: if len(lat.shape) == 2: latv[:] = N.ma.resize(lat, latv.shape) else: yaxis = latv.getOrder().index('y') new_shape = len(latv.shape) * [1] new_shape[yaxis] = latv.shape[yaxis] tile_shape = list(latv.shape) tile_shape[yaxis] = 1 latv[:] = N.tile(lat[:].reshape(new_shape), tile_shape) else: latv = lat if not N.ndim(lat) else lat[:] # Compute f0 = 2 * N.ma.sin(N.pi * latv / 180.) # f0 *= 2*N.pi/(24.*3600.) f0 *= 2 * N.pi / (86164.) # 86164 = sidereal day.... # Format if N.isscalar(f0): return f0 f0 = MV2.asarray(f0) if not fromvar and isaxis(lat) and f0.ndim == 1: f0.setAxis(0, lat) return format_var(f0, 'corio', format_axes=format_axes)
def coriolis_parameter(lat, gravity=default_gravity, fromvar=False, format_axes=False): """Get the coriolis parameters computed at each latitude :Params: - **lat**: Latitude or a variable with latitude coordinates. - **gravity**, optional: Gravity. - **fromvar**, optional: If True, lat is supposed to be a MV2 array with latitude coordinates. """ # Latitude if fromvar: if not cdms2.isVariable(lat): raise VACUMMError('lat must a MV2 array because fromvar is True') latv = lat*0 lat = lat.getLatitude() if lat is None: raise VACUMMError('lat must a MV2 array with a latitude axis because fromvar is True') if cdms2.isVariable(lat): lat=lat.asma() # 2D axes if lat.shape!=latv.shape: if len(lat.shape)==2: latv[:] = N.ma.resize(lat, latv.shape) else: yaxis = latv.getOrder().index('y') new_shape = len(latv.shape)*[1] new_shape[yaxis] = latv.shape[yaxis] tile_shape = list(latv.shape) tile_shape[yaxis] = 1 latv[:] = N.tile(lat[:].reshape(new_shape), tile_shape) else: latv = lat if N.isscalar(lat) else lat[:] # Compute f0 = 2*N.ma.sin(N.pi*latv/180.) # f0 *= 2*N.pi/(24.*3600.) f0 *= 2*N.pi/(86164.) # 86164 = sidereal day.... # Format if N.isscalar(f0): return f0 f0 = MV2.asarray(f0) if not fromvar and isaxis(lat) and f0.ndim==1: f0.setAxis(0, lat) return format_var(f0, 'corio', format_axes=format_axes)
def _format_var_(vv, name, mask=None, prefix=True, suffix=True, templates=None, htemplates=None, attributes=None, single=True, **kwargs): # Some inits ist = name.startswith('t') name = name[1:] if prefix is True: prefix = 'Temporal ' if ist else 'Spatial ' elif not prefix: prefix = '' kwargs['copy'] = 0 # Aways have a list if isinstance(vv, tuple): vv = list(vv) single = False elif not isinstance(vv, list): vv = [vv] single = True elif single: single = len(vv)==1 else: single = False dual = len(vv)==2 if templates is not None and not isinstance(templates, (list, tuple)): templates = [templates]*len(vv) if htemplates is not None and not isinstance(htemplates, (list, tuple)): htemplates = [htemplates]*len(vv) if attributes is None: attributes = ({}, {}) elif not isinstance(attributes, (list, tuple)): attributes = [attributes]*len(vv) # Long_name long_name = prefix if name=='avail': long_name += 'availability' if name=='count': long_name += 'count' elif name=='mean': long_name += 'average' elif name=='std': long_name += 'standard deviation' elif name=='bias': long_name += 'bias' elif name=='rms': long_name += 'absolute RMS difference' elif name=='crms': long_name += 'centered RMS difference' elif name=='corr': long_name += 'correlation' elif name=='hist': long_name += 'histogram' # Type change if 'count' in name: dtype = 'l' else: dtype = None for i, v in enumerate(vv): # From template or not hvar = v.ndim==2 # Histogram-like variables: first axis = bins hist = htemplates and hvar if templates is not None: # From axis (sstats) if isaxis(templates[i]): # if hvar and not ist: # v = N.ma.transpose(v) # time first, not bins var = MV2.asarray(v) var.setAxis(0, templates[i]) # try: # var.setAxis(int(hist), templates[i]) # except: # pass if hist: var.setAxis(1, htemplates[i]) # From variable (tstats) else: try: var = (htemplates if hvar else templates)[i].clone() except: pass try: var[:] = v.reshape(var.shape) except: pass else: var = MV2.asarray(v) del v # Type if dtype: var = var.astype(dtype) # Mask if mask is not None: func = N.resize if var.size!=mask.size else N.reshape var[:] = MV2.masked_where(func(mask, var.shape), var, copy=0) # Attributes # - id and long_name var.id = attributes[i]['id']+'_'+name var.long_name = long_name if suffix and isinstance(suffix, basestring): var.long_name += suffix # - single stats if name in ['mean', 'std', 'hist', 'min', 'max']: if "units" in attributes[i]: var.units = attributes[i]['units'] if suffix is True and "long_name" in attributes[i]: var.long_name += ' of '+attributes[i]['long_name'] # - dual stats elif name in ['bias', 'rms', 'crms']: for attr in attributes: # loop on both variables attributes if "units" in attr and not hasattr(var, 'units'): var.units = attr['units'] if suffix is True and "long_name" in attr and var.long_name==long_name: var.long_name += ' of '+attr['long_name'] vv[i] = var if single: return vv[0] return tuple(vv)
def _format_var_(vv, name, mask=None, prefix=True, suffix=True, templates=None, htemplates=None, attributes=None, single=True, **kwargs): if name=='tstd': pass # Some inits ist = name.startswith('t') name = name[1:] if prefix is True: prefix = 'Temporal ' if ist else 'Spatial ' elif not prefix: prefix = '' kwargs['copy'] = 0 # Aways have a list if isinstance(vv, tuple): vv = list(vv) single = False elif not isinstance(vv, list): vv = [vv] single = True elif single: single = len(vv)==1 else: single = False dual = len(vv)==2 if templates is not None and not isinstance(templates, (list, tuple)): templates = [templates]*len(vv) if htemplates is not None and not isinstance(htemplates, (list, tuple)): htemplates = [htemplates]*len(vv) if attributes is None: attributes = ({}, {}) elif not isinstance(attributes, (list, tuple)): attributes = [attributes]*len(vv) # Long_name long_name = prefix if name=='avail': long_name += 'availability' elif name=='mean': long_name += 'average' elif name=='std': long_name += 'standard deviation' elif name=='bias': long_name += 'bias' elif name=='rms': long_name += 'absolute RMS difference' elif name=='crms': long_name += 'centered RMS difference' elif name=='corr': long_name += 'correlation' elif name=='hist': long_name += 'histogram' # Type change if 'count' in name: dtype = 'l' else: dtype = None for i, v in enumerate(vv): # From template or not hvar = v.ndim==2 # Histogram-like variables: first axis = bins hist = htemplates and hvar if templates is not None: # From axis (sstats) if isaxis(templates[i]): # if hvar and not ist: # v = N.ma.transpose(v) # time first, not bins var = MV2.asarray(v) var.setAxis(0, templates[i]) # try: # var.setAxis(int(hist), templates[i]) # except: # pass if hist: var.setAxis(1, htemplates[i]) # From variable (tstats) else: try: var = (htemplates if hvar else templates)[i].clone() except: pass try: var[:] = v.reshape(var.shape) except: pass else: var = MV2.asarray(v) del v # Type if dtype: var = var.astype(dtype) # Mask if mask is not None: func = N.resize if var.size!=mask.size else N.reshape var[:] = MV2.masked_where(func(mask, var.shape), var, copy=0) # Attributes # - id and long_name var.id = attributes[i]['id']+'_'+name var.long_name = long_name if suffix and isinstance(suffix, basestring): var.long_name += suffix # - single stats if name in ['mean', 'std', 'hist', 'min', 'max']: if "units" in attributes[i]: var.units = attributes[i]['units'] if suffix is True and "long_name" in attributes[i]: var.long_name += ' of '+attributes[i]['long_name'] # - dual stats elif name in ['bias', 'rms', 'crms']: for attr in attributes: # loop on both variables attributes if "units" in attr and not hasattr(var, 'units'): var.units = attr['units'] if suffix is True and "long_name" in attr and var.long_name==long_name: var.long_name += ' of '+attr['long_name'] vv[i] = var if single: return vv[0] return tuple(vv)
def change_loc(var, toloc, axes=True, squeeze=True): """Change location specifications of a variable and its axes It affects the id, the standard_name and the long_name when they are defined. :Params: - :Example: >>> change_loc(sst, 'u').id 'sst_u' >>> change_loc(sst, 't', squeeze=True).id 'sst' """ # Squeeze physloc if not isinstance(squeeze, basestring): if squeeze: squeeze = get_physloc(var) else: squeeze = None # Change attributes # - get specs = change_loc_specs( toloc, squeeze=squeeze, id=var.id, standard_name=getattr(var, 'standard_name', None), long_name=getattr(var, 'long_name', None), ) # - set var.id = specs['id'] for att in 'standard_name', 'long_name': if att in specs: setattr(var, att, specs[att]) # - cf name if hasattr(var, '_vacumm_cf_name'): var._vacumm_cf_name = change_loc_single(var._vacumm_cf_name, 'id', toloc, squeeze=squeeze) # Change axes and grid attributes if axes and cdms2.isVariable(var) or cdms2.isGrid(var): # Axes # - usual for meth in 'Longitude', 'Latitude', 'Time', 'Level': if hasattr(var, 'get' + meth): axismet = getattr(var, 'get' + meth) # var.getLongitude if axismet() is not None: change_loc(axismet(), toloc, squeeze=squeeze) # - 2d axes if cdms2.isVariable(var) and isaxis(var) and var.ndim > 2: for i in -1, -2: change_loc(var.getAxis(i), toloc, squeeze=squeeze) # Grid if cdms2.isVariable(var) and var.getGrid() is not None: change_loc(var.getGrid(), toloc, squeeze=squeeze) # Reference attribute set_loc(var, toloc) return var
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 change_loc(var, toloc, axes=True, squeeze=True): """Change location specifications of a variable and its axes It affects the id, the standard_name and the long_name when they are defined. :Params: - :Example: >>> change_loc(sst, 'u').id 'sst_u' >>> change_loc(sst, 't', squeeze=True).id 'sst' """ # Squeeze physloc if not isinstance(squeeze, basestring): if squeeze: squeeze = get_physloc(var) else: squeeze = None # Change attributes # - get specs = change_loc_specs(toloc, squeeze=squeeze, names=var.id, standard_names = getattr(var, 'standard_name', None), long_names = getattr(var, 'long_name', None), ) # - set var.id = specs['names'] for att in 'standard_name', 'long_name': if att+'s' in specs: setattr(var, att, specs[att+'s']) # - cf name if hasattr(var, '_vacumm_cf_name'): var._vacumm_cf_name = change_loc_single(var._vacumm_cf_name, 'name', toloc, squeeze=squeeze) # Change axes and grid attributes if axes and cdms2.isVariable(var) or cdms2.isGrid(var): # Axes # - usual for meth in 'Longitude', 'Latitude', 'Time', 'Level': if hasattr(var, 'get'+meth): axismet = getattr(var, 'get'+meth) # var.getLongitude if axismet() is not None: change_loc(axismet(), toloc, squeeze=squeeze) # - 2d axes if cdms2.isVariable(var) and isaxis(var) and var.ndim>2: for i in -1, -2: change_loc(var.getAxis(i), toloc, squeeze=squeeze) # Grid if cdms2.isVariable(var) and var.getGrid() is not None: change_loc(var.getGrid(), toloc, squeeze=squeeze) # Reference attribute set_loc(var, toloc) return var
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