Example #1
0
def __myGetAxisWeights(x, i, axisoptions=None):
    """ Assume x is an MV2 duh! and get the weights associated with axis index i.
    index i can be any of the dimensions in x whose bounds are available.
    If bounds are not available then an error is raised.
    """
    if x.getAxis(i).isLatitude():
        Lataxis = x.getAxis(i)
        xgr = cdms2.createGenericGrid(Lataxis[:], numpy.array(range(1), numpy.float), latBounds=Lataxis.getBounds())
        xlatwt, xlonwt = xgr.getWeights()
        return xlatwt
    elif x.getAxis(i).isLongitude():
        Lonaxis = x.getAxis(i)
        xgr = cdms2.createGenericGrid(numpy.array(range(1), numpy.float), Lonaxis[:], lonBounds=Lonaxis.getBounds())
        xlatwt, xlonwt = xgr.getWeights()
        return xlonwt
    else:
        axis_bounds = x.getAxis(i).getBounds()
        if axis_bounds is None:
	    ax=x.getAxis(i)
            if axisoptions is not None:
                axo=cdms2.orderparse(axisoptions)
                if (i in axo ) or (ax.isTime() and 't' in axo) or (ax.isLevel() and 'z' in axo) or ('('+ax.id+')' in axo):
                    raise AveragerError, 'Bounds not available to compute weights on dimension: '+ax.id
                else:
                    axis_wts=numpy.ones(x.getAxis(i)[:].shape)
            else:
                raise AveragerError, 'Bounds not available to compute weights for dimension: '+ax.id
        else:
            axis_wts =  abs(axis_bounds[..., 1] - axis_bounds[..., 0])
        return axis_wts
Example #2
0
def __myGetAxisWeights(x, i, axisoptions=None):
    """ Assume x is an MV2 duh! and get the weights associated with axis index i.
    index i can be any of the dimensions in x whose bounds are available.
    If bounds are not available then an error is raised.
    """
    if x.getAxis(i).isLatitude():
        Lataxis = x.getAxis(i)
        xgr = cdms2.createGenericGrid(Lataxis[:], numpy.array(range(1), numpy.float), latBounds=Lataxis.getBounds())
        xlatwt, xlonwt = xgr.getWeights()
        return xlatwt
    elif x.getAxis(i).isLongitude():
        Lonaxis = x.getAxis(i)
        xgr = cdms2.createGenericGrid(numpy.array(range(1), numpy.float), Lonaxis[:], lonBounds=Lonaxis.getBounds())
        xlatwt, xlonwt = xgr.getWeights()
        return xlonwt
    else:
        axis_bounds = x.getAxis(i).getBounds()
        if axis_bounds is None:
	    ax=x.getAxis(i)
            if axisoptions is not None:
                axo=cdms2.orderparse(axisoptions)
                if (i in axo ) or (ax.isTime() and 't' in axo) or (ax.isLevel() and 'z' in axo) or ('('+ax.id+')' in axo):
                    raise AveragerError, 'Bounds not available to compute weights on dimension: '+ax.id
                else:
                    axis_wts=numpy.ones(x.getAxis(i)[:].shape)
            else:
                raise AveragerError, 'Bounds not available to compute weights for dimension: '+ax.id
        else:
            axis_wts =  abs(axis_bounds[..., 1] - axis_bounds[..., 0])
        return axis_wts
Example #3
0
def _check_axisoptions(x, axisoptions):
    """checks the axis=options to make sure that it is valid"""
    axlist = cdms2.orderparse(axisoptions)
    if Ellipsis in axlist:
        raise AveragerError, 'Error: Ellipsis (...) not allowed in axis options'
    try:
        cdms2.order2index(x.getAxisList(), axisoptions)
        return axlist
    except:
        raise AveragerError, 'Error: You have specified an invalid axis= option.'
Example #4
0
def _check_axisoptions(x, axisoptions):
    """checks the axis=options to make sure that it is valid"""
    axlist = cdms2.orderparse(axisoptions)
    if Ellipsis in axlist:
        raise AveragerError, 'Error: Ellipsis (...) not allowed in axis options'
    try:
        cdms2.order2index(x.getAxisList(), axisoptions)
        return axlist
    except:
        raise AveragerError, 'Error: You have specified an invalid axis= option.'
Example #5
0
def check_order(var, allowed, vertical=None, copy=False, reorder=False,
    extended=None, getorder=False):
    """Check that the axis order of a variable is matches
    at least one the specifed valid orders

    :Params:

        - **var**: MV2 array.
        - **allowed**: A single order string or a list. It should contain one or
          several of these letters:

            - ``x``: longitudes,
            - ``y``: latitudes,
            - ``z``: vertical levels,
            - ``t``: time axis,
            - ``d``: data values (ignored),
            - ``-``: any kind of axis.

    :Return:

        ``var``, or ``var, order, reordered`` if **reorder** is True.
    """

    # Check allowed orders
    # - consistency
    if not isinstance(allowed, (list, tuple)):
        allowed = [allowed]
    else:
        allowed = list(allowed)
    withd = 'd' in allowed[0]
    get_rank = lambda o: len(o.replace('d', ''))
    rank = get_rank(allowed[0])
    for order in allowed:
        try:
            cdms2.orderparse(order.lower().replace('d', ''))
        except:
            raise VACUMMError("Wrong allowed order: "+order)
        if ('d' in order and not withd) or ('d' not in order and withd):
            raise VACUMMError("'d' only partially present in allowed order: %s"%allowed)
        if get_rank(order)!=rank:
            raise VACUMMError("Inconsistent ranks between allowed orders: %s"%[get_rank(o) for o in allowed])
    # - check extended mode
    if extended is None: # extended?
        re_upper = re.compile('[XYZT]').search
        for order in allowed:
            if re_upper(order) is not None:
                extended = True # force extended mode
                break
        else:
            extended = False
    if extended is False: # lower
        allowed = [order.lower() for order in allowed]
    else: #add tolerance for lower case orders
        re_sub = re.compile('[xyzt]').sub
        allowed = allowed+[re_sub('-', order) for order in allowed]
    # - unique and lower case
    _, idx = N.unique(allowed, return_index=True)
    idx = N.sort(idx)
    allowed = N.array(allowed)[idx].tolist()
    # - restrict to vertical or horizontal (1D data only)
    if vertical is not None and len(allowed[0])==2:
        allowed = [oo for oo in allowed if oo[int(vertical)]=='d']

    # Data order
    data_cdms_order = get_order(var)

    # Loop on allowed orders
    from vacumm.misc.grid.misc import get_axis, var2d
    reordered = False
    for allowed_order in allowed:

        # Handle data case
        d = allowed_order.find('d')
        if d!=-1: allowed_order = allowed_order.replace('d', '') # pure axis

        # Check cdms order
        allowed_cdms_order = allowed_order.lower() # lower case
        if order_match(data_cdms_order, allowed_cdms_order, strict='right'): break # It is already good

        # Try to reorder
        if reorder:

            try:
                reordered = cdms2.order2index(var.getAxisList(), allowed_cdms_order)
                new_var = var.reorder(allowed_cdms_order)
                if allowed_cdms_order[-1]=='x' and len(get_axis(new_var, -1).shape)==2: # 2D axes
                    del var
                    var = var2d(new_var,
                        MV2.transpose(get_axis(new_var, 0)),
                        MV2.transpose(get_axis(new_var, -1)), copy=0)
                    set_order(new_var, allowed_cdms_order)
                else:
                    del var
                    var = new_var
                data_cdms_order = get_order(var)
                break # No error so it worked and we leave

            except:
                continue

    else:
        raise VACUMMError('Wrong type of axes. Possible forms are: %s'%', '.join(allowed))

    if not getorder: return var
    if d!=-1:
        data_cdms_order = cdms2.orderparse(data_cdms_order)
        data_cdms_order.insert(d, 'd')
        data_cdms_order = ''.join(data_cdms_order)
    return var, data_cdms_order, reordered
Example #6
0
def __check_weightoptions(x, axisoptions, weightoptions):
    """
    Checks the weights=options to make sure that it is valid.
    
    Default: 'weighted'
    
    weight options are one of 'weighted', 'unweighted',  an array of weights for each 
    dimension or a MaskedVariable of the same shape as the data x.
    - 'weighted' means use the grid information to generate weights for that
      dimension or if multiple axes are passed, generate goes ahead and
      generates the full masked area weights.
    - 'unweighted' means use equal weights for all the grid points in that axis. 
    - Also an array of weights (of the same shape as the dimension being 
      averaged over or same shape as V) can be passed.
    """
    #
    # Since the _check_axisoptions was passed, the variable x has already been reordered
    # to the required order..... check it anyway.
    #
    #
    __DEBUG__ = 0
    #
    if __DEBUG__: print 'Axis options entering __check_weightoptions = ', axisoptions
    #
    axisindex = cdms2.order2index(x.getAxisList(), axisoptions)
    if __DEBUG__: print 'This should be 0,1,2... etc. is it? ', axisindex
    #
    axislist = cdms2.orderparse(axisoptions)
    if __DEBUG__: print 'axislist = ', axislist
    #
    if not isinstance(weightoptions, types.ListType):
        #
        # We have either 1 axis only or multiple axes and one MV2 of weights
        #
        if MV2.isMaskedVariable(weightoptions):
            #
            # Weight passed is an MV2. Probably OK
            #
            try:
                # We had required that the weights be of the same rank as the variable to be averaged.
                weightoptions = weightoptions(order=axisoptions)
                #
                # KRISHNA : check this for combinewts!!
                #
##                 if x.shape != weightoptions.shape:
##                     raise AveragerError, \
##                           'Error: Shape of weight array does not match shape of data array'
##                 # end of if x.shape != weightoptions.shape:
                if __DEBUG__: print '... definitely OK'
            except:
                raise AveragerError, \
                      'Error: Did not find the axes requested in the Masked variable.'
        elif len(axislist) == 1:
            #
            # Only one axis to reduce over....'
            # figure out if it is an array (numpy or numpy.ma) or 'equal' or 'generate' or something else
            #
            if __DEBUG__: print 'I have only 1 axis and 1 option'
            weightoptions = __check_each_weight_option(x, axislist[0], axisindex[0], weightoptions)
        else:
            #
            # More than 1 axis to reduce over, and not an MV2 of the same dimensionality as x!
            #
            if weightoptions in ['generate','weighted']:
                weightoptions = area_weights(x,axisoptions)
            else:
                # Cannot do this because 'generate' was not passed with multiple axes.
                raise AveragerError, 'Error: Multiple axes passed without weights to match'
            # end of if weightoptions == 'generate':
    else:
        #
        # I have a list of weightoptions i.e more than 1 axis in axisoption
        #
        #
        # We have multiple axes to deal with each with a weight....
        #
        for i in range(len(axislist)):
            weightoptions[i] = __check_each_weight_option(x, axislist[i], axisindex[i], weightoptions[i])
        # end of for i in range(len(axislist)):
        #
        if len(axislist) < len(weightoptions):
            for j in range(len(axislist), len(weightoptions), 1):
                weightoptions[j] = __check_each_weight_option(x, None, j, weightoptions[j])
        # end of if len(axislist) < len(weightoptions):
    # end of if not isinstance(weightoptions, types.ListType):
    #
    if __DEBUG__: print 'Successful with __check_weightoptions'
    #
    return weightoptions
Example #7
0
def __check_weightoptions(x, axisoptions, weightoptions):
    """
    Checks the weights=options to make sure that it is valid.
    
    Default: 'weighted'
    
    weight options are one of 'weighted', 'unweighted',  an array of weights for each 
    dimension or a MaskedVariable of the same shape as the data x.
    - 'weighted' means use the grid information to generate weights for that
      dimension or if multiple axes are passed, generate goes ahead and
      generates the full masked area weights.
    - 'unweighted' means use equal weights for all the grid points in that axis. 
    - Also an array of weights (of the same shape as the dimension being 
      averaged over or same shape as V) can be passed.
    """
    #
    # Since the _check_axisoptions was passed, the variable x has already been reordered
    # to the required order..... check it anyway.
    #
    #
    __DEBUG__ = 0
    #
    if __DEBUG__:
        print 'Axis options entering __check_weightoptions = ', axisoptions
    #
    axisindex = cdms2.order2index(x.getAxisList(), axisoptions)
    if __DEBUG__: print 'This should be 0,1,2... etc. is it? ', axisindex
    #
    axislist = cdms2.orderparse(axisoptions)
    if __DEBUG__: print 'axislist = ', axislist
    #
    if not isinstance(weightoptions, types.ListType):
        #
        # We have either 1 axis only or multiple axes and one MV2 of weights
        #
        if MV2.isMaskedVariable(weightoptions):
            #
            # Weight passed is an MV2. Probably OK
            #
            try:
                # We had required that the weights be of the same rank as the variable to be averaged.
                weightoptions = weightoptions(order=axisoptions)
                #
                # KRISHNA : check this for combinewts!!
                #
                ##                 if x.shape != weightoptions.shape:
                ##                     raise AveragerError, \
                ##                           'Error: Shape of weight array does not match shape of data array'
                ##                 # end of if x.shape != weightoptions.shape:
                if __DEBUG__: print '... definitely OK'
            except:
                raise AveragerError, \
                      'Error: Did not find the axes requested in the Masked variable.'
        elif len(axislist) == 1:
            #
            # Only one axis to reduce over....'
            # figure out if it is an array (numpy or numpy.ma) or 'equal' or 'generate' or something else
            #
            if __DEBUG__: print 'I have only 1 axis and 1 option'
            weightoptions = __check_each_weight_option(x, axislist[0],
                                                       axisindex[0],
                                                       weightoptions)
        else:
            #
            # More than 1 axis to reduce over, and not an MV2 of the same dimensionality as x!
            #
            if weightoptions in ['generate', 'weighted']:
                weightoptions = area_weights(x, axisoptions)
            else:
                # Cannot do this because 'generate' was not passed with multiple axes.
                raise AveragerError, 'Error: Multiple axes passed without weights to match'
            # end of if weightoptions == 'generate':
    else:
        #
        # I have a list of weightoptions i.e more than 1 axis in axisoption
        #
        #
        # We have multiple axes to deal with each with a weight....
        #
        for i in range(len(axislist)):
            weightoptions[i] = __check_each_weight_option(
                x, axislist[i], axisindex[i], weightoptions[i])
        # end of for i in range(len(axislist)):
        #
        if len(axislist) < len(weightoptions):
            for j in range(len(axislist), len(weightoptions), 1):
                weightoptions[j] = __check_each_weight_option(
                    x, None, j, weightoptions[j])
        # end of if len(axislist) < len(weightoptions):
    # end of if not isinstance(weightoptions, types.ListType):
    #
    if __DEBUG__: print 'Successful with __check_weightoptions'
    #
    return weightoptions
Example #8
0
def check_order(var,
                allowed,
                vertical=None,
                copy=False,
                reorder=False,
                extended=None,
                getorder=False):
    """Check that the axis order of a variable is matches
    at least one the specifed valid orders

    :Params:

        - **var**: MV2 array.
        - **allowed**: A single order string or a list. It should contain one or
          several of these letters:

            - ``x``: longitudes,
            - ``y``: latitudes,
            - ``z``: vertical levels,
            - ``t``: time axis,
            - ``d``: data values (ignored),
            - ``-``: any kind of axis.

    :Return:

        ``var``, or ``var, order, reordered`` if **reorder** is True.
    """

    # Check allowed orders
    # - consistency
    if not isinstance(allowed, (list, tuple)):
        allowed = [allowed]
    else:
        allowed = list(allowed)
    withd = 'd' in allowed[0]
    get_rank = lambda o: len(o.replace('d', ''))
    rank = get_rank(allowed[0])
    for order in allowed:
        try:
            cdms2.orderparse(order.lower().replace('d', ''))
        except:
            raise VACUMMError("Wrong allowed order: " + order)
        if ('d' in order and not withd) or ('d' not in order and withd):
            raise VACUMMError(
                "'d' only partially present in allowed order: %s" % allowed)
        if get_rank(order) != rank:
            raise VACUMMError("Inconsistent ranks between allowed orders: %s" %
                              [get_rank(o) for o in allowed])
    # - check extended mode
    if extended is None:  # extended?
        re_upper = re.compile('[XYZT]').search
        for order in allowed:
            if re_upper(order) is not None:
                extended = True  # force extended mode
                break
        else:
            extended = False
    if extended is False:  # lower
        allowed = [order.lower() for order in allowed]
    else:  #add tolerance for lower case orders
        re_sub = re.compile('[xyzt]').sub
        allowed = allowed + [re_sub('-', order) for order in allowed]
    # - unique and lower case
    _, idx = N.unique(allowed, return_index=True)
    idx = N.sort(idx)
    allowed = N.array(allowed)[idx].tolist()
    # - restrict to vertical or horizontal (1D data only)
    if vertical is not None and len(allowed[0]) == 2:
        allowed = [oo for oo in allowed if oo[int(vertical)] == 'd']

    # Data order
    data_cdms_order = get_order(var)

    # Loop on allowed orders
    from vacumm.misc.grid.misc import get_axis, var2d
    reordered = False
    for allowed_order in allowed:

        # Handle data case
        d = allowed_order.find('d')
        if d != -1: allowed_order = allowed_order.replace('d', '')  # pure axis

        # Check cdms order
        allowed_cdms_order = allowed_order.lower()  # lower case
        if order_match(data_cdms_order, allowed_cdms_order, strict='right'):
            break  # It is already good

        # Try to reorder
        if reorder:

            try:
                reordered = cdms2.order2index(var.getAxisList(),
                                              allowed_cdms_order)
                new_var = var.reorder(allowed_cdms_order)
                if allowed_cdms_order[-1] == 'x' and len(
                        get_axis(new_var, -1).shape) == 2:  # 2D axes
                    del var
                    var = var2d(new_var,
                                MV2.transpose(get_axis(new_var, 0)),
                                MV2.transpose(get_axis(new_var, -1)),
                                copy=0)
                    set_order(new_var, allowed_cdms_order)
                else:
                    del var
                    var = new_var
                data_cdms_order = get_order(var)
                break  # No error so it worked and we leave

            except:
                continue

    else:
        raise VACUMMError('Wrong type of axes. Possible forms are: %s' %
                          ', '.join(allowed))

    if not getorder: return var
    if d != -1:
        data_cdms_order = cdms2.orderparse(data_cdms_order)
        data_cdms_order.insert(d, 'd')
        data_cdms_order = ''.join(data_cdms_order)
    return var, data_cdms_order, reordered