Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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