Example #1
0
def set_grid_type(var, gtype):
    """Set an attribute so that var is identified as being on the specified Arakawa
    grid type.

    If var is a :mod:`cdms2` variable or grid, it sets the
    :attr:`_vacumm_arakawa_grid_type` attribute,
    else it sets the :attr:`arakawa_grid_type` attribute.

    :Params:

        - **var**:  A :mod:`cdms2` variable or grid, a
          :class:`~vacumm.data.misc.dataset.Dataset` instance.
        - **gtype**: None or one of the :attr:`grid_type` letters.

    """
    if gtype is not None:
        gtype = str(gtype).upper()
    if cdms2.isVariable(var) or cdms2.isGrid(var):
        vv = [var]
        if cdms2.isVariable(var):
            grid = var.getGrid()
            if grid is not None: vv.append(grid)
        for v in vv:
            _set_clean_atts_(v, _cdms2_atts, gtype)
    else:
        _set_clean_atts_(var, _other_atts, gtype)
    return gtype
Example #2
0
def set_grid_type(var, gtype):
    """Set an attribute so that var is identified as being on the specified Arakawa
    grid type.

    If var is a :mod:`cdms2` variable or grid, it sets the
    :attr:`_vacumm_arakawa_grid_type` attribute,
    else it sets the :attr:`arakawa_grid_type` attribute.

    :Params:

        - **var**:  A :mod:`cdms2` variable or grid, a
          :class:`~vacumm.data.misc.dataset.Dataset` instance.
        - **gtype**: None or one of the :attr:`grid_type` letters.

    """
    if gtype is not None:
        gtype = str(gtype).upper()
    if cdms2.isVariable(var) or cdms2.isGrid(var):
        vv = [var]
        if cdms2.isVariable(var):
            grid = var.getGrid()
            if grid is not None: vv.append(grid)
        for v in vv:
            _set_clean_atts_(v, _cdms2_atts, gtype)
    else:
        _set_clean_atts_(var, _other_atts, gtype)
    return gtype
Example #3
0
    def __init__(self, u, v, rsphere=6.3712e6):
        """Initialize a VectorWind instance.

        **Arguments:**

        *u*, *v*
            Zonal and meridional components of the vector wind
            respectively. Both components should be `cdms2`
            variables. The components must have the same shape and
            contain no missing values.

        **Example:**

        Initialize a `VectorWind` instance with zonal and meridional
        components of the vector wind::

            from windspharm.cdms import VectorWind
            w = VectorWind(u, v)

        """
        # Ensure the input are cdms2 variables.
        if not (cdms2.isVariable(u) and cdms2.isVariable(v)):
            raise TypeError("u and v must be cdms2 variables")
        # Check that both u and v have dimensions in the same order and that
        # there are latitude and longitude dimensions present.
        uorder = u.getOrder()
        vorder = v.getOrder()
        if uorder != vorder:
            raise ValueError("u and v must have the same dimension order")
        for order in (uorder, vorder):
            if "x" not in order or "y" not in order:
                raise ValueError("a latitude-longitude grid is required")
        self.order = uorder
        # Assess how to re-order the inputs to be compatible with the
        # computation API.
        apiorder = "yx" + "".join([a for a in order if a not in "xy"])
        # Order the dimensions correctly.
        u = u.reorder(apiorder)
        v = v.reorder(apiorder)
        # Do a region selection on the inputs to ensure the latitude dimension
        # is north-to-south.
        u = u(latitude=(90, -90))
        v = v(latitude=(90, -90))
        # Determine the grid type,
        lon = u.getLongitude()
        lat = u.getLatitude()
        if lon is None or lat is None:
            raise ValueError("a latitude-longitude grid is required")
        gridtype = self._gridtype(lat)
        # Store the shape and axes when data is in the API order.
        self.ishape = u.shape
        self.axes = u.getAxisList()
        # Re-shape to 3-dimensional (compatible with API)
        u = u.reshape(u.shape[:2] + (np.prod(u.shape[2:]),))
        v = v.reshape(v.shape[:2] + (np.prod(v.shape[2:]),))
        # Instantiate a VectorWind object to do the computations.
        self.api = standard.VectorWind(u, v, gridtype=gridtype, rsphere=rsphere)
Example #4
0
    def __init__(self, u, v):
        """Initialize a VectorWind instance.

        **Arguments:**

        *u*, *v*
            Zonal and meridional components of the vector wind
            respectively. Both components should be `cdms2`
            variables. The components must have the same shape and
            contain no missing values.

        **Example:**

        Initialize a `VectorWind` instance with zonal and meridional
        components of the vector wind::

            from windspharm.cdms import VectorWind
            w = VectorWind(u, v)

        """
        # Ensure the input are cdms2 variables.
        if not (cdms2.isVariable(u) and cdms2.isVariable(v)):
            raise TypeError('u and v must be cdms2 variables')
        # Check that both u and v have dimensions in the same order and that
        # there are latitude and longitude dimensions present.
        uorder = u.getOrder()
        vorder = v.getOrder()
        if uorder != vorder:
            raise ValueError('u and v must have the same dimension order')
        for order in (uorder, vorder):
            if 'x' not in order or 'y' not in order:
                raise ValueError('a latitude-longitude grid is required')
        self.order = uorder
        # Assess how to re-order the inputs to be compatible with the
        # computation API.
        apiorder = 'yx' + ''.join([a for a in order if a not in 'xy'])
        # Order the dimensions correctly.
        u = u.reorder(apiorder)
        v = v.reorder(apiorder)
        # Do a region selection on the inputs to ensure the latitude dimension
        # is north-to-south.
        u = u(latitude=(90, -90))
        v = v(latitude=(90, -90))
        # Determine the grid type,
        lon = u.getLongitude()
        lat = u.getLatitude()
        if lon is None or lat is None:
            raise ValueError('a latitude-longitude grid is required')
        gridtype = self._gridtype(lat)
        # Store the shape and axes when data is in the API order.
        self.ishape = u.shape
        self.axes = u.getAxisList()
        # Re-shape to 3-dimensional (compatible with API)
        u = u.reshape(u.shape[:2] + (np.prod(u.shape[2:]),))
        v = v.reshape(v.shape[:2] + (np.prod(v.shape[2:]),))
        # Instantiate a VectorWind object to do the computations.
        self.api = standard.VectorWind(u, v, gridtype=gridtype)
Example #5
0
def _val2z_(var, dep, varref, axis, monosign):
    """Compute depth for a given reference data value"""

    # Inits with Z axis first
    var = var.asma() if cdms2.isVariable(var) else N.ma.asarray(var)
    var = var.copy()
    dep = dep.asma() if cdms2.isVariable(dep) else N.ma.asarray(dep)
    dep = N.ma.masked_where(var.mask, dep, copy=False)
    varref = varref.asma() if cdms2.isVariable(varref) else N.ma.asarray(
        varref)
    if var.ndim - 1 == 0:
        var = var.reshape(-1, 1)
        dep = dep.reshape(-1, 1)
        varref = varref.reshape(1)
        axis = 0
    rvar = N.rollaxis(var, axis) if axis else var
    rdep = N.rollaxis(dep, axis) if axis else dep
    rdepref = rdep[0].copy()
    rvar = rvar.copy()
    nz = rvar.shape[0]  # nb of elements along the first axis (z in general)
    maskland = N.ma.getmaskarray(rvar)[-1]

    # Monotonic
    rvar *= monosign
    varref *= monosign
    dvar = N.ma.diff(rvar, axis=0)

    # Find z index
    dvarref = rvar - varref
    iiz0 = N.arange(nz - 1, dtype='i')
    iiz0 = N.ma.resize(iiz0, rvar.shape[rvar.ndim - 1:0:-1] + (nz - 1, )).T
    iiz0 = N.ma.masked_where(N.ma.diff(N.sign(dvarref), axis=0) < 2,
                             iiz0,
                             copy=0)
    iz0 = iiz0.max(axis=0)
    del iiz0
    maskdz = iz0.mask
    iz0 = iz0.filled(0.)

    # Interpolation
    dvar0 = N_choose(iz0, dvar)
    dvar0[maskdz] = 1.
    w1 = -N_choose(iz0, dvarref) / dvar0
    w1.set_fill_value(0.)
    rdep.set_fill_value(0.)
    rdepref = N_choose(iz0 + 1, rdep) * w1
    rdepref += N_choose(iz0, rdep) * (1 - w1)

    # Masking
    rdepref[maskland] = N.ma.masked
    rdepref = N.ma.where(~maskland & maskdz, rdep.min(axis=0), rdepref)

    return rdepref
Example #6
0
def _val2z_(var, dep, varref, axis, monosign):
    """Compute depth for a given reference data value"""

    # Inits with Z axis first
    var = var.asma() if cdms2.isVariable(var) else N.ma.asarray(var)
    var = var.copy()
    dep = dep.asma() if cdms2.isVariable(dep) else N.ma.asarray(dep)
    dep = N.ma.masked_where(var.mask, dep, copy=False)
    varref = varref.asma() if cdms2.isVariable(varref) else N.ma.asarray(varref)
    if var.ndim-1==0:
        var = var.reshape(-1,1)
        dep = dep.reshape(-1,1)
        varref = varref.reshape(1)
        axis = 0
    rvar = N.rollaxis(var, axis) if axis else var
    rdep = N.rollaxis(dep, axis) if axis else dep
    rdepref = rdep[0].copy()
    rvar = rvar.copy()
    nz = rvar.shape[0]   # nb of elements along the first axis (z in general)
    maskland = N.ma.getmaskarray(rvar)[-1]

    # Monotonic
    rvar *= monosign
    varref *= monosign
    dvar = N.ma.diff(rvar, axis=0)

    # Find z index
    dvarref = rvar-varref
    iiz0 = N.arange(nz-1, dtype='i')
    iiz0 = N.ma.resize(iiz0, rvar.shape[rvar.ndim-1:0:-1]+(nz-1, )).T
    iiz0 = N.ma.masked_where(N.ma.diff(N.sign(dvarref), axis=0)<2, iiz0, copy=0)
    iz0 = iiz0.max(axis=0)
    del iiz0
    maskdz = iz0.mask
    iz0 = iz0.filled(0.)


    # Interpolation
    dvar0 = N_choose(iz0, dvar)
    dvar0[maskdz] = 1.
    w1 = -N_choose(iz0, dvarref)/dvar0
    w1.set_fill_value(0.)
    rdep.set_fill_value(0.)
    rdepref = N_choose(iz0+1, rdep)*w1
    rdepref += N_choose(iz0, rdep)*(1-w1)

    # Masking
    rdepref[maskland] = N.ma.masked
    rdepref = N.ma.where(~maskland&maskdz, rdep.min(axis=0), rdepref)

    return rdepref
Example #7
0
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)
Example #8
0
def get_grid_type(var):
    """Guess the Arakawa grid type

    It search for the following attributes: :attr:`arakawa_grid_type`, :attr:`grid_type`
    and :attr:`_vacumm_arakawa_grid_type`.

    :Params:

        - **var**: A :mod:`cdms2` variable or grid, an :class:`ArakawaGrid` instance or
          a :class:`~vacumm.data.misc.dataset.Dataset` instance.
          If var is a :mod:`cdms2` variable, it also check its grid if defined.

    :Return: An Arakawa grid upper-base letter, like 'C'
    """
    vv = [var]
    if cdms2.isVariable(var):
        grid = var.getGrid()
        if grid is not None:
            vv.append(grid)
    for v in vv:
        for att in _cdms2_atts + _other_atts:
            if hasattr(v, att):
                gt = getattr(a, att)
                if gt is None: return
                return str(gt).upper()
Example #9
0
def generateLandSeaMask(target,
                        source=None,
                        threshold_1=.2,
                        threshold_2=.3,
                        regridTool='regrid2'):
    """ Generates a best guess mask on any rectilinear grid, using the method described in PCMDI's report #58
    see: http://www-pcmdi.llnl.gov/publications/ab58.html
    Input:
       target: either a MV2 object with a grid, or a cdms2 grid (rectilinear grid only)
       source: A fractional (0 to 1.) land sea mask, where 1 means all land
       threshold_1 (optional): criteria 1 for detecting cells with possible increment see report for detail
                               difference threshold
       threshold_2 (optional): criteria 2 for detecting cells with possible increment see report for detail
                               water/land content threshold
       regridTool: which cdms2 regridder tool to use, default is regrid2
    Output:
       landsea maks on target grid
    """
    cdat_info.pingPCMDIdb("cdat", "cdutil.generateLandSeaMask")
    if cdms2.isVariable(target):
        target = target.getGrid()
        if target is None:
            raise Exception, "Error target data passed do not have  a grid"
    if not isinstance(target, cdms2.grid.TransientRectGrid):
        raise Exception, "Error: target grid must be rectilinear"

    if source is None:
        source = cdms2.open(
            os.path.join(sys.prefix, 'share', 'cdutil',
                         'navy_land.nc'))('sftlf')

    try:
        navy_frac_t = source.regrid(target, regridTool='regrid2')
    except Exception, err:
        raise "error, cannot regrid source data to target, got error message: %s" % err
Example #10
0
def generateLandSeaMask(target,source=None,threshold_1 = .2, threshold_2 = .3,regridTool='regrid2'):
    """ Generates a best guess mask on any rectilinear grid, using the method described in PCMDI's report #58
    see: http://www-pcmdi.llnl.gov/publications/ab58.html
    Input:
       target: either a MV2 object with a grid, or a cdms2 grid (rectilinear grid only)
       source: A fractional (0 to 1.) land sea mask, where 1 means all land
       threshold_1 (optional): criteria 1 for detecting cells with possible increment see report for detail
                               difference threshold
       threshold_2 (optional): criteria 2 for detecting cells with possible increment see report for detail
                               water/land content threshold
       regridTool: which cdms2 regridder tool to use, default is regrid2
    Output:
       landsea maks on target grid
    """
    cdat_info.pingPCMDIdb("cdat","cdutil.generateLandSeaMask")
    if cdms2.isVariable(target):
        target = target.getGrid()
        if target is None:
            raise Exception,"Error target data passed do not have  a grid"
    if not isinstance(target,cdms2.grid.TransientRectGrid):
        raise Exception, "Error: target grid must be rectilinear"

    if source is None:
        source = cdms2.open(os.path.join(sys.prefix,'share','cdutil','navy_land.nc'))('sftlf')
        
    try:
        navy_frac_t = source.regrid(target,regridTool='regrid2')
    except Exception,err:
        raise "error, cannot regrid source data to target, got error message: %s" % err
Example #11
0
def create_axis(values, atype='-', **atts):
    """Quickly create a :mod:`cdms2` axis

    :Params:

        - **values**: Numerical values.
        - **atype**, optional: axis type within 'x','y','z','t','-' [default: '-']
        - Other keywords are passed as attributes to the axis.

    :Example:

        >>> lon = create_axis(N.arange(-10., 0, 2), 'x')
        >>> lon = create_axis((-10., 0, 2), 't', id='temps', units='seconds since 2000')
        >>>
    """
    from vacumm.misc import cp_atts
    if N.isscalar(values):
        values = [values]
    if isinstance(values, tuple) and len(values) < 4:
        values = N.arange(*values, **{'dtype': 'd'})
    if cdms2.isVariable(values):
        for item in values.attributes.items():
            atts.setdefault(*item)
        values = values.asma()
    if not isaxis(values):
        axis = cdms2.createAxis(values)
    else:
        axis = values
    for att, val in atts.items():
        setattr(axis, att, val)
    axis.axis = atype.upper()
    check_axis(axis)
    if axis.axis == '-':
        del axis.axis
    return axis
Example #12
0
def split_varname(varname):
    """Split a variable name in three parts (physical, depth, others)

    The separator is the underscore sign.

    Examples
    --------
    >>> print split_varname('temp_surf_std_dev')
    ('temp', 'surf', 'std_dev')
    >>> print split_varname('temp_variance')
    ('temp', None, 'variance')
    >>> print split_varname('temp')
    ('temp', None, 'None')
    """
    if cdms2.isVariable(varname):
        varname = varname.id
    svname = varname.split('_')
    physical = svname[0]
    depth = others = None
    if len(svname)>1:
        if svname[1] in ['surf', 'bottom']:
            depth = svname[1]
            svname = svname[2:]
            if depth=='3d':
                depth = None
        else:
            svname = svname[1:]
        if svname:
            others = '_'.join(svname)
    return physical, depth, others
Example #13
0
File: scrip.py Project: AZed/uvcdat
    def __call__(self, input):

        import numpy.ma
        from cdms2 import isVariable
        from cdms2.tvariable import TransientVariable

        # If input is a variable, make it a TV
        if isVariable(input) and not isinstance(input, TransientVariable):
            input = input.subSlice()

        isvar = isinstance(input, TransientVariable)

        if isvar:
            domain = tuple(input.getAxisList())
            if self.inputGrid is not None:
                ingrid = self.inputGrid
            else:
                ingrid = input.getGrid()
            if ingrid is None:
                raise RegridError, "Input variable must have an associated grid."
            rank = len(ingrid.shape)
            gridsize = ingrid.size()
            outgridshape = self.outputGrid.shape

            # Check that the grid matches the last dimension(s) of input
            if input.shape[-rank:] != ingrid.shape:
                raise RegridError, 'Last dimensions of input array must match grid shape: %s'%`ingrid.shape`
            #this expects contiguous arrays
            if input.iscontiguous() is False:
                input = input.ascontiguous()

        else:
            rank = 1                    # If not a TV, last dimension is the 'cell' dimension
            gridsize = input.shape[-1]
            outgridshape = (reduce(lambda x,y: x*y, self.outputGrid.shape, 1),)
            
        # If input is an numpy.ma, make it Numeric
        if numpy.ma.isMaskedArray(input):
            input = input.filled()

        restoreShape = input.shape[:-rank]
        restoreLen = reduce(lambda x,y: x*y, restoreShape, 1)
        oldshape = input.shape
        newshape = (restoreLen, gridsize)
        input.shape = newshape

        # Regrid
        output = self.regrid(input)

        # Reshape output and restore input shape
        input.shape = oldshape
        outshape = restoreShape + outgridshape
        output.shape = outshape

        # If the input was a variable, so is the output
        if isvar:
            outdomain = domain[:-rank]+(self.outputGrid,)
            output = TransientVariable(output, axes=outdomain)

        return output
Example #14
0
def recursive_transform_att(data, att, func, *args, **kwargs):
    """Strip ids of a recursive lists of arrays"""
    if not isinstance(data, list):
        if cdms2.isVariable(data) and hasattr(data, att):
                setattr(data, att, func(getattr(data, att), *args, **kwargs))
        return data
    return [recursive_transform_att(dat, att, func, *args, **kwargs) for dat in data]
Example #15
0
def get_grid_type(var):
    """Guess the Arakawa grid type

    It search for the following attributes: :attr:`arakawa_grid_type`, :attr:`grid_type`
    and :attr:`_vacumm_arakawa_grid_type`.

    :Params:

        - **var**: A :mod:`cdms2` variable or grid, an :class:`ArakawaGrid` instance or
          a :class:`~vacumm.data.misc.dataset.Dataset` instance.
          If var is a :mod:`cdms2` variable, it also check its grid if defined.

    :Return: An Arakawa grid upper-base letter, like 'C'
    """
    vv = [var]
    if cdms2.isVariable(var):
        grid = var.getGrid()
        if grid is not None:
            vv.append(grid)
    for v in vv:
        for att in _cdms2_atts+_other_atts:
            if hasattr(v, att):
                gt = getattr(a, att)
                if gt is None: return
                return str(gt).upper()
Example #16
0
def return_defined_data_list():
      tv = __main__.__dict__
      trash_str = gui_defined_variables.trash_str
      data_list = []
      for x in tv.keys():
#         if ( ( isinstance( tv[x] , numpy.ndarray) ) or ( cdms2.isVariable( tv[x] ) ) or
#            ( MV2.isMA( tv[x] ) ) ):
         if ( cdms2.isVariable( tv[x] ) ):

            str_var = x + ' ('
            for i in range(len(tv[x].shape)):
               s ="%d" % tv[x].shape[i]

               str_var = str_var + s + ', '

            if len (tv[x]) > 0:
               str_var = str_var[0:len(str_var)-2]
            str_var = str_var + ')'

            a = string.split( str_var, ' ')[0]
            if a[-len(trash_str):] != trash_str:
               if str_var[-2:] == '()': str_var = str_var + (' = %.17g' % tv[ x ])
               data_list.append( str_var )

      data_list.sort()

      return data_list
Example #17
0
def create_axis(values, atype='-', **atts):
    """Quickly create a :mod:`cdms2` axis

    :Params:

        - **values**: Numerical values.
        - **atype**, optional: axis type within 'x','y','z','t','-' [default: '-']
        - Other keywords are passed as attributes to the axis.

    :Example:

        >>> lon = create_axis(N.arange(-10., 0, 2), 'x')
        >>> lon = create_axis((-10., 0, 2), 't', id='temps', units='seconds since 2000')
        >>>
    """
    from vacumm.misc import cp_atts
    if isinstance(values, tuple) and len(values) < 4:
        values = N.arange(*values, **{'dtype':'d'})
    if cdms2.isVariable(values):
        for item in values.attributes.items():
            atts.setdefault(*item)
        values = values.asma()
    if not isaxis(values):
        axis = cdms2.createAxis(values)
    else:
        axis = values
    for att,val in atts.items():
        setattr(axis, att, val)
    axis.axis = atype.upper()
    check_axis(axis)
    if axis.axis == '-':
        del axis.axis
    return axis
Example #18
0
def return_defined_data_list():
    tv = __main__.__dict__
    trash_str = gui_defined_variables.trash_str
    data_list = []
    for x in tv.keys():
        #         if ( ( isinstance( tv[x] , numpy.ndarray) ) or ( cdms2.isVariable( tv[x] ) ) or
        #            ( MV2.isMA( tv[x] ) ) ):
        if (cdms2.isVariable(tv[x])):

            str_var = x + ' ('
            for i in range(len(tv[x].shape)):
                s = "%d" % tv[x].shape[i]

                str_var = str_var + s + ', '

            if len(tv[x]) > 0:
                str_var = str_var[0:len(str_var) - 2]
            str_var = str_var + ')'

            a = string.split(str_var, ' ')[0]
            if a[-len(trash_str):] != trash_str:
                if str_var[-2:] == '()':
                    str_var = str_var + (' = %.17g' % tv[x])
                data_list.append(str_var)

    data_list.sort()

    return data_list
Example #19
0
def kinetic_energy(sshuv, gravity=default_gravity, format_axes=None, dxy=None):
    """Compute kinetic energy in m2.s-2 either from SSH or velocity on C-grid

    .. todo:: Rewrite it using :mod:`vacumm.data.misc.arakawa` and defining
        a limited number of algorithms for different staggering configurations.

    :Params:

        - **sshuv**: SSH or (U,V).

            - If SSH, geostrophic velocity is computed at U and V points
              using :func:`barotropic_geostrophic_velocity`.
            - If (U,V), velocities are supposed to be at V and U points.

        - **dxy**, optional: Horizontal resolutions (see :func:`barotropic_geostrophic_velocity`).

    :Return: KE at T points.
    """

    # Init and get velocities
    if cdms2.isVariable(sshuv): # from SSH
        ke = sshuv*MV2.masked
        u, v = barotropic_geostrophic_velocity(sshuv, dxy=dxy, gravity=gravity, format_axes=format_axes)
        if format_axes is None: format_axes = False
    else: # from (U,V)
        u, v = sshuv
        ke = u*MV2.masked
        if format_axes is None: format_axes = True
        gridt = shiftgrid(u.getGrid(), jshift=1)
        set_grid(ke, gridt)

    # Sum contributions
    uf = u.filled(0.)
    vf = v.filled(0.)
    ke[..., 1:, :] =  uf[..., 1:,  :]**2
    ke[..., 1:, :] += uf[..., :-1, :]**2
    ke[..., 1:]    += vf[..., :-1]**2
    ke[..., 1:]    += vf[..., :-1]**2

    # Weight and mask
    count = N.zeros(ke.shape, 'i')
    gu = 1-N.ma.getmaskarray(u).astype('i')
    gv = 1-N.ma.getmaskarray(v).astype('i')
    count[1:] = gu[:-1]
    count[1:] += gu[1:]
    count[:, 1:] += gv[:, :-1]
    count[:, 1:] += gv[:, 1:]
    del gu, gv
    mask = count==0
    count[mask] = 1
    ke[:] /= count
    ke[:] = MV2.masked_where(mask, ke, copy=0)
    del mask, count

    # Format
    if format_axes:
        format_grid(gridt, 't')
    return format_var(ke, "ke", format_axes=False)
Example #20
0
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)
Example #21
0
def format_grid(grid, pt, **kwargs):
    """Format a grid and its axes"""
    if cdms2.isVariable(grid): grid = grid.getGrid()
    if grid is None: return
    gs = GRID_SPECS[pt]
    lon = grid.getLongitude()
    lat = grid.getLatitude()
    format_axis(lon, gs['lon'], **kwargs)
    format_axis(lat, gs['lat'], **kwargs)
Example #22
0
def format_grid(grid, pt, **kwargs):
    """Format a grid and its axes"""
    if cdms2.isVariable(grid): grid = grid.getGrid()
    if grid is None: return
    gs = GRID_SPECS[pt]
    lon = grid.getLongitude()
    lat = grid.getLatitude()
    format_axis(lon, gs['lon'])
    format_axis(lat, gs['lat'])
Example #23
0
    def _get_from_name_(self, name, selector=None, lons=None, lats=None, times=None):
        """Load axis or variable from its generic name

        .. note:: Tests against generic names are case insensitives.
            They are search for in :attr:`names`.

        :Return: None is not found, else a MV2 array
        """

        # Inits
        ncname = self._get_ncname_(name)
        if ncname is None: return
        selector = as_selector(selector)

        # Axis
        var = ncread_axis(self.f, ncname, mode=None)
        if var is not None:

            # Selector
            atype = axis_type(var, genname=True)[:3]
            for sname, sel in list(split_selector(selector)[1].items()):
                if sname==var.id or (atype is not None and atype==sname[:3]):
                    if not isinstance(sel, slice):
                        ijk = var.mapIntervalExt(sel)
                    else:
                        ijk = sel.indices(len(var))
                    var = var.subaxis(*ijk)
            return var

        # Variable
        Variables = list(self.f.variables.keys())
        variables = list(map(string.lower, Variables))
        if ncname.lower() in variables:
            ncname = Variables[variables.index(ncname.lower())]
            not_scalar = self.f[ncname].shape
            args = [ncname]
            if selector and not_scalar:
                args.append(selector)
            kwargs = {'mode':None}
            var = ncread_var(self.f, *args, **kwargs)
            if var is None:
                return
            if not_scalar and hasattr(self.f[ncname], '_FillValue') and cdms2.isVariable(var):
                var[:] = MV2.masked_values(var, self.f[ncname]._FillValue, copy=0)

            # Transect
            if not_scalar and lons is not None and lats is not None:
                var = grid2xy(var, xo=lons, yo=lons, to=times, outaxis=False)
            return var

        # Attribute
        Attributes = list(self.f.attributes.keys())
        attributes = list(map(string.lower, Attributes))
        if ncname.lower() in attributes:
            ncname = Attributes[attributes.index(ncname.lower())]
        return self.f.attributes.get(ncname, None)
Example #24
0
def asma(*args):
    """Return pure numpy or numpy.ma arrays"""
    if not args: return
#    single = len(args)==1
    out = []
    for arg in args:
        if cdms2.isVariable(arg):
            arg = arg.asma()
        out.append(arg)
    if len(args)==1:
        return out[0]
    return out
Example #25
0
def xycompress(valid, vari, **atts):
    """Keep valid spatial points

    Parameters
    ----------
    valid: 1D or 2D bool array
        2D array for data on structured grid
    vari: array
        The variable to compress
    """

    # Slice for extra dimensions
    pslice = (slice(None), ) * (vari.ndim - valid.ndim)

    if cdms2.isVariable(vari):

        nv = valid.sum()


        if valid.ndim==2:


            # Init
            assert valid.ndim == 2, 'Valid must be a 2D array'
            varo = vari[pslice + (0, slice(0, nv))].clone()
            ax = create_axis((nv, ), id='point', long_name='Spatial points')
            varo.setAxis(-1, ax)
            varo.setGrid(None)

            # Fill
            varo[:] = vari.asma()[pslice + (valid, )]

        else:

            # Init
            ax = vari.getAxis(-1)
            varo = vari[pslice + (slice(0, nv), )].clone()

            # Fill
            varo.getAxis(-1)[:] = N.compress(valid, ax[:])
            varo[:] = N.ma.compress(valid, vari.asma(), axis=-1)

        # Attributes
        set_atts(varo, **atts)

    else: # numpy or ma

        varo = vari[pslice + (valid, )]

    return varo
Example #26
0
def _valmin2z_(var, dep, varmax, axis, monosign):
    """Compute depth at which data value at lower than a reference value"""

    # Inits with Z axis first
    var = var.asma() if cdms2.isVariable(var) else N.ma.asarray(var)
    var = var.copy()
    dep = dep.asma() if cdms2.isVariable(dep) else N.ma.asarray(dep)
    if var.ndim-1==0:
        var = var.reshape(-1,1)
        dep = dep.reshape(-1,1)
        axis = 0
    rvar = N.rollaxis(var, axis) if axis else var
    rdep = N.rollaxis(dep, axis) if axis else dep
    rvar = rvar.copy()
    nz = rvar.shape[0]
    maskland = N.ma.getmaskarray(rvar)[-1]

    # Monotonic (greater at surface)
    rvar *= monosign

    # Find z index
    iiz = N.arange(nz, dtype='i')
    iiz = N.ma.resize(iiz, rvar.shape[rvar.ndim-1:0:-1]+(nz, )).T
    iiz = N.ma.masked_where(rvar>varmax, iiz, copy=0)
    iz0 = iiz.max(axis=0)
    del iiz
    maskz = iz0.mask
    iz0 = iz0.filled(0.)

    # Values
    rdepref = N_choose(iz0, rdep)

    # Masking
    rdepref[maskland] = N.ma.masked
    rdepref = N.ma.where(~maskland&maskz, rdep.min(axis=0), rdepref)

    return rdepref
Example #27
0
def _valmin2z_(var, dep, varmax, axis, monosign):
    """Compute depth at which data value at lower than a reference value"""

    # Inits with Z axis first
    var = var.asma() if cdms2.isVariable(var) else N.ma.asarray(var)
    var = var.copy()
    dep = dep.asma() if cdms2.isVariable(dep) else N.ma.asarray(dep)
    if var.ndim - 1 == 0:
        var = var.reshape(-1, 1)
        dep = dep.reshape(-1, 1)
        axis = 0
    rvar = N.rollaxis(var, axis) if axis else var
    rdep = N.rollaxis(dep, axis) if axis else dep
    rvar = rvar.copy()
    nz = rvar.shape[0]
    maskland = N.ma.getmaskarray(rvar)[-1]

    # Monotonic (greater at surface)
    rvar *= monosign

    # Find z index
    iiz = N.arange(nz, dtype='i')
    iiz = N.ma.resize(iiz, rvar.shape[rvar.ndim - 1:0:-1] + (nz, )).T
    iiz = N.ma.masked_where(rvar > varmax, iiz, copy=0)
    iz0 = iiz.max(axis=0)
    del iiz
    maskz = iz0.mask
    iz0 = iz0.filled(0.)

    # Values
    rdepref = N_choose(iz0, rdep)

    # Masking
    rdepref[maskland] = N.ma.masked
    rdepref = N.ma.where(~maskland & maskz, rdep.min(axis=0), rdepref)

    return rdepref
Example #28
0
def set(Array,Indices,Values,axis=0):
    """
    Arrayrrayindexing set Array[Indices] with Values, indices are taken along dimension given with axis
    
    Usage:
    Array=set(Array,Indices,Values,axis=0) # i.e. Array[Indices]=Values

    Indices accepts negative value ,e.g: -1 is last element
    """
##     if numpy.rank(Indices)==0:
##         Array[Indices]=Values
    ## First some checks
    #isma=numpy.ma.isMA(Array)
    if Indices.dtype not in [numpy.int,numpy.int32,numpy.int16]:
        raise "Error indices array must be made of integers (try: Indices=Indices.astype('l') first)"
    
    if cdms2.isVariable(Array) :
        xatt=Array.attributes
        id=Array.id
    if len(Array.shape)!=len(Indices.shape):
        crap,Indices,crap,axis,ax=statistics.__checker(Array,Indices,None,axis,smally=1)
        Array,Values,crap,axis,ax=statistics.__checker(Array,Values,None,axis,smally=1)
        if Indices.shape!=Array.shape[1:]:
            raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)
    else:
        Array,Indices,Values,axis,ax=statistics.__checker(Array,Indices,Values,axis)
        if Indices.shape!=Array.shape:
            raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)

    m=numpy.ma.getmask(Array)
    mv=numpy.ma.getmask(Values)
    if numpy.rank(Indices)>0:
        Indices=Indices.raw_data() # Something happened with masking of y by x mask
        Values=Values.raw_data()
    genutil.array_indexing_emulate.set(Array.raw_data(),Indices.astype('i'),Values)
    if m is not numpy.ma.nomask:
        if mv is not numpy.ma.nomask:
            genutil.array_indexing_emulate.set(m,Indices,mv)
    elif mv is not numpy.ma.nomask:
        m=numpy.zeros(mv.shape,mv.typcode())
        genutil.array_indexing_emulate.set(m,Indices,mv)
        if not numpy.ma.allequal(m,0):
            Array=numpy.ma.masked_where(m,Array,copy=0)
    if not ax is None:
        Array=cdms2.createVariable(C,axes=ax,id=id,copy=0)
        for at in xatt.keys():
            setattr(C,at,xatt[at])
    return Array
Example #29
0
def check_variables(vv, searchmode='ns', format=True):
    """Check that all variables are of MV2.array type and are well known
    of the :mod:`vacumm.data.cf` module

    Variable are first checked on the first part of their id, before a "_".
    If the prefix is not known, their are checked is their are known
    with the :func:`vacumm.data.cf.match_known_var`. In this latter case,
    the id of the variable is changed in case of success if format is True.

    Return
    ------
    list
        The corresponding list of generic names
    """
    al = ArgList(vv)
    gennames = []
    for var in al.get():

        # It is MV2.array?
        if not cdms2.isVariable(var):
            raise SONATError('Variable is not of MV2.array type')

        # Is the name generic?
        vns = var.id.split('_')
        varname = vns[0]
        suffix = '_'.join(vns[1:])
        if varname in GENERIC_VAR_NAMES:
            gennames.append(var.id)
            continue

        # Do its properties match a known variable?
        genname = match_known_var(var, searchmode=searchmode)
        if not genname:
            raise SONATError('Unkown variable')
        if format:
            format_var(var, genname, format_axes=False, force=1 if suffix else 2)

        # Suffix
        if suffix:
            if format:
                var.id = var.id + '_' + suffix
            genname = genname + '_' + suffix

        gennames.append(genname)

    return al.put(gennames)
Example #30
0
def get(Array,Indices,axis=0):
    """
    Arrayrrayindexing returns Array[Indices], indices are taken along dimension given with axis
    
    Usage:
    C=get(Array,Indices,axis=0) # i.e. C=Array[Indices]
    Indices accepts negative value ,e.g: -1 is last element
    """
    ## First some checks

    isma=numpy.ma.isMA(Array)
    if isinstance(Indices,int):
        return Array[Indices]
    if Indices.dtype not in [numpy.int,numpy.int32,numpy.int16]:
        raise "Error indices array must be made of integers (try: Indices=Indices.astype('l') first)"
    
    if cdms2.isVariable(Array) :
        xatt=Array.attributes
        id=Array.id
        
    if len(Array.shape)!=len(Indices.shape):
        Array,Indices,weights,axis,ax=statistics.__checker(Array,Indices,None,axis,smally=1)
        if isinstance(Indices,int):
            return Array[Indices]
        if Indices.shape!=Array.shape[1:]:
            raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)
    else:
        Array,Indices,weights,axis,ax=statistics.__checker(Array,Indices,None,axis)
        if Indices.shape!=Array.shape:
            raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)

    m=Array.mask
    if not isinstance(Indices,int): Indices=Indices.data.astype('i') # Sometihng happened with masking of y by x mask
    print Array.data.dtype.char,Indices.dtype.char
    C=genutil.array_indexing.extract(Array.data,Indices)
    if m is not numpy.ma.nomask:
        M=genutil.array_indexing.extract(m.astype('i'),Indices)
        C=numpy.ma.masked_where(M,C,copy=0)
    elif isma:
        C=numpy.ma.array(C,copy=0,mask=None)
    if not ax is None:
        C=cdms2.createVariable(C,axes=ax,id=id,copy=0)
        for at in xatt.keys():
            setattr(C,at,xatt[at])
    return C
Example #31
0
 def scale(self, data, copy=False, mean=None, norm=None, mode=None):
     """Remove mean and normalize unpacked data"""
     if mode=='mean':
         if norm is None:
             norm = False
         if mean is None:
             mean = True
     elif mode=='norm':
         if norm is None:
             norm = True
         if mean is None:
             mean = False
     if copy:
         data = data.clone() if cdms2.isVariable(data) else data.copy()
     if mean is not False:
         data[:] -= self.mean if mean is True or mean is None else mean
     if norm is not False:
         data[:] /= self._norm if norm is True or norm is None else norm
     return data
Example #32
0
def get_order(var):
    """Enhanced version of getOrder() method that handles 2D axes

    :Params:

        - **var**: axis or cdms variable.

    :Output: string containing letters x, y, z, t or -

    :Example:

        >>> get_order(var)
        "-yx"
    """
    # Already an order
    if isinstance(var, basestring):
        return var.lower()

    # Axis
    if isaxis(var):
        order = get_axis_type(var)
        if len(var.shape) == 2 and order in 'xy':
            return 'yx'
        return order

    # Variable
    if not cdms2.isVariable(var): return '-' * len(var.shape)
    order = var.getOrder()
    if getattr(var,  '_nogridorder', False) or \
        '-' not in order[-2:]:
        return order
    if var.getGrid() is not None and \
        'z' not in order[-2:] and 't' not in order[-2:]:
        if order[-1] == '-' and 'x' not in order:
            #            lon = var.getLongitude()
            #            if len(lon.shape)==2:
            order = order[:-1] + 'x'
        if order[-2] == '-' and 'y' not in order:
            #            lat = var.getLatitude()
            #            if len(lat.shape)==2:
            order = order[:-2] + 'y' + order[-1]
    return order
Example #33
0
def norm_atan(var, stretch=1.):
    """Normalize using arctan (arctan(strecth*var/std(var))

    - *stretch*: If stretch close to 1, saturates values [default: 1]

    Return: Value in [-1,1]
    """
    if cdms2.isVariable(var):
        var_norm = var.clone()
        var_norm.id += '_norm'
        mm = MV
    elif MA.isMA(var):
        var_norm = var.copy()
        mm = MA
    else:
        var_norm = N.array(var)
        mm = N
    std = var.std()
    var_norm[:] = mm.arctan(stretch * var / var.std()) * 2. / N.pi
    return var_norm
Example #34
0
def norm_atan(var,stretch=1.):
    """Normalize using arctan (arctan(strecth*var/std(var))

    - *stretch*: If stretch close to 1, saturates values [default: 1]

    Return: Value in [-1,1]
    """
    if cdms2.isVariable(var):
        var_norm = var.clone()
        var_norm.id  += '_norm'
        mm = MV
    elif MA.isMA(var):
        var_norm = var.copy()
        mm = MA
    else:
        var_norm = N.array(var)
        mm = N
    std = var.std()
    var_norm[:] = mm.arctan(stretch*var/var.std())*2./N.pi
    return var_norm
Example #35
0
def get_order(var):
    """Enhanced version of getOrder() method that handles 2D axes

    :Params:

        - **var**: axis or cdms variable.

    :Output: string containing letters x, y, z, t or -

    :Example:

        >>> get_order(var)
        "-yx"
    """
    # Already an order
    if isinstance(var, basestring):
        return var.lower()

    # Axis
    if isaxis(var):
        order = get_axis_type(var)
        if len(var.shape)==2 and order in 'xy':
            return 'yx'
        return order

    # Variable
    if not cdms2.isVariable(var): return '-'*len(var.shape)
    order = var.getOrder()
    if getattr(var,  '_nogridorder', False) or \
        '-' not in order[-2:]: return order
    if var.getGrid() is not None and \
        'z' not in order[-2:] and 't' not in order[-2:]:
        if order[-1]=='-' and 'x' not in order:
#            lon = var.getLongitude()
#            if len(lon.shape)==2:
            order= order[:-1]+'x'
        if order[-2]=='-' and 'y' not in order:
#            lat = var.getLatitude()
#            if len(lat.shape)==2:
            order = order[:-2]+'y'+order[-1]
    return order
Example #36
0
 def trimData2D(self,data):
   if data is None:
     return None
   try:
     g=data.getGrid()
     gaxes=list(g.getAxisList())
     daxes=list(data.getAxisList())
     if daxes[len(daxes)-len(gaxes):] == gaxes:
       # Ok it is gridded and the grid axes are last
       return self.cleanupData(data(*(slice(0,1),)*(len(daxes)-len(gaxes)),squeeze=1))
     else:
       # Ok just return the last two dims
       return self.cleanupData(data(*(slice(0,1),)*(len(daxes)-2),squeeze=1))
   except Exception,err: # ok no grid info
     daxes=list(data.getAxisList())
     if cdms2.isVariable(data):
       return self.cleanupData( data(*(slice(0,1),)*(len(daxes)-2)))
     else: #numpy arrays are not callable
       op = ()
       for i in range(numpy.rank(data)-2):
         op.append(slice(0,1))
       return self.cleanupData(data[op])
Example #37
0
 def trimData2D(self,data):
   if data is None:
     return None
   try:
     g=data.getGrid()
     gaxes=list(g.getAxisList())
     daxes=list(data.getAxisList())
     if daxes[len(daxes)-len(gaxes):] == gaxes:
       # Ok it is gridded and the grid axes are last
       return self.cleanupData(data(*(slice(0,1),)*(len(daxes)-len(gaxes)),squeeze=1))
     else:
       # Ok just return the last two dims
       return self.cleanupData(data(*(slice(0,1),)*(len(daxes)-2),squeeze=1))
   except Exception,err: # ok no grid info
     daxes=list(data.getAxisList())
     if cdms2.isVariable(data):
       return self.cleanupData( data(*(slice(0,1),)*(len(daxes)-2)))
     else: #numpy arrays are not callable
       op = ()
       for i in range(numpy.rank(data)-2):
         op.append(slice(0,1))
       return self.cleanupData(data[op])
Example #38
0
def _get_anomaly_(var, ref='mean', mean=None):

    # Basic checks
    assert var.ndim == 1, 'Input variable must be 1D'
    assert cdms2.isVariable(var) and var.getTime(
    ) is not None, 'Input variable must have a proper time axis'

    # Get reference
    if ref is None: ref = 'mean'
    nt = len(var)
    if isinstance(ref, int):
        var_ref = running_average(var, ref)
    elif ref in ['demerliac', 'godin']:
        var_ref = eval(ref)(var, get_tide=False)
    elif ref == 'mean':
        if mean is None:
            var_ref = float(var.mean())
        else:
            var_ref = mean
    else:
        var_ref = ref
    if not isinstance(var_ref, (float, int)) and nt != len(var_ref):
        ntref = len(var_ref)
        ct = var_ref.getAxis(0).subAxis(0, ntref, ntref - 1).asComponentTime()
        var = var((ct[0], ct[-1], 'cc'))
        nt = ntref
    if var.getMissing() is None: var.setMissing(1.e20)

    # Departure
    vara = var - var_ref

    # Deal with mask
    if vara.mask is not MV2.nomask:
        vara = compress(vara)
        if not isinstance(var_ref, (float, int)):
            var_ref = compress(MV2.masked_where(vara.mask, var_ref, copy=0))

    return vara, var_ref
Example #39
0
def _get_anomaly_(var,ref='mean',mean=None):

    # Basic checks
    assert var.ndim==1, 'Input variable must be 1D'
    assert cdms2.isVariable(var) and var.getTime() is not None, 'Input variable must have a proper time axis'

    # Get reference
    if ref is None: ref = 'mean'
    nt = len(var)
    if isinstance(ref,int):
        var_ref = running_average(var,ref)
    elif ref in ['demerliac','godin']:
        var_ref = eval(ref)(var,get_tide=False)
    elif ref == 'mean':
        if mean is None:
            var_ref = float(var.mean())
        else:
            var_ref = mean
    else:
        var_ref = ref
    if not isinstance(var_ref, (float, int)) and nt != len(var_ref):
        ntref = len(var_ref)
        ct = var_ref.getAxis(0).subAxis(0,ntref,ntref-1).asComponentTime()
        var = var((ct[0],ct[-1],'cc'))
        nt = ntref
    if var.getMissing() is None: var.setMissing(1.e20)

    # Departure
    vara = var - var_ref

    # Deal with mask
    if vara.mask is not MV2.nomask:
        vara = compress(vara)
        if not  isinstance(var_ref, (float, int)):
            var_ref = compress(MV2.masked_where(vara.mask, var_ref, copy=0))

    return vara, var_ref
Example #40
0
    def projectField(self, fields, neofs=None, eofscaling=0, weighted=True):
        """Project a set of fields onto the EOFs.

        Given a set of fields, projects them onto the EOFs to generate a
        corresponding set of pseudo-PCs.

        **Argument:**

        *fields*
            A list/tuple containing one or more `cdms2` variables, each
            with two or more dimensions, containing the data to be
            projected onto the EOFs. Each field must have the same
            spatial dimensions (including missing values in the same
            places) as the corresponding data set in the
            `MultivariateEof` input *datasets*. The fields may have
            different length time dimensions to the `MultivariateEof`
            inputs *datasets* or no time dimension at all, but this
            must be consistent for all fields.

        **Optional arguments:**

        *neofs*
            Number of EOFs to project onto. Defaults to all EOFs. If the
            number of EOFs requested is more than the number that are
            available, then the field will be projected onto all
            available EOFs.

        *eofscaling*
            Set the scaling of the EOFs that are projected
            onto. The following values are accepted:

            * *0* : Un-scaled EOFs (default).
            * *1* : EOFs are divided by the square-root of their
              eigenvalue.
            * *2* : EOFs are multiplied by the square-root of their
              eigenvalue.

        *weighted*
            If *True* then each field in *fields* is weighted using the
            same weights used for the EOF analysis prior to projection.
            If *False* then no weighting is applied. Defaults to *True*
            (weighting is applied). Generally only the default setting
            should be used.

        **Returns:**

        *pseudo_pcs*
            A `cdms2` variable containing the ordered pseudo-PCs.

        **Examples:**

        Project a data set onto all EOFs::

            pseudo_pcs = solver.projectField([field1, field2])

        Project a data set onto the four leading EOFs::

            pseudo_pcs = solver.projectField([field1, field2], neofs=4)

        """
        for field in fields:
            if not cdms2.isVariable(field):
                raise TypeError("the input data set must be a cdms2 variable")
        if len(fields) != self._ndata:
            raise ValueError(
                "number of fields is incorrect, expecting {:d} " "but got {:d}".format(self._ndata, len(fields))
            )
        for field in fields:
            order = field.getOrder()
            if "t" in order:
                if order[0] != "t":
                    raise ValueError("time must be the first dimension, " "consider using the reorder() method")
        pcs = self._solver.projectField(
            [f.asma() for f in fields], neofs=neofs, eofscaling=eofscaling, weighted=weighted
        )
        # Create an axis list, its contents depend on whether or not a time
        # axis was present in the input field.
        if pcs.ndim == 2:
            # Time dimension present:
            pcsax = cdms2.createAxis(range(pcs.shape[1]), id="pc")
            pcsax.long_name = "pc_number"
            axlist = [fields[0].getAxis(0), pcsax]
        else:
            # A PC axis and a leading time axis.
            pcsax = cdms2.createAxis(range(pcs.shape[0]), id="pc")
            pcsax.long_name = "pc_number"
            axlist = [pcsax]
        # Apply meta data to the projected PCs.
        pcs = cdms2.createVariable(pcs, id="pseudo_pcs", axes=axlist)
        pcs.long_name = "psuedo_pcs"
        return pcs
Example #41
0
def grid(axis_ids,latitude=None,longitude=None,latitude_vertices=None,longitude_vertices=None,nvertices=None):
    """ Creates a cmor grid
    Usage:
    grid_id = grid(axis_ids,latitude,longitude,latitude_vertices=None,longitude_vertices=None)
    Where:
    axis_ids : array contianing the axes ids for this grid.
    latitude/longitude: the values for longitude/latitude arrays (unless it is a time varying grid)
    latitude_vertices/longitude_vertices: coordinates of vertices for each latitude/latitude (unless it is a time varying grid)
    """
    if numpy.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif isinstance(axis_ids,(list,tuple)):
        axis_ids = numpy.ascontiguousarray(axis_ids)
    elif not isinstance(axis_ids, numpy.ndarray):
        raise Exception, "Error could not convert axis_ids list to a numpy array"

    if numpy.ndim(axis_ids)>1:
        raise Exception, "error axes list/array must be 1D"

    if latitude is not None:
        latitude = _to_numpy(latitude, 'latitude')

        if numpy.ndim(latitude)!=len(axis_ids):
            raise Exception, "latitude's rank does not match number of axes passed via axis_ids"

        type = latitude.dtype.char
        nvert = 0
        if not type in ['d','f','i','l']:
            raise Exception, "latitude array must be of type 'd','f','l' or 'i'"

        longitude = _to_numpy(longitude, 'longitude')

        if numpy.ndim(longitude)!=len(axis_ids):
            raise Exception, "longitude's rank does not match number of axes passed via axis_ids"

    ##     print 'longitude type:',longitude.dtype.char
        if longitude.dtype.char!=type:
            longitude = longitude.astype(type)
    elif longitude is not None:
        raise Exception, "latitude and longitude must be BOTH an array or None"
    else:
        type='f'
        if nvertices is None :
            nvert=0
        else:
            nvert = nvertices

    if latitude_vertices is not None:
        latitude_vertices = _to_numpy(latitude_vertices, 'latitude_vertices')

        if numpy.ndim(latitude_vertices)!=len(axis_ids)+1:
            raise Exception, "latitude_vertices's rank does not match number of axes passed via axis_ids +1 (for vertices)"
##         print 'latitude_vert type:',latitude_vertices.dtype.char
        if latitude_vertices.dtype.char!=type:
            latitude_vertices = latitude_vertices.astype(type)
        nvert = latitude_vertices.shape[-1]
        if nvertices is not None:
            if nvert!=nvertices:
                raise Exception,"you passed nvertices as: %i, but from your latitude_vertices it seems to be: %i" % (nvertices,nvert)

    if longitude_vertices is not None:
        longitude_vertices = _to_numpy(longitude_vertices, 'longitude_vertices')
        if numpy.ndim(longitude_vertices)!=len(axis_ids)+1:
            raise Exception, "longitude_vertices's rank does not match number of axes passed via axis_ids +1 (for vertices)"
##         print 'longitude_vert type:',longitude_vertices.dtype.char
        if longitude_vertices.dtype.char!=type:
            longitude_vertices = longitude_vertices.astype(type)
        nvert2 = longitude_vertices.shape[-1]
        if latitude_vertices is None:
            nvert = nvert2
        elif nvert!=nvert2:
            raise Exception, "error in shape longitude_vertices and latitude_vertices seem to have different # of vertices: %i vs %i, %s" % (nvert,nvert2, str(longitude_vertices.shape ))
        if nvertices is not None:
            if nvert!=nvertices:
                raise Exception,"you passed nvertices as: %i, but from your longitude_vertices it seems to be: %i" % (nvertices,nvert)


##     if area is not None:
##         if not isinstance(area,numpy.ndarray):
##             try:
##                 area = numpy.ascontiguousarray(area.filled())
##             except:
##                 raise Exception, "Error could not convert area to a numpy array"
##             if numpy.rank(area)!=len(axis_ids):
##                 raise Exception, "area's rank does not match number of axes passed via axis_ids"
##         if area.dtype.char!=type:
##             area = area.astype(type)
    n = len(axis_ids)
    axis_ids=axis_ids.astype('i');
    return _cmor.grid(n,axis_ids,type,latitude,longitude,nvert,latitude_vertices,longitude_vertices)
Example #42
0
def write(var_id,data,ntimes_passed=None,file_suffix="",time_vals=None,time_bnds=None,store_with=None):

    """ write data to a cmor variable
    Usage:
    ierr = write(var_id,data,ntimes_passed=None,file_suffix="",time_vals=None,time_bnds=None,store_with=None
    """
    if not isinstance(var_id,(int,numpy.int,numpy.int32)):
        raise Exception, "error var_id must be an integer"
    var_id = int(var_id)

    if not isinstance(file_suffix,str):
        raise Exception,  "Error file_suffix must be a string"

    if store_with is not None:
        if not isinstance(store_with,(int,numpy.int,numpy.int32)):
            raise Exception, "error store_with must be an integer"
        store_with = int(store_with)

    if numpy.ma.isMA(data):
        data = numpy.ascontiguousarray(data.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(data):
        data = numpy.ascontiguousarray(data.filled())
    elif has_cdms2 and cdms2.isVariable(data):
        if time_vals is None:
            time_vals = data.getTime()
        data = numpy.ascontiguousarray(data.filled())
    elif isinstance(data,(list,tuple)):
        data = numpy.ascontiguousarray(data)
    elif not isinstance(data, numpy.ndarray):
            raise Exception, "Error could not convert data to a numpy array"


    if time_vals is None:
        pass
    elif numpy.ma.isMA(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif has_cdms2 and isinstance(time_vals,cdms2.axis.TransientAxis):
        if time_bnds is None:
            time_bnds = time_vals.getBounds()
        time_vals = numpy.ascontiguousarray(time_vals[:])
    elif has_cdms2 and cdms2.isVariable(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif isinstance(time_vals,(list,tuple)):
        time_vals = numpy.ascontiguousarray(time_vals)
    elif not isinstance(time_vals, numpy.ndarray):
        try:
            time_vals = numpy.ascontiguousarray(time_vals)
        except:
            raise Exception, "Error could not convert time_vals to a numpy array"

    if time_vals is not None:
        type = time_vals.dtype.char
        if not type in ['f','d','i','l']:
            raise Exception, "Error time_vals type must one of: 'f','d','i','l', please convert first"
        time_vals=time_vals.astype("d")


    if ntimes_passed is None:
        if time_vals is None:
            ntimes_passed = 0
        else:
            ntimes_passed = len(time_vals)
    if not isinstance(ntimes_passed,(int,numpy.int,numpy.int32)):
        raise Exception, "error ntimes_passed must be an integer"
    ntimes_passed = int(ntimes_passed)


    #At that ponit we check that shapes matches!
    goodshape = _cmor.get_original_shape(var_id,1)
    osh = data.shape
    ogoodshape=list(goodshape)
    sh=list(osh)
    j=0
    while sh.count(1)>0:
        sh.remove(1)
    while goodshape.count(1)>0:
        goodshape.remove(1)
    for i in range(len(goodshape)):
        if goodshape[i]!=0:
            if sh[j]!=goodshape[i]:
                if goodshape[i]!=1:
                    raise Exception,"Error: your data shape (%s) does not match the expected variable shape (%s)\nCheck your variable dimensions before caling cmor_write" % (str(osh),str(ogoodshape))
            j+=1
        elif ntimes_passed!=1:
            j+=1



    data = numpy.ascontiguousarray(numpy.ravel(data))


    if time_bnds is not None:
        if numpy.ma.isMA(time_bnds):
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(time_bnds):
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif has_cdms2 and cdms2.isVariable(time_bnds):
            if time_vals is None:
                time_vals = time_bnds.getTime()
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif isinstance(time_bnds,(list,tuple)):
            time_bnds = numpy.ascontiguousarray(time_bnds)
        elif not isinstance(time_bnds, numpy.ndarray):
            raise Exception, "Error could not convert time_bnds to a numpy array"

        if numpy.ndim(time_bnds)>2:
            raise Exception, "bounds rank cannot be greater than 2"
        elif numpy.ndim(time_bnds)==2:
            if time_bnds.shape[1]!=2:
                raise Exception, "error time_bnds' 2nd dimension must be of length 2"
            bnds =[]
            if time_bnds.shape[0] > 1:
                _check_time_bounds_contiguous(time_bnds)
                bnds = _flatten_time_bounds(time_bnds)
            else:
                bnds = time_bnds.ravel()
            time_bnds=numpy.array(bnds)
        else: # ok it is a rank 1!
            if numpy.ndim(time_vals)==0:
                ltv=1
            else:
                ltv=len(time_vals)
            if len(time_bnds)!=ltv+1:
                raise Exception,"error time_bnds if 1D must be 1 elt greater than time_vals, you have %i vs %i" % (len(time_bnds),ltv)
            bnds=[]
            for i in range(ltv):
                bnds.append([time_bnds[i],time_bnds[i+1]])
            bnds=numpy.array(bnds)
            bnds = _flatten_time_bounds(bnds)
            time_bnds=numpy.array(bnds)

    if time_bnds is not None:
        type = time_bnds.dtype.char
        if not type in ['f','d','i','l']:
            raise Exception, "Error time_bnds type must one of: 'f','d','i','l', please convert first"
        time_bnds=time_bnds.astype("d")

    type = data.dtype.char
    if not type in ['f','d','i','l']:
        raise Exception, "Error data type must one of: 'f','d','i','l', please convert first"

    return _cmor.write(var_id,data,type,ntimes_passed,time_vals,time_bnds,store_with)
Example #43
0
File: scrip.py Project: AZed/uvcdat
    def __call__(self, input, gradLat, gradLon, gradLatlon):
        """gradLat = df/di
        gradLon = df/dj
        gradLatlon = d(df)/(di)(dj)
        """

        import numpy.ma
        from cdms2 import isVariable
        from cdms2.tvariable import TransientVariable

        if (gradLat.shape != input.shape or
            gradLon.shape != input.shape or
            gradLatlon.shape != input.shape):
            raise RegridError, "All input arrays must have shape %s"%`input.shape`

        if (type(gradLat) is not type(input) or
            type(gradLon) is not type(input) or
            type(gradLatlon) is not type(input)):
            raise RegridError, "All input arrays must have type %s"%`type(input)`

        # If input is a variable, make it a TV
        if isVariable(input) and not isinstance(input, TransientVariable):
            input = input.subSlice()
            gradLat = gradLat.subSlice()
            gradLon = gradLon.subSlice()
            gradLatlon = gradLatlon.subSlice()

        isvar = isinstance(input, TransientVariable)

        if isvar:
            domain = tuple(input.getAxisList())
            if self.inputGrid is not None:
                ingrid = self.inputGrid
            else:
                ingrid = input.getGrid()
            if ingrid is None:
                raise RegridError, "Input variable must have an associated grid."
            rank = len(ingrid.shape)
            gridsize = ingrid.size()
            outgridshape = self.outputGrid.shape

            # Check that the grid matches the last dimension(s) of input
            if input.shape[-rank:] != ingrid.shape:
                raise RegridError, 'Last dimensions of input array must match grid shape: %s'%`ingrid.shape`

        else:
            rank = 1                    # If not a TV, last dimension is the 'cell' dimension
            gridsize = input.shape[-1]
            outgridshape = (reduce(lambda x,y: x*y, self.outputGrid.shape, 1),)
            
        # If input is an numpy.ma, make it Numeric
        if numpy.ma.isMaskedArray(input):
            input = input.filled()
            gradLat = gradLat.filled()
            gradLon = gradLon.filled()
            gradLatlon = gradLatlon.filled()

        restoreShape = input.shape[:-rank]
        restoreLen = reduce(lambda x,y: x*y, restoreShape, 1)
        oldshape = input.shape
        newshape = (restoreLen, gridsize)
        input.shape = newshape
        gradLat.shape = newshape
        gradLon.shape = newshape
        gradLatlon.shape = newshape

        # Regrid
        output = _scrip.bicubic_regrid(self.outputGrid.size(), input, self.remapMatrix, self.sourceAddress, self.destAddress, gradLat, gradLon, gradLatlon)


        # Reshape output and restore input shape
        input.shape = oldshape
        gradLat.shape = oldshape
        gradLon.shape = oldshape
        gradLatlon.shape = oldshape
        outshape = restoreShape + outgridshape
        output.shape = outshape

        # If the input was a variable, so is the output
        if isvar:
            outdomain = domain[:-rank]+(self.outputGrid,)
            output = TransientVariable(output, axes=outdomain)

        return output
Example #44
0
    def testTV(self):
        f = self.getDataFile("test.xml")

        x = self.test_arr
        v = f.variables['v']
        vp = x[1, 1:, 4:12, 8:25]
        vp2 = vp[1, 1:-1, 1:]
        tv = v.subRegion((366., 731., 'ccn'), (-42., 42., 'ccn'), (90., 270.))
        tvv = v[0:2, 0:10, 30:40]

        # Make sure we retrieve a scalar
        xx = tv[1, 7, 15]
        self.assertFalse(isinstance(xx, numpy.ndarray))

        # Variable get: axis, grid, latitude, level, longitude, missing, order,
        # time, len, typecode

        vaxis0 = v.getAxis(0)
        axis0 = tv.getAxis(0)
        self.assertFalse(not numpy.ma.allequal(axis0[:], vaxis0[1:]))

        taxis = tv.getTime()
        taxisarray = taxis[:]
        vaxisarray = vaxis0[1:]
        self.assertFalse(not numpy.ma.allequal(taxisarray, vaxisarray))

        vaxis1 = v.getAxis(1)
        lataxis = tv.getLatitude()
        self.assertFalse(not numpy.ma.allequal(lataxis[:], vaxis1[4:12]))

        vaxis2 = v.getAxis(2)
        lonaxis = tv.getLongitude()

        #
        #  default is 'ccn' -- now it 8:25
        #
        self.assertFalse(not numpy.ma.allequal(lonaxis[:], vaxis2[8:25]))

        tv = v.subRegion((366., 731., 'ccn'), (-42., 42., 'ccn'), (90., 270.))
        missing_value = v.getMissing()
        self.assertEqual(missing_value, -99.9)

        tmv = tv.fill_value
        # TODO: Did the default value of fill_value/missing change? This is failing.
        #self.assertEqual(tmv, -99.9)

        grid = tv.getGrid()
        self.assertFalse(grid is None)

        order = tv.getOrder()
        self.assertEqual(order, 'tyx')

        self.assertEqual(len(tv), 2)

        # get TV domain
        domain = tv.getDomain()
        self.assertEqual(len(domain), 3)

        # getRegion of a TV
        tv2 = tv.getRegion(731., (-30., 30., 'ccn'), (101.25, 270.0))
        self.assertFalse(not numpy.ma.allequal(tv2, vp2))

        # Axis get: bounds, calendar, value, isXXX, len, subaxis, typecode
        axis1 = tv.getAxis(1)
        axis2 = tv.getAxis(2)
        bounds = axis1.getBounds()
        self.assertFalse(bounds is None)
        self.assertEqual(axis0.getCalendar(), cdtime.MixedCalendar)
        val = axis1.getValue()
        self.assertFalse(not numpy.ma.allequal(axis1.getValue(), axis1[:]))
        self.assertFalse(not axis0.isTime())
        self.assertFalse(not axis1.isLatitude())
        self.assertFalse(not axis2.isLongitude())
        self.assertTrue(axis2.isCircular())
        self.assertEqual(len(axis2), 17)

        saxis = axis2.subAxis(1, -1)
        self.assertFalse(not numpy.ma.allequal(saxis[:], axis2[1:-1]))
        self.assertEqual(axis1.typecode(), numpy.sctype2char(numpy.float))
        self.assertEqual(axis2.shape, (17, ))

        # Axis set: bounds, calendar
        savebounds = copy.copy(bounds)
        bounds[0, 0] = -90.0
        axis1.setBounds(bounds)
        nbounds = axis1.getBounds()
        self.assertFalse(not numpy.ma.allequal(bounds, nbounds))
        axis0.setCalendar(cdtime.NoLeapCalendar)
        self.assertEqual(axis0.getCalendar(), cdtime.NoLeapCalendar)
        gaussaxis = cdms2.createGaussianAxis(32)
        try:
            testaxis = cdms2.createGaussianAxis(31)
        except BaseException:
            markError('Gaussian axis with odd number of latitudes')

        # Grid get: axis, bounds, latitude, longitude, mask, order, type,
        # weights, subgrid, subgridRegion
        a1 = grid.getAxis(1)
        self.assertFalse(not numpy.ma.allequal(a1[:], axis2[:]))

        bounds[0, 0] = savebounds[0, 0]
        axis1.setBounds(bounds)
        latbounds, lonbounds = grid.getBounds()
        self.assertFalse(not numpy.ma.allequal(latbounds, savebounds))
        glat = grid.getLatitude()
        glon = grid.getLongitude()
        mask = grid.getMask()
        order = grid.getOrder()
        self.assertEqual(order, 'yx')
        gtype = grid.getType()
        weights = grid.getWeights()
        subg = grid.subGrid((1, 7), (1, 15))
        subg2 = grid.subGridRegion((-30., 30., 'ccn'), (101.25, 247.5, 'ccn'))
        self.assertFalse(not numpy.ma.allequal(subg.getLongitude()[:],
                                               subg2.getLongitude()[:]))
        self.assertEqual(grid.shape, (8, 17))

        # Grid set: bounds, mask, type
        latbounds[0, 0] = -90.0
        grid.setBounds(latbounds, lonbounds)
        nlatb, nlonb = grid.getBounds()
        self.assertFalse(not numpy.ma.allequal(latbounds, nlatb))
        grid.setType('uniform')
        self.assertEqual(grid.getType(), 'uniform')

        yy = numpy.ma.reshape(numpy.ma.arange(272.0), tv.shape)
        tv.assignValue(yy)
        self.assertFalse(not numpy.ma.allequal(tv, yy))
        tv3 = tv[0:-1]
        self.assertEqual(tv3.shape, (1, 8, 17))

        # Create a transient variable from scratch
        oldlat = tv.getLatitude()
        oldBounds = oldlat.getBounds()
        newlat = cdms2.createAxis(numpy.ma.array(oldlat[:]),
                                  numpy.ma.array(oldBounds))
        b = newlat.getBounds()
        b[0, 0] = -48.
        newlat.setBounds(b)

        tv4 = cdms2.createVariable(tv[:], copy=1, fill_value=255.)
        tv4[0, 1:4] = 20.0

        self.assertEqual(tv[:, ::-1, :].shape, tv.shape)

        # Test asVariable
        www = cdms2.asVariable(tv4)
        self.assertFalse(www is not tv4)
        www = cdms2.asVariable(v, 0)
        self.assertFalse(www is not v)
        www = cdms2.asVariable([1., 2., 3.])
        self.assertFalse(not cdms2.isVariable(www))

        # Check that createAxis allows an axis as an argument
        lon = f.axes['longitude']
        newlon = cdms2.createAxis(lon)
        self.assertFalse(newlon.typecode() == 'O')

        # Test take of axis without bounds
        newlat.setBounds(None)
        samp = cdms2.axis.take(newlat, (2, 4, 6))
Example #45
0
    def __call__(self, input, gradLat, gradLon, gradLatlon):
        """gradLat = df/di
        gradLon = df/dj
        gradLatlon = d(df)/(di)(dj)
        """

        import numpy.ma
        from cdms2 import isVariable
        from cdms2.tvariable import TransientVariable

        if (gradLat.shape != input.shape or gradLon.shape != input.shape
                or gradLatlon.shape != input.shape):
            raise RegridError("All input arrays must have shape %s" %
                              repr(input.shape))

        if (not isinstance(gradLat, type(input))
                or not isinstance(gradLon, type(input))
                or not isinstance(gradLatlon, type(input))):
            raise RegridError("All input arrays must have type %s" %
                              repr(type(input)))

        # If input is a variable, make it a TV
        if isVariable(input) and not isinstance(input, TransientVariable):
            input = input.subSlice()
            gradLat = gradLat.subSlice()
            gradLon = gradLon.subSlice()
            gradLatlon = gradLatlon.subSlice()

        isvar = isinstance(input, TransientVariable)

        if isvar:
            domain = tuple(input.getAxisList())
            if self.inputGrid is not None:
                ingrid = self.inputGrid
            else:
                ingrid = input.getGrid()
            if ingrid is None:
                raise RegridError(
                    "Input variable must have an associated grid.")
            rank = len(ingrid.shape)
            gridsize = ingrid.size()
            outgridshape = self.outputGrid.shape

            # Check that the grid matches the last dimension(s) of input
            if input.shape[-rank:] != ingrid.shape:
                raise RegridError(
                    'Last dimensions of input array must match grid shape: %s'
                    % repr(ingrid.shape))

        else:
            rank = 1  # If not a TV, last dimension is the 'cell' dimension
            gridsize = input.shape[-1]
            outgridshape = (reduce(lambda x, y: x * y, self.outputGrid.shape,
                                   1), )

        # If input is an numpy.ma, make it Numeric
        if numpy.ma.isMaskedArray(input):
            input = input.filled()
            gradLat = gradLat.filled()
            gradLon = gradLon.filled()
            gradLatlon = gradLatlon.filled()

        restoreShape = input.shape[:-rank]
        restoreLen = reduce(lambda x, y: x * y, restoreShape, 1)
        oldshape = input.shape
        newshape = (restoreLen, gridsize)
        input.shape = newshape
        gradLat.shape = newshape
        gradLon.shape = newshape
        gradLatlon.shape = newshape

        # Regrid
        output = _scrip.bicubic_regrid(self.outputGrid.size(), input,
                                       self.remapMatrix, self.sourceAddress,
                                       self.destAddress, gradLat, gradLon,
                                       gradLatlon)

        # Reshape output and restore input shape
        input.shape = oldshape
        gradLat.shape = oldshape
        gradLon.shape = oldshape
        gradLatlon.shape = oldshape
        outshape = restoreShape + outgridshape
        output.shape = outshape

        # If the input was a variable, so is the output
        if isvar:
            outdomain = domain[:-rank] + (self.outputGrid, )
            output = TransientVariable(output, axes=outdomain)

        return output
Example #46
0
def write(var_id,
          data,
          ntimes_passed=None,
          file_suffix="",
          time_vals=None,
          time_bnds=None,
          store_with=None):
    """ write data to a cmor variable
    Usage:
    ierr = write(var_id,data,ntimes_passed=None,file_suffix="",time_vals=None,time_bnds=None,store_with=None
    """
    if not isinstance(var_id, (int, numpy.int, numpy.int32)):
        raise Exception, "error var_id must be an integer"
    var_id = int(var_id)

    if not isinstance(file_suffix, str):
        raise Exception, "Error file_suffix must be a string"

    if store_with is not None:
        if not isinstance(store_with, (int, numpy.int, numpy.int32)):
            raise Exception, "error store_with must be an integer"
        store_with = int(store_with)

    if numpy.ma.isMA(data):
        data = numpy.ascontiguousarray(data.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(data):
        data = numpy.ascontiguousarray(data.filled())
    elif has_cdms2 and cdms2.isVariable(data):
        if time_vals is None:
            time_vals = data.getTime()
        data = numpy.ascontiguousarray(data.filled())
    elif isinstance(data, (list, tuple)):
        data = numpy.ascontiguousarray(data)
    elif not isinstance(data, numpy.ndarray):
        raise Exception, "Error could not convert data to a numpy array"

    if time_vals is None:
        pass
    elif numpy.ma.isMA(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif has_cdms2 and isinstance(time_vals, cdms2.axis.TransientAxis):
        if time_bnds is None:
            time_bnds = time_vals.getBounds()
        time_vals = numpy.ascontiguousarray(time_vals[:])
    elif has_cdms2 and cdms2.isVariable(time_vals):
        time_vals = numpy.ascontiguousarray(time_vals.filled())
    elif isinstance(time_vals, (list, tuple)):
        time_vals = numpy.ascontiguousarray(time_vals)
    elif not isinstance(time_vals, numpy.ndarray):
        try:
            time_vals = numpy.ascontiguousarray(time_vals)
        except:
            raise Exception, "Error could not convert time_vals to a numpy array"

    if time_vals is not None:
        type = time_vals.dtype.char
        if not type in ['f', 'd', 'i', 'l']:
            raise Exception, "Error time_vals type must one of: 'f','d','i','l', please convert first"
        time_vals = time_vals.astype("d")

    if ntimes_passed is None:
        if time_vals is None:
            ntimes_passed = 0
        else:
            ntimes_passed = len(time_vals)
    if not isinstance(ntimes_passed, (int, numpy.int, numpy.int32)):
        raise Exception, "error ntimes_passed must be an integer"
    ntimes_passed = int(ntimes_passed)

    #At that ponit we check that shapes matches!
    goodshape = _cmor.get_original_shape(var_id, 1)
    osh = data.shape
    ogoodshape = list(goodshape)
    sh = list(osh)
    j = 0
    while sh.count(1) > 0:
        sh.remove(1)
    while goodshape.count(1) > 0:
        goodshape.remove(1)
    for i in range(len(goodshape)):
        if goodshape[i] != 0:
            if sh[j] != goodshape[i]:
                if goodshape[i] != 1:
                    raise Exception, "error your data shape (%s) does not match the expect variable shape (%s)" % (
                        str(osh), str(ogoodshape))
            j += 1
        elif ntimes_passed != 1:
            j += 1

    data = numpy.ascontiguousarray(numpy.ravel(data))

    if time_bnds is not None:
        if numpy.ma.isMA(time_bnds):
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(time_bnds):
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif has_cdms2 and cdms2.isVariable(time_bnds):
            if time_vals is None:
                time_vals = time_bnds.getTime()
            time_bnds = numpy.ascontiguousarray(time_bnds.filled())
        elif isinstance(time_bnds, (list, tuple)):
            time_bnds = numpy.ascontiguousarray(time_bnds)
        elif not isinstance(time_bnds, numpy.ndarray):
            raise Exception, "Error could not convert time_bnds to a numpy array"

        if numpy.ndim(time_bnds) > 2:
            raise Exception, "bounds rank cannot be greater than 2"
        elif numpy.ndim(time_bnds) == 2:
            if time_bnds.shape[1] != 2:
                raise Exception, "error time_bnds' 2nd dimension must be of length 2"
            bnds = []
            if time_bnds.shape[0] > 1:
                _check_time_bounds_contiguous(time_bnds)
                bnds = _flatten_time_bounds(time_bnds)
            else:
                bnds = time_bnds.ravel()
            time_bnds = numpy.array(bnds)
        else:  # ok it is a rank 1!
            if numpy.ndim(time_vals) == 0:
                ltv = 1
            else:
                ltv = len(time_vals)
            if len(time_bnds) != ltv + 1:
                raise Exception, "error time_bnds if 1D must be 1 elt greater than time_vals, you have %i vs %i" % (
                    len(time_bnds), ltv)
            bnds = []
            for i in range(ltv):
                bnds.append([time_bnds[i], time_bnds[i + 1]])
            bnds = numpy.array(bnds)
            bnds = _flatten_time_bounds(bnds)
            time_bnds = numpy.array(bnds)

    if time_bnds is not None:
        type = time_bnds.dtype.char
        if not type in ['f', 'd', 'i', 'l']:
            raise Exception, "Error time_bnds type must one of: 'f','d','i','l', please convert first"
        time_bnds = time_bnds.astype("d")

    type = data.dtype.char
    if not type in ['f', 'd', 'i', 'l']:
        raise Exception, "Error data type must one of: 'f','d','i','l', please convert first"

    return _cmor.write(var_id, data, type, ntimes_passed, time_vals, time_bnds,
                       store_with)
Example #47
0
def zfactor(zaxis_id,
            zfactor_name,
            units="",
            axis_ids=None,
            type=None,
            zfactor_values=None,
            zfactor_bounds=None):

    if not isinstance(zaxis_id, (int, numpy.int, numpy.int32)):
        raise Exception, "error zaxis_id must be a number"
    zaxis_id = int(zaxis_id)

    if not isinstance(zfactor_name, str):
        raise Exception, "Error you must pass a string for the variable zfactor_name"

    if not isinstance(units, str):
        raise Exception, "Error you must pass a string for the variable units"

    if numpy.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif isinstance(axis_ids, (list, tuple)):
        axis_ids = numpy.ascontiguousarray(axis_ids)
    elif axis_ids is None:
        pass
    elif isinstance(axis_ids, (int, numpy.int, numpy.int32)):
        axis_ids = numpy.array([
            axis_ids,
        ])
    elif not isinstance(axis_ids, numpy.ndarray):
        raise Exception, "Error could not convert axis_ids list to a numpy array"

    if numpy.ndim(axis_ids) > 1:
        raise Exception, "error axis_ids list/array must be 1D"

    if axis_ids is None:
        ndims = 0
        axis_ids = numpy.array(1)
    else:
        ndims = len(axis_ids)


##     if ndims>1 and zfactor_values is not None:
##         raise Exception, "Error you can only pass zfactor_values for zfactor with rank <=1"
##     if ndims>1 and zfactor_bounds is not None:
##         raise Exception, "Error you can only pass zfactor_bounds for zfactor with rank <=1"

    if zfactor_values is not None:
        if isinstance(
                zfactor_values,
            (float, int, numpy.float, numpy.float32, numpy.int, numpy.int32)):
            zfactor_values = numpy.array((zfactor_values, ))
        elif numpy.ma.isMA(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif has_cdms2 and cdms2.isVariable(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif isinstance(zfactor_values, (list, tuple)):
            zfactor_values = numpy.ascontiguousarray(zfactor_values)
        elif not isinstance(zfactor_values, numpy.ndarray):
            raise Exception, "Error could not convert zfactor_values to a numpy array"

        if type is None:
            try:
                type = zfactor_values.dtype.char
            except:
                if isinstance(zfactor_values,
                              (float, numpy.float, numpy.float32)):
                    type = 'f'
                elif isinstance(zfactor_values, (int, numpy.int, numpy.int32)):
                    type = 'd'
                else:
                    raise Exception, "Error unknown type for zfactor_values: %s" % repr(
                        zfactor_values)
    elif type is None:
        type = 'd'

    if not isinstance(type, str):
        raise Exception, "error tpye must a a string"
    type = type.lower()
    if type == 's':
        type = 'c'
    if not type in ["c", "d", "f", "l", "i"]:
        raise Exception, 'error unknown type: "%s", must be one of: "c","d","f","l","i"'

    if zfactor_bounds is not None:
        if numpy.ma.isMA(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif has_cdms2 and cdms2.isVariable(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif isinstance(zfactor_bounds, (list, tuple)):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds)
        elif not isinstance(zfactor_bounds, numpy.ndarray):
            raise Exception, "Error could not convert zfactor_bounds to a numpy array"
        if numpy.ndim(zfactor_bounds) > 2:
            raise Exception, "error zfactor_bounds must be rank 2 at most"
        elif numpy.ndim(zfactor_bounds) == 2:
            if zfactor_bounds.shape[1] != 2:
                raise Exception, "error zfactor_bounds' 2nd dimension must be of length 2"
            bnds = []
            b = zfactor_bounds[0]
            for i in range(zfactor_bounds.shape[0]):
                b = zfactor_bounds[i]
                bnds.append(b[0])
                if (i < zfactor_bounds.shape[0] - 1) and (
                        b[1] != zfactor_bounds[i + 1][0]):
                    raise Exception, "error zfactor_bounds have gaps between them"
            bnds.append(zfactor_bounds[-1][1])
            zfactor_bounds = numpy.array(bnds)
    axis_ids = axis_ids.astype('i')

    ##     print "sending",zaxis_id,zfactor_name,units,ndims,axis_ids,type,zfactor_values,zfactor_bounds
    return _cmor.zfactor(zaxis_id, zfactor_name, units, ndims, axis_ids, type,
                         zfactor_values, zfactor_bounds)
Example #48
0
def dataset(experiment_id,institution,source,calendar,outpath='.',realization=1,contact="",history="",comment="",references="",leap_year=0,leap_month=0,month_lengths=None,model_id="",forcing="",initialization_method=None,physics_version=None,institute_id="",parent_experiment_id="",branch_time=None,parent_experiment_rip=""):
    """ Initialize a cmor dataset 
    Usage:
    dataset(experiment_id,institution,source,outpath='.',calendar=None,realization=None,contact=None,history="",comment="",references="",leap_year=None,leap_month=None,month_lengths=None,model_id="",forcing="",initialization_method=None,physics_version=None,institute_id="",parent_experiment_id="",branch_time=None,parent_experiment_rip="")
    """

    if isinstance(calendar,int):
        if has_cdtime: # put this in a try loop in case cdtime is not available on the system 
            if calendar == cdtime.Calendar360:
                calendar = "360_day"
            elif calendar == cdtime.ClimCalendar:
                calendar = "clim"
            elif calendar == cdtime.DefaultCalendar:
                calendar = "standard"
            elif calendar == cdtime.GregorianCalendar:
                calendar = "proleptic_gregorian"
            elif calendar == cdtime.JulianCalendar:
                calendar = "julian"
            elif calendar == cdtime.MixedCalendar:
                calendar= "standard"
            elif calendar == cdtime.NoLeapCalendar:
                calendar = "noleap"
            elif calendar == cdtime.StandardCalendar:
                calendar = "proleptic_gregorian"
            elif calendar == cdtime.ClimLeapCalendar:
                calendar = "climleap"
    elif calendar is None:
        calendar ="none"
                
    for st in [outpath,experiment_id,institution,source,contact,history,comment,references,model_id,forcing,institute_id,parent_experiment_id,parent_experiment_rip]:
        if not isinstance(st,str):
            for o in dir():
                if locals()[o] is st:
                    raise Exception, "Error argument %s must be a string" % o

    calendar = calendar.lower()
    
    for i in [realization,leap_year,leap_month]:
        if not isinstance(i,int):
            for o in dir():
                if locals()[o] is i:
                    raise Exception, "Error argument %s must be an integer" % o
    if isinstance(month_lengths,(list,tuple)):
        month_lengths = numpy.array(month_lengths)
    elif has_cdms2 and cdms2.isVariable(month_lengths):
        month_lengths = month_lengths.filled()
    elif isinstance(month_lengths,(numpy.ma.core.MaskedArray)):
        month_lengths = month_lengths.filled()
    elif has_oldma and isinstance(month_lengths,numpy.oldnumeric.ma.MaskedArray):
        month_lengths = month_lengths.filled()
        
    if isinstance(month_lengths,numpy.ndarray):
        if not numpy.rank(month_lengths)==1:
            raise Exception, "Error month_lengths must be 1D"
        if len(month_lengths)!=12:
            raise Exception, "Error month_lengths must have 12 elements exactly"
        months_lengths = numpy.ascontiguousarray(month_lengths)
    elif month_lengths is not None:
        raise Exception, "Error month_lengths must be a 12 elts array or list"
    if initialization_method is not None:
        if not isinstance(initialization_method,int):
            raise Exception, "initialization_method must be an int"
    else:
        initialization_method=0
    if physics_version is not None:
        if not isinstance(physics_version,int):
            raise Exception, "physics_version must be an int"
    else:
        physics_version=0

    if branch_time is not None:
        if not isinstance(branch_time,(float,int,numpy.float,numpy.float32,numpy.int,numpy.int32)):
            raise Exception,"branch_time must be a float"
        else:
            branch_time=float(branch_time)

    return _cmor.dataset(outpath,experiment_id,institution,source,calendar,realization,contact,history,comment,references,leap_year,leap_month,month_lengths,model_id,forcing,initialization_method,physics_version,institute_id,parent_experiment_id,branch_time,parent_experiment_rip)
Example #49
0
    def __init__(self, *datasets, **kwargs):
        """Create a MultipleEof object.

        The EOF solution is computed at initialization time. Method
        calls are used to retrieve computed quantities.

        **Arguments:**

        *\*datasets*
            One or more :py:mod:`cdms2` variables containing the data to
            be analyzed. Time must be the first dimension of each
            variable. Missing values are allowed provided that they are
            constant with time (e.g., values of an oceanographic field
            over land).
        
        **Optional arguments:**

        *weights*
            Sets the weighting method. The following values are
            accepted:

            * *"area"* : Square-root of grid cell area normalized by
              total area. Requires a latitude-longitude grid to be
              present in the corresponding :py:mod:`cdms2` variable
              in *\*datasets*. This is a fairly standard weighting
              strategy. If you are unsure which method to use and you
              have gridded data then this should be your first choice.

            * *"coslat"* : Square-root of cosine of latitude
              (*"cos_lat"* is also accepted). Requires a latitude
              dimension to be present in the corresponding
              :py:mod:`cmds2` variable in *\*datasets*.

            * *"none"* : Equal weights for all grid points (default).

            * *None* : Same as *"none"*.

             A sequence of values may be passed to use different
             weighting for each data set. Arrays of weights may also
             be supplied instead of specifying a weighting method.

        *center*
            If *True*, the mean along the first axis of the input data
            sets (the time-mean) will be removed prior to analysis. If
            *False*, the mean along the first axis will not be removed.
            Defaults to *True* (mean is removed). Generally this option
            should be set to *True* as the covariance interpretation
            relies on input data being anomalies with a time-mean of 0.
            A valid reson for turning this off would be if you have
            already generated an anomaly data set. Setting to *True* has
            the useful side-effect of propagating missing values along
            the time-dimension, ensuring the solver will work even if
            missing values occur at different locations at different
            times.

        *ddof*
            'Delta degrees of freedom'. The divisor used to normalize
            the covariance matrix is *N - ddof* where *N* is the
            number of samples. Defaults to *1*.

        **Examples:**

        EOF analysis with area-weighting using two input fields:

        >>> from eof2 import Eof
        >>> eofobj = Eof(field_a, field_b, weights="area")

        """
        # Handle keyword arguments manually.
        keywords = {"weights": "none", "center": True, "ddof":1}
        for kwarg in kwargs:
            if kwarg not in keywords.keys():
                raise EofError("invalid argument: %s." % kwarg)
        weights = kwargs.get("weights", keywords["weights"])
        center = kwargs.get("center", keywords["center"])
        ddof = kwargs.get("ddof", keywords["ddof"])
        # Record the number of datasets.
        self._numdsets = len(datasets)
        # Ensure the weights are specified one per dataset.
        if weights in ("none", None, "area", "cos_lat", "coslat"):
            weights = [weights] * self._numdsets
        elif len(weights) != self._numdsets:
            raise EofError("number of weights and data sets differs")
        # Record dimension information, missing values and compute weights.
        self._multitimeaxes = list()
        self._multichannels = list()
        self._multimissing = list()
        passweights = list()
        for dataset, weight in zip(datasets, weights):
            if not cdms2.isVariable(dataset):
                raise EofError("the input data set must be a cdms2 variable")
            # Ensure a time dimension exists.
            timeaxis = dataset.getTime()
            if timeaxis is None:
                raise EofError("time axis not found")
            self._multitimeaxes.append(timeaxis)
            # Ensure the time dimension is the first dimension.
            order = dataset.getOrder()
            if order[0] != "t":
                raise EofError("time must be the first dimension")
            # Record the other dimensions.
            channels = dataset.getAxisList()
            channels.remove(timeaxis)
            if len(channels) < 1:
                raise EofError("one or more spatial dimensions are required")
            self._multichannels.append(channels)
            # Record the missing values.
            self._multimissing.append(dataset.getMissing())
            # Compute weights as required.
            if weight in ("none", None):
                passweights.append(None)
            else:
                try:
                    wtarray = weights_array(dataset, scheme=weight.lower())
                    passweights.append(wtarray)
                except AttributeError:
                    # Weight specification is not a string. Assume it is an array
                    # of weights.
                    passweights.append(weight)
                except EofToolError, err:
                    # Another error occured, raise it as an EOF error.
                    raise EofError(err)
Example #50
0
oldBounds = oldlat.getBounds()
newlat = cdms2.createAxis(numpy.ma.array(oldlat[:]),numpy.ma.array(oldBounds))
b = newlat.getBounds()
b[0,0]=-48.
newlat.setBounds(b)

tv4 = cdms2.createVariable(tv[:],copy=1,fill_value=255.)
tv4[0,1:4]=20.0

if tv[:,::-1,:].shape != tv.shape: markError("Reversing axis direction")

# Test asVariable
www = cdms2.asVariable(tv4)
if www is not tv4: markError("asVariable failed, transient case.")
www = cdms2.asVariable (v, 0)
if www is not v:   markError("asVariable failed, transient case.")
www = cdms2.asVariable([1.,2.,3.])
if not cdms2.isVariable(www): markError("as/is test failed.")

# Check that createAxis allows an axis as an argument
lon = f.axes['longitude']
newlon = cdms2.createAxis(lon)
if newlon.typecode()=='O': markError("createAxis failed: allow axis arg")

# Test take of axis without bounds
newlat.setBounds(None)
samp = cdms2.axis.take(newlat,(2,4,6))

f.close()
reportError()
Example #51
0
    def __init__(self, dataset, weights=None, center=True, ddof=1):
        """Create an Eof object.

        The EOF solution is computed at initialization time. Method
        calls are used to retrieve computed quantities.

        **Argument:**

        *dataset*
            A `cdms2` variable containing the data to be analysed. Time
            must be the first dimension. Missing values are allowed
            provided that they are constant with time (e.g., values of
            an oceanographic field over land).

        **Optional arguments:**

        *weights*
            Sets the weighting method. The following pre-defined
            weighting methods are available:

            * *'area'* : Square-root of grid cell area normalized by
              total grid area. Requires a latitude-longitude grid to be
              present in the `cdms2` variable *dataset*. This is a
              fairly standard weighting strategy. If you are unsure
              which method to use and you have gridded data then this
              should be your first choice.

            * *'coslat'* : Square-root of cosine of latitude. Requires a
              latitude dimension to be present in the `cdms2` variable
              *dataset*.

            * *None* : Equal weights for all grid points (*'none'* is
              also accepted).

             Alternatively an array of weights whose shape is compatible
             with the `cdms2` variable *dataset* may be supplied instead
             of specifying a weighting method.

        *center*
            If *True*, the mean along the first axis of *dataset* (the
            time-mean) will be removed prior to analysis. If *False*,
            the mean along the first axis will not be removed. Defaults
            to *True* (mean is removed).

            The covariance interpretation relies on the input data being
            anomalies with a time-mean of 0. Therefore this option
            should usually be set to *True*. Setting this option to
            *True* has the useful side effect of propagating missing
            values along the time dimension, ensuring that a solution
            can be found even if missing values occur in different
            locations at different times.

        *ddof*
            'Delta degrees of freedom'. The divisor used to normalize
            the covariance matrix is *N - ddof* where *N* is the
            number of samples. Defaults to *1*.

        **Returns:**

        *solver*
            An `Eof` instance.

        **Examples:**

        EOF analysis with grid-cell-area weighting for the input field::

            from eofs.cdms import Eof
            solver = Eof(dataset, weights='area')

        """
        # Check that dataset is recognised by cdms2 as a variable.
        if not cdms2.isVariable(dataset):
            raise TypeError('the input data must be a cdms2 variable')
        # Store the time axis as an instance variable.
        self._timeax = dataset.getTime()
        # Verify that a time axis was found, getTime returns None when a
        # time axis is not found.
        if self._timeax is None:
            raise ValueError('time axis not found')
        # Check the dimension order of the input, time must be the first
        # dimension.
        order = dataset.getOrder()
        if order[0] != 't':
            raise ValueError('time must be the first dimension, '
                             'consider using the reorder() method')
        # Verify the presence of at least one spatial dimension. The
        # instance variable channels will also be used as a partial axis
        # list when constructing meta-data. It contains the spatial
        # dimensions.
        self._channels = dataset.getAxisList()
        self._channels.remove(self._timeax)
        if len(self._channels) < 1:
            raise ValueError('one or more spatial dimensions are required')
        # Store the missing value attribute of the data set in an
        # instance variable so that it is recoverable later.
        self._missing_value = dataset.getMissing()
        # Generate an appropriate set of weights for the input dataset. There
        # are several weighting schemes. The 'area' weighting scheme requires
        # a latitude-longitude grid to be present, the 'cos_lat' scheme only
        # requires a latitude dimension.
        if weights in ('none', None):
            # No weights requested, set the weight array to None.
            wtarray = None
        else:
            try:
                # Generate a weights array of the appropriate kind, with a
                # shape compatible with the data set.
                scheme = weights.lower()
                wtarray = weights_array(dataset, scheme=scheme)
            except AttributeError:
                # Weights is not a string, assume it is an array.
                wtarray = weights
            except ValueError, err:
                # Weights is not recognized, raise an error.
                raise ValueError(err)
Example #52
0
    def __init__(self, datasets, weights=None, center=True, ddof=1):
        """Create a MultivariateEof object.

        The EOF solution is computed at initialization time. Method
        calls are used to retrieve computed quantities.

        **Arguments:**

        *datasets*
            A list/tuple containing one or more `cdms2` variables, each
            two or more dimensions, containing the data to be analysed.
            Time must be the first dimension of each variable. Missing
            values are allowed provided that they are constant with time
            in each field (e.g., values of an oceanographic field over
            land).

        **Optional arguments:**

        *weights*
            Sets the weighting method. One method can be chosen to apply
            to all variables in *datasets* or a sequence of options can
            be given to specify a different weighting method for each
            variable in *datasets*. The following pre-defined weighting
            methods are available:

            * *'area'* : Square-root of grid cell area normalized by
              total grid area. Requires a latitude-longitude grid to be
              present in the corresponding `cdms2` variable. This is a
              fairly standard weighting strategy. If you are unsure
              which method to use and you have gridded data then this
              should be your first choice.

            * *'coslat'* : Square-root of cosine of latitude. Requires a
              latitude dimension to be present in the corresponding
              `cdms2` variable.

            * *None* : Equal weights for all grid points (*'none'* is
              also accepted).

             Alternatively a sequence of arrays of weights whose shapes
             are compatible with the corresponding `cdms2` variables in
             *datasets* may be supplied instead of specifying a
             weighting method.

        *center*
            If *True*, the mean along the first axis of each variable in
            *datasets* (the time-mean) will be removed prior to
            analysis. If *False*, the mean along the first axis will not
            be removed. Defaults to *True* (mean is removed).

            The covariance interpretation relies on the input data being
            anomalies with a time-mean of 0. Therefore this option
            should usually be set to *True*. Setting this option to
            *True* has the useful side effect of propagating missing
            values along the time dimension, ensuring that a solution
            can be found even if missing values occur in different
            locations at different times.

        *ddof*
            'Delta degrees of freedom'. The divisor used to normalize
            the covariance matrix is *N - ddof* where *N* is the
            number of samples. Defaults to *1*.

        **Returns:**

        *solver*
            An `MultivariateEof` instance.

        **Examples:**

        EOF analysis with grid-cell-area weighting using two input
        fields::

            from eofs.multivariate.cdms import MultivariateEof
            solver = MultivariateEof([var1, var2], weights='area')

        """
        # Record the number of datasets.
        self._ndata = len(datasets)
        # Ensure the weights are specified one per dataset.
        if weights in ("none", None, "area", "coslat"):
            weights = [weights] * self._ndata
        elif len(weights) != self._ndata:
            raise ValueError(
                "number of weights is incorrect, " "expecting {:d} but got {:d}".format(self._ndata, len(weights))
            )
        # Record dimension information, missing values and compute weights.
        self._multitimeaxes = list()
        self._multichannels = list()
        self._multimissing = list()
        passweights = list()
        for dataset, weight in zip(datasets, weights):
            if not cdms2.isVariable(dataset):
                raise TypeError("the input data set must be a cdms2 variable")
            # Ensure a time dimension exists.
            timeaxis = dataset.getTime()
            if timeaxis is None:
                raise ValueError("time axis not found")
            self._multitimeaxes.append(timeaxis)
            # Ensure the time dimension is the first dimension.
            order = dataset.getOrder()
            if order[0] != "t":
                raise ValueError("time must be the first dimension, " "consider using the reorder() method")
            # Record the other dimensions.
            channels = dataset.getAxisList()
            channels.remove(timeaxis)
            if len(channels) < 1:
                raise ValueError("one or more spatial dimensions are required")
            self._multichannels.append(channels)
            # Record the missing values.
            self._multimissing.append(dataset.getMissing())
            # Compute weights as required.
            if weight in ("none", None):
                passweights.append(None)
            else:
                try:
                    wtarray = weights_array(dataset, scheme=weight.lower())
                    passweights.append(wtarray)
                except AttributeError:
                    # Weight specification is not a string. Assume it is an
                    # array of weights.
                    passweights.append(weight)
                # any other error will be raised
        # Define a time axis as the time axis of the first dataset.
        self._timeax = self._multitimeaxes[0]
        # Create a MultipleEofSolver to do the computations.
        self._solver = standard.MultivariateEof(
            [d.asma() for d in datasets], weights=passweights, center=center, ddof=ddof
        )
        #: Number of EOFs in the solution.
        self.neofs = self._solver.neofs
        # Names of the input variables.
        self._dataset_names = map(lambda v: cdms2_name(v).replace(" ", "_"), datasets)
        self._dataset_ids = [dataset.id for dataset in datasets]
Example #53
0
def grid(axis_ids,
         latitude=None,
         longitude=None,
         latitude_vertices=None,
         longitude_vertices=None,
         nvertices=None):
    """ Creates a cmor grid
    Usage:
    grid_id = grid(axis_ids,latitude,longitude,latitude_vertices=None,longitude_vertices=None)
    Where:
    axis_ids : array contianing the axes ids for this grid.
    latitude/longitude: the values for longitude/latitude arrays (unless it is a time varying grid)
    latitude_vertices/longitude_vertices: coordinates of vertices for each latitude/latitude (unless it is a time varying grid)
    """
    if numpy.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif isinstance(axis_ids, (list, tuple)):
        axis_ids = numpy.ascontiguousarray(axis_ids)
    elif not isinstance(axis_ids, numpy.ndarray):
        raise Exception, "Error could not convert axis_ids list to a numpy array"

    if numpy.ndim(axis_ids) > 1:
        raise Exception, "error axes list/array must be 1D"

    if latitude is not None:
        latitude = _to_numpy(latitude, 'latitude')

        if numpy.ndim(latitude) != len(axis_ids):
            raise Exception, "latitude's rank does not match number of axes passed via axis_ids"

        type = latitude.dtype.char
        nvert = 0
        if not type in ['d', 'f', 'i', 'l']:
            raise Exception, "latitude array must be of type 'd','f','l' or 'i'"

        longitude = _to_numpy(longitude, 'longitude')

        if numpy.ndim(longitude) != len(axis_ids):
            raise Exception, "longitude's rank does not match number of axes passed via axis_ids"

    ##     print 'longitude type:',longitude.dtype.char
        if longitude.dtype.char != type:
            longitude = longitude.astype(type)
    elif longitude is not None:
        raise Exception, "latitude and longitude must be BOTH an array or None"
    else:
        type = 'f'
        if nvertices is None:
            nvert = 0
        else:
            nvert = nvertices

    if latitude_vertices is not None:
        latitude_vertices = _to_numpy(latitude_vertices, 'latitude_vertices')

        if numpy.ndim(latitude_vertices) != len(axis_ids) + 1:
            raise Exception, "latitude_vertices's rank does not match number of axes passed via axis_ids +1 (for vertices)"
##         print 'latitude_vert type:',latitude_vertices.dtype.char
        if latitude_vertices.dtype.char != type:
            latitude_vertices = latitude_vertices.astype(type)
        nvert = latitude_vertices.shape[-1]
        if nvertices is not None:
            if nvert != nvertices:
                raise Exception, "you passed nvertices as: %i, but from your latitude_vertices it seems to be: %i" % (
                    nvertices, nvert)

    if longitude_vertices is not None:
        longitude_vertices = _to_numpy(longitude_vertices,
                                       'longitude_vertices')
        if numpy.ndim(longitude_vertices) != len(axis_ids) + 1:
            raise Exception, "longitude_vertices's rank does not match number of axes passed via axis_ids +1 (for vertices)"
##         print 'longitude_vert type:',longitude_vertices.dtype.char
        if longitude_vertices.dtype.char != type:
            longitude_vertices = longitude_vertices.astype(type)
        nvert2 = longitude_vertices.shape[-1]
        if latitude_vertices is None:
            nvert = nvert2
        elif nvert != nvert2:
            raise Exception, "error in shape longitude_vertices and latitude_vertices seem to have different # of vertices: %i vs %i, %s" % (
                nvert, nvert2, str(longitude_vertices.shape))
        if nvertices is not None:
            if nvert != nvertices:
                raise Exception, "you passed nvertices as: %i, but from your longitude_vertices it seems to be: %i" % (
                    nvertices, nvert)


##     if area is not None:
##         if not isinstance(area,numpy.ndarray):
##             try:
##                 area = numpy.ascontiguousarray(area.filled())
##             except:
##                 raise Exception, "Error could not convert area to a numpy array"
##             if numpy.rank(area)!=len(axis_ids):
##                 raise Exception, "area's rank does not match number of axes passed via axis_ids"
##         if area.dtype.char!=type:
##             area = area.astype(type)
    n = len(axis_ids)
    axis_ids = axis_ids.astype('i')
    return _cmor.grid(n, axis_ids, type, latitude, longitude, nvert,
                      latitude_vertices, longitude_vertices)
Example #54
0
def axis(table_entry,units=None,length=None,coord_vals=None,cell_bounds=None,interval=None):
    """ Creates an cmor_axis
    Usage:
    axis_id = axis(table_entry,units=None,length=None,coord_vals=None,cell_bounds=None,interval=None)
    Where:
    table_entry: table_entry in the cmor table
    units: the axis units
    length: the number of coord_vals to actuall y use, or simply the number of coord_vals in case in index_only axes
    coord_vals: cmds2 axis or numpy/MV2 array (1D)
    cell_bounds: numpy or MV2 array, if coord_vals is a cdms2 axis then will try to obtain bounds from it
    interval: a string used for time axes only (???)
    """
    if not isinstance(table_entry,str):
        raise Exception, "You need to pass a table_entry to match in the cmor table"

    if coord_vals is None:
        if cell_bounds is not None:
            raise Exception, "you passed cell_bounds but no coords"
    else:
        if has_cdms2 and isinstance(coord_vals,cdms2.axis.TransientAxis):
            if units is None:
                if hasattr(coord_vals,"units"):
                    units = coord_vals.units
            if cell_bounds is None:
                cell_bounds = coord_vals.getBounds()

            if interval is None and hasattr(coord_vals,"interval"):
                interval = coord_vals.interval
            coord_vals = numpy.ascontiguousarray(coord_vals[:])
        elif isinstance(coord_vals,(list,tuple)):
            coord_vals = numpy.ascontiguousarray(coord_vals)
        elif has_cdms2 and cdms2.isVariable(coord_vals):
            if units is None:
                if hasattr(coord_vals,"units"):
                    units = coord_vals.units
            if interval is None and hasattr(coord_vals,"interval"):
                interval = coord_vals.interval
            coord_vals = numpy.ascontiguousarray(coord_vals.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(coord_vals):
            coord_vals = numpy.ascontiguousarray(coord_vals.filled())
        elif numpy.ma.isMA(coord_vals):
            coord_vals = numpy.ascontiguousarray(coord_vals.filled())

        if not isinstance(coord_vals,numpy.ndarray):
            raise Exception, "Error coord_vals must be an array or cdms2 axis or list/tuple"

        if numpy.ndim(coord_vals)>1:
            raise Exception, "Error, you must pass a 1D array!"

    if numpy.ma.isMA(cell_bounds):
        cell_bounds = numpy.ascontiguousarray(cell_bounds.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(cell_bounds):
        cell_bounds = numpy.ascontiguousarray(cell_bounds.filled())
    elif has_cdms2 and cdms2.isVariable(cell_bounds):
        cell_bounds = numpy.ascontiguousarray(cell_bounds.filled())
    elif has_cdms2 and cdms2.isVariable(cell_bounds):
        cell_bounds = numpy.ascontiguousarray(cell_bounds.filled())
    elif isinstance(cell_bounds,(list,tuple)):
        cell_bounds = numpy.ascontiguousarray(cell_bounds)

    if cell_bounds is not None:
        if numpy.ndim(cell_bounds)>2:
            raise Exception, "Error cell_bounds rank must be at most 2"
        if numpy.ndim(cell_bounds)==2:
            if cell_bounds.shape[0]!=coord_vals.shape[0]:
                raise Exception, "Error, coord_vals and cell_bounds do not have the same length"
            if cell_bounds.shape[1]!=2:
                raise Exception, "Error, cell_bounds' second dimension must be of length 2"
            cbnds = 2
            cell_bounds = numpy.ascontiguousarray(numpy.ravel(cell_bounds))
        else:
            cbnds = 1
            if len(cell_bounds)!=len(coord_vals)+1:
                raise Exception, "error cell_bounds are %i long and axes coord_vals are %i long this is not consistent" % (len(cell_bounds),len(coord_vals))
    else:
        cbnds = 0

    if coord_vals is not None:
        l = len(coord_vals)
        type = coord_vals.dtype.char[0]

        if not type in ['i','l','f','d','S']:
            raise Exception, "error allowed data type are: i,l,f,d or S"

        if type == 'S':
            type = 'c'
            cbnds = 0
            for s in coord_vals:
                #print 'testing:',s,len(s)
                if len(s)>cbnds:
                    cbnds = len(s)
            #cbnds+=1
    else:
        l = 0
        type = 'd'

    if cell_bounds is not None:
        if type !=cell_bounds.dtype.char:
            cell_bounds = cell_bounds.astype(type)

    if units is None:
        if coord_vals is not None:
            raise Exception, "Error you need to provide the units your coord_vals are in"
        else:
            units = "1"

    if interval is None:
        interval = ""

    if length is not None:
        l = int(length)

    return _cmor.axis(table_entry,units,l,coord_vals,type,cell_bounds,cbnds,interval)
Example #55
0
    def __init__(self, dataset, weights="none", center=True, ddof=1):
        """Create an Eof object.
        
        **Argument:**

        *dataset*
            A :py:mod:`cdms2` variable containing the data to be
            analyzed. Time must be the first dimension. Missing values
            are allowed provided that they are constant with time (e.g.,
            values of an oceanographic field over land).
        
        **Optional arguments:**

        *weights*
            Sets the weighting method. The following values are
            accepted:

            * *"area"* : Square-root of grid cell area normalized by
              total area. Requires a latitude-longitude grid to be
              present in the input :py:mod:`cdms2` variable *dataset*.
              This is a fairly standard weighting strategy. If you are
              unsure which method to use and you have gridded data then
              this should be your first choice.

            * *"coslat"* : Square-root of cosine of latitude
              (*"cos_lat"* is also accepted). Requires a latitude
              dimension to be present in the input :py:mod:`cdms2`
              variable *dataset*.

            * *"none"* : Equal weights for all grid points (default).

            * *None* : Same as *"none"*.

             An array of weights may also be supplied instead of
             specifying a weighting method.

        *center*
            If *True*, the mean along the first axis of the input data
            set (the time-mean) will be removed prior to analysis. If
            *False*, the mean along the first axis will not be removed.
            Defaults to *True* (mean is removed). Generally this option
            should be set to *True* as the covariance interpretation
            relies on input data being anomalies with a time-mean of 0.
            A valid reson for turning this off would be if you have
            already generated an anomaly data set. Setting to *True* has
            the useful side-effect of propagating missing values along
            the time-dimension, ensuring the solver will work even if
            missing values occur at different locations at different
            times.

        *ddof*
            'Delta degrees of freedom'. The divisor used to normalize
            the covariance matrix is *N - ddof* where *N* is the
            number of samples. Defaults to *1*.

        **Examples:**

        EOF analysis with area-weighting for the input field:

        >>> from eof2 import Eof
        >>> eofobj = Eof(field, weights="area")

        """
        # Check that dataset is recognised by cdms2 as a variable.
        if not cdms2.isVariable(dataset):
            raise EofError("the input data must be a cdms2 variable")
        # Store the time axis as an instance variable.
        self._timeax = dataset.getTime()
        # Verify that a time axis was found, getTime returns None when a
        # time axis is not found.
        if self._timeax is None:
            raise EofError("time axis not found")
        # Check the dimension order of the input, time must be the first
        # dimension.
        order = dataset.getOrder()
        if order[0] != "t":
            raise EofError("time must be the first dimension")
        # Verify the presence of at least one spatial dimension. The
        # instance variable channels will also be used as a partial axis
        # list when constructing meta-data. It contains the spatial
        # dimensions.
        self._channels = dataset.getAxisList()
        self._channels.remove(self._timeax)
        if len(self._channels) < 1:
            raise EofError("one or more spatial dimensions are required")
        # Store the missing value attribute of the data set in an
        # instance variable so that it is recoverable later.
        self._missing_value = dataset.getMissing()
        # Generate an appropriate set of weights for the input dataset. There
        # are several weighting schemes. The "area" weighting scheme requires
        # a latitude-longitude grid to be present, the "cos_lat" scheme only
        # requires a latitude dimension.
        if weights in ("none", None):
            # No weights requested, set the weight array to None.
            wtarray = None
        else:
            try:
                # Generate a weights array of the appropriate kind, with a
                # shape compatible with the data set.
                scheme = weights.lower()
                wtarray = weights_array(dataset, scheme=scheme)
            except AttributeError:
                # Weights is not a string, assume it is an array.
                wtarray = weights
            except EofToolError, err:
                # Weights is not recognized, raise an error.
                raise EofError(err)
Example #56
0
def variable(table_entry,units,axis_ids,type='f',missing_value=None,tolerance = 1.e-4,positive=None,original_name=None,history=None,comment=None):

    if not isinstance(table_entry,str):
        raise Exception, "Error you must pass a string for the variable table_entry"

    if not isinstance(units,str):
        raise Exception, "Error you must pass a string for the variable units"

    if original_name is not None:
        if not isinstance(original_name,str):
            raise Exception, "Error you must pass a string for the variable original_name"
    else:
        original_name = ""

    if history is not None:
        if not isinstance(history,str):
            raise Exception, "Error you must pass a string for the variable history"
    else:
        history = ""

    if comment is not None:
        if not isinstance(comment,str):
            raise Exception, "Error you must pass a string for the variable comment"
    else:
        comment = ""

    if numpy.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif isinstance(axis_ids,(list,tuple)):
        axis_ids = numpy.ascontiguousarray(axis_ids)
    elif not isinstance(axis_ids, numpy.ndarray):
        raise Exception, "Error could not convert axis_ids list to a numpy array"

    if numpy.ndim(axis_ids)>1:
        raise Exception, "error axis_ids list/array must be 1D"

    if not isinstance(type,str):
        raise Exception, "error tpye must a a string"
    type = type.lower()
    if type == 's':
        type ='c'
    if not type in ["c","d","f","l","i"]:
        raise Exception, 'error unknown type: "%s", must be one of: "c","d","f","l","i"'

    ndims = len(axis_ids)

    if positive is None:
        positive = ""
    else:
        positive = str(positive)

    if history is None:
        history = ""
    else:
        history = str(history)

    if comment is None:
        comment = ""
    else:
        comment = str(comment)

    if not isinstance(tolerance,(float,int,numpy.float,numpy.float32,numpy.int,numpy.int32)):
        raise Exception, "error tolerance must be a number"

    tolerance = float(tolerance)

    if missing_value is not None:
        if not isinstance(missing_value,(float,int,numpy.float,numpy.float32,numpy.int,numpy.int32)):
            raise Exception, "error missing_value must be a number, you passed: %s" % repr(missing_value)

        missing_value = float(missing_value)

    axis_ids=axis_ids.astype('i')
    return _cmor.variable(table_entry,units,ndims,axis_ids,type,missing_value,tolerance,positive,original_name,history,comment)
Example #57
0
    def __call__(self, input):

        import numpy.ma
        from cdms2 import isVariable
        from cdms2.tvariable import TransientVariable

        # If input is a variable, make it a TV
        if isVariable(input) and not isinstance(input, TransientVariable):
            input = input.subSlice()

        isvar = isinstance(input, TransientVariable)

        if isvar:
            domain = tuple(input.getAxisList())
            if self.inputGrid is not None:
                ingrid = self.inputGrid
            else:
                ingrid = input.getGrid()
            if ingrid is None:
                raise RegridError(
                    "Input variable must have an associated grid.")
            rank = len(ingrid.shape)
            gridsize = ingrid.size()
            outgridshape = self.outputGrid.shape

            # Check that the grid matches the last dimension(s) of input
            if input.shape[-rank:] != ingrid.shape:
                raise RegridError(
                    'Last dimensions of input array must match grid shape: %s'
                    % repr(ingrid.shape))
            # this expects contiguous arrays
            if input.iscontiguous() is False:
                input = input.ascontiguous()

        else:
            rank = 1  # If not a TV, last dimension is the 'cell' dimension
            gridsize = input.shape[-1]
            outgridshape = (reduce(lambda x, y: x * y, self.outputGrid.shape,
                                   1), )

        # If input is an numpy.ma, make it Numeric
        if numpy.ma.isMaskedArray(input):
            input = input.filled()

        restoreShape = input.shape[:-rank]
        restoreLen = reduce(lambda x, y: x * y, restoreShape, 1)
        oldshape = input.shape
        newshape = (restoreLen, gridsize)
        input.shape = newshape

        # Regrid
        output = self.regrid(input)

        # Reshape output and restore input shape
        input.shape = oldshape
        outshape = restoreShape + outgridshape
        output.shape = outshape

        # If the input was a variable, so is the output
        if isvar:
            outdomain = domain[:-rank] + (self.outputGrid, )
            output = TransientVariable(output, axes=outdomain)

        return output
Example #58
0
def zfactor(zaxis_id,zfactor_name,units="",axis_ids=None,type=None,zfactor_values=None,zfactor_bounds=None):

    if not isinstance(zaxis_id,(int,numpy.int,numpy.int32)):
        raise Exception, "error zaxis_id must be a number"
    zaxis_id = int(zaxis_id)

    if not isinstance(zfactor_name,str):
        raise Exception, "Error you must pass a string for the variable zfactor_name"

    if not isinstance(units,str):
        raise Exception, "Error you must pass a string for the variable units"

    if numpy.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_oldma and numpy.oldnumeric.ma.isMA(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif has_cdms2 and cdms2.isVariable(axis_ids):
        axis_ids = numpy.ascontiguousarray(axis_ids.filled())
    elif isinstance(axis_ids,(list,tuple)):
        axis_ids = numpy.ascontiguousarray(axis_ids)
    elif axis_ids is None:
        pass
    elif isinstance(axis_ids,(int,numpy.int,numpy.int32)):
        axis_ids = numpy.array([axis_ids,])
    elif not isinstance(axis_ids, numpy.ndarray):
        raise Exception, "Error could not convert axis_ids list to a numpy array"

    if numpy.ndim(axis_ids)>1:
        raise Exception, "error axis_ids list/array must be 1D"

    if axis_ids is None:
        ndims = 0
        axis_ids = numpy.array(1)
    else:
        ndims = len(axis_ids)

##     if ndims>1 and zfactor_values is not None:
##         raise Exception, "Error you can only pass zfactor_values for zfactor with rank <=1"
##     if ndims>1 and zfactor_bounds is not None:
##         raise Exception, "Error you can only pass zfactor_bounds for zfactor with rank <=1"

    if zfactor_values is not None:
        if isinstance(zfactor_values,(float,int,numpy.float,numpy.float32,numpy.int,numpy.int32)):
            zfactor_values = numpy.array((zfactor_values,))
        elif numpy.ma.isMA(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif has_cdms2 and cdms2.isVariable(zfactor_values):
            zfactor_values = numpy.ascontiguousarray(zfactor_values.filled())
        elif isinstance(zfactor_values,(list,tuple)):
            zfactor_values = numpy.ascontiguousarray(zfactor_values)
        elif not isinstance(zfactor_values, numpy.ndarray):
            raise Exception, "Error could not convert zfactor_values to a numpy array"

        if type is None:
            try:
                type = zfactor_values.dtype.char
            except:
                if isinstance(zfactor_values,(float,numpy.float,numpy.float32)):
                    type = 'f'
                elif isinstance(zfactor_values,(int,numpy.int,numpy.int32)):
                    type = 'd'
                else:
                    raise Exception, "Error unknown type for zfactor_values: %s" % repr(zfactor_values)
    elif type is None:
        type='d'


    if not isinstance(type,str):
        raise Exception, "error tpye must a a string"
    type = type.lower()
    if type == 's':
        type ='c'
    if not type in ["c","d","f","l","i"]:
        raise Exception, 'error unknown type: "%s", must be one of: "c","d","f","l","i"'

    if zfactor_bounds is not None:
        if numpy.ma.isMA(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif has_oldma and numpy.oldnumeric.ma.isMA(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif has_cdms2 and cdms2.isVariable(zfactor_bounds):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds.filled())
        elif isinstance(zfactor_bounds,(list,tuple)):
            zfactor_bounds = numpy.ascontiguousarray(zfactor_bounds)
        elif not isinstance(zfactor_bounds, numpy.ndarray):
            raise Exception, "Error could not convert zfactor_bounds to a numpy array"
        if numpy.ndim(zfactor_bounds)>2:
            raise Exception, "error zfactor_bounds must be rank 2 at most"
        elif numpy.ndim(zfactor_bounds)==2:
            if zfactor_bounds.shape[1]!=2:
                raise Exception, "error zfactor_bounds' 2nd dimension must be of length 2"
            bnds =[]
            b = zfactor_bounds[0]
            for i in range(zfactor_bounds.shape[0]):
                b = zfactor_bounds[i]
                bnds.append(b[0])
                if (i<zfactor_bounds.shape[0]-1) and (b[1]!=zfactor_bounds[i+1][0]):
                    raise Exception, "error zfactor_bounds have gaps between them"
            bnds.append(zfactor_bounds[-1][1])
            zfactor_bounds=numpy.array(bnds)
    axis_ids = axis_ids.astype('i')

##     print "sending",zaxis_id,zfactor_name,units,ndims,axis_ids,type,zfactor_values,zfactor_bounds
    return _cmor.zfactor(zaxis_id,zfactor_name,units,ndims,axis_ids,type,zfactor_values,zfactor_bounds)
Example #59
0
def putMetadata(meta, tv, **args):
    import cdms2 as cdms
    if cdms.isVariable(meta): meta = getMetadata(meta, **args)
    return cdms.createVariable(tv, axes=meta[0], attributes=meta[1])
Example #60
0
    def projectField(self, field, neofs=None, eofscaling=0, weighted=True):
        """Project a field onto the EOFs.

        Given a data set, projects it onto the EOFs to generate a
        corresponding set of pseudo-PCs.

        **Argument:**

        *field*
            A `cdms2` variable containing the field to project onto the
            EOFs. It must have the same corresponding spatial dimensions
            (including missing values in the same places) as the `Eof`
            input *dataset*. It may have a different length time
            dimension to the `Eof` input *dataset* or no time dimension
            at all. If a time dimension exists it must be the first
            dimension.

        **Optional arguments:**

        *neofs*
            Number of EOFs to project onto. Defaults to all EOFs. If the
            number of EOFs requested is more than the number that are
            available, then the field will be projected onto all
            available EOFs.

        *eofscaling*
            Set the scaling of the EOFs that are projected
            onto. The following values are accepted:

            * *0* : Un-scaled EOFs (default).
            * *1* : EOFs are divided by the square-root of their eigenvalue.
            * *2* : EOFs are multiplied by the square-root of their
              eigenvalue.

        *weighted*
            If *True* then the field is weighted using the same weights
            used for the EOF analysis prior to projection. If *False*
            then no weighting is applied. Defaults to *True* (weighting
            is applied). Generally only the default setting should be
            used.

        **Returns:**

        *pseudo_pcs*
            A `cdms2` variable containing the pseudo-PCs. The PCs are
            numbered from 0 to *neofs* - 1.

        **Examples:**

        Project a field onto all EOFs::

            pseudo_pcs = solver.projectField(field)

        Project fields onto the three leading EOFs::

            pseudo_pcs = solver.projectField(field, neofs=3)

        """
        # Check that field is recognised by cdms2 as a variable.
        if not cdms2.isVariable(field):
            raise TypeError('the input field must be a cdms2 variable')
        dataset_name = cdms2_name(field).replace(' ', '_')
        # Compute the projected PCs.
        pcs = self._solver.projectField(field.asma(),
                                        neofs=neofs,
                                        eofscaling=eofscaling,
                                        weighted=weighted)
        # Construct the required axes.
        if pcs.ndim == 2:
            # 2D PCs require a time axis and a PC axis.
            pcsax = cdms2.createAxis(range(pcs.shape[1]), id='pc')
            pcsax.long_name = 'pc_number'
            timeax = field.getAxis(0)  # time is assumed to be first anyway
            axlist = [timeax, pcsax]
        else:
            # 1D PCs require only a PC axis.
            pcsax = cdms2.createAxis(range(pcs.shape[0]), id='pc')
            pcsax.long_name = 'pc_number'
            axlist = [pcsax]
        # Apply meta data to the projected PCs.
        pcs = cdms2.createVariable(pcs, id='pseudo_pcs', axes=axlist)
        pcs.long_name = '{:s}_pseudo_pcs'.format(dataset_name)
        return pcs