Пример #1
0
    def test1DMissing(self):
        yx = self.x.createyxvsx()

        data = """-11.14902417  -9.17390922  -7.29515002
        -7.51774549  -8.63608171
          -10.4827395   -9.93859485  -7.3394366   -5.39241468  -5.74825567
             -6.74967902  -7.09622319  -5.93836983  -4.04592997  -2.65591499
                -1.68180032  -0.86935245  -0.40114047  -0.54273785  -1.36178957
                   -2.67488251  -3.87524401  -4.84708491  -5.49186142  -5.28618944
                      -4.30557389  -2.89804038  -1.53825408  -1.84771029  -2.74948361
                         -2.23517037  -1.73306118  -0.71200646   0.76416785   1.51511193
                            -0.04018418  -1.54564706  -1.88664877  -0.43751604   0.89988184
                                0.33437949  -1.70341844  -3.79880014  -4.03570169  -4.7740073
                                   -5.04626101  -3.77609961  -3.18667176  -2.21038272  -1.3666902
                                      -0.54267951  -0.16472441  -0.52871418  -0.83520848  -0.90315403
                                         -0.21747426   0.01922666   0.89621996   1.75691927   3.12657503
                                             4.55749531   6.04921304   7.20744489   7.65294958""".split(
        )
        data = numpy.array(data, dtype=numpy.float)
        data = MV2.array(data)

        data = MV2.masked_where(MV2.logical_and(data > -4, data < -2), data)

        self.x.plot(data, yx, bg=self.bg)
        fnm = "test_vcs_1d_missing.png"
        self.checkImage(fnm)
Пример #2
0
def loop(potential,potential_reg,c2,w3,region):
    nmax        = potential.shape[0]
    c3          = MV2.not_equal(w3,0.)
    c           = MV2.logical_and(c2,c3)
    thisturn    = MV2.ones(c.shape)
    for i in range(nmax):
        c1                  = MV2.logical_or(MV2.equal(potential_reg[i],region),MV2.equal(potential[i],-999))
        c2                  = MV2.logical_and(c,c1)
        c2                  = MV2.logical_and(c2,thisturn)
        potential_reg[i]    = MV2.where(c2,region,potential_reg[i])
        thisturn            = MV2.where(c2,0,thisturn)
        c1                  = MV2.logical_and(c2,MV2.equal(potential[i],-999))
        c2                  = MV2.logical_and(c2,MV2.not_equal(potential[i],-999))
        potential[i]        = MV2.where(c1,w3,potential[i])
        potential[i]        = MV2.where(c2,potential[i]+w3,potential[i])
    ## Ultimate test to see if more would be needed !
    if not MV2.allequal(MV2.logical_and(c,thisturn),0):
        raise 'OOOPS WE COULD USE MORE REGIONS BUDDY !'
    return
Пример #3
0
  -10.4827395   -9.93859485  -7.3394366   -5.39241468  -5.74825567
     -6.74967902  -7.09622319  -5.93836983  -4.04592997  -2.65591499
        -1.68180032  -0.86935245  -0.40114047  -0.54273785  -1.36178957
           -2.67488251  -3.87524401  -4.84708491  -5.49186142  -5.28618944
              -4.30557389  -2.89804038  -1.53825408  -1.84771029  -2.74948361
                 -2.23517037  -1.73306118  -0.71200646   0.76416785   1.51511193
                    -0.04018418  -1.54564706  -1.88664877  -0.43751604   0.89988184
                        0.33437949  -1.70341844  -3.79880014  -4.03570169  -4.7740073
                           -5.04626101  -3.77609961  -3.18667176  -2.21038272  -1.3666902
                              -0.54267951  -0.16472441  -0.52871418  -0.83520848  -0.90315403
                                 -0.21747426   0.01922666   0.89621996   1.75691927   3.12657503
                                     4.55749531   6.04921304   7.20744489   7.65294958""".split()
data = numpy.array(data,dtype=numpy.float)
data = MV2.array(data)

data=MV2.masked_where(MV2.logical_and(data>-4,data<-2),data)

#yx.datawc_x1 = 0
#yx.datawc_x2 = 80
##yx.datawc_y1 =-12 
#yx.datawc_y2 = 12 


x.plot(data,yx,bg=1)
fnm = "test_vcs_1d_missing.png"
x.png(fnm)

print "fnm:",fnm
print "src:",src
ret = checkimage.check_result_image(fnm,src,checkimage.defaultThreshold)
sys.exit(ret)
Пример #4
0
def linearInterpolation(A,
                        I,
                        levels=[
                            100000, 92500, 85000, 70000, 60000, 50000, 40000,
                            30000, 25000, 20000, 15000, 10000, 7000, 5000,
                            3000, 2000, 1000
                        ],
                        status=None):
    """
    Linear interpolation
    to interpolate a field from some levels to another set of levels
    Value below "surface" are masked
    
    Input
    A :      array to interpolate
    I :      interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level), i.e P value going up with each level
    levels : levels to interplate to (same units as I), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]

    I and levels must have same units

    Output
    array on new levels (levels)
    
    Examples:
    A=interpolate(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
    """

    try:
        nlev = len(levels)  # Number of pressure levels
    except:
        nlev = 1  # if only one level len(levels) would breaks
        levels = [
            levels,
        ]
    order = A.getOrder()
    A = A(order='z...')
    I = I(order='z...')
    sh = list(I.shape)
    nsigma = sh[0]  #number of sigma levels
    sh[0] = nlev
    t = MV2.zeros(sh, typecode=MV2.float32)
    sh2 = I[0].shape
    prev = -1
    for ilev in range(nlev):  # loop through pressure levels
        if status is not None:
            prev = genutil.statusbar(ilev, nlev - 1., prev)
        lev = levels[ilev]  # get value for the level
        Iabv = MV2.ones(sh2, MV2.float)
        Aabv = -1 * Iabv  # Array on sigma level Above
        Abel = -1 * Iabv  # Array on sigma level Below
        Ibel = -1 * Iabv  # Pressure on sigma level Below
        Iabv = -1 * Iabv  # Pressure on sigma level Above
        Ieq = MV2.masked_equal(Iabv, -1)  # Area where Pressure == levels
        for i in range(1, nsigma):  # loop from second sigma level to last one
            a = MV2.greater_equal(
                I[i], lev)  # Where is the pressure greater than lev
            b = MV2.less_equal(I[i - 1],
                               lev)  # Where is the pressure less than lev
            # Now looks if the pressure level is in between the 2 sigma levels
            # If yes, sets Iabv, Ibel and Aabv, Abel
            a = MV2.logical_and(a, b)
            Iabv = MV2.where(a, I[i], Iabv)  # Pressure on sigma level Above
            Aabv = MV2.where(a, A[i], Aabv)  # Array on sigma level Above
            Ibel = MV2.where(a, I[i - 1],
                             Ibel)  # Pressure on sigma level Below
            Abel = MV2.where(a, A[i - 1], Abel)  # Array on sigma level Below
            Ieq = MV2.where(MV2.equal(I[i], lev), A[i], Ieq)

        val = MV2.masked_where(
            MV2.equal(Ibel, -1.),
            numpy.ones(Ibel.shape) *
            lev)  # set to missing value if no data below lev if there is

        tl = (val - Ibel) / (Iabv - Ibel) * (Aabv -
                                             Abel) + Abel  # Interpolation
        if ((Ieq.mask is None) or (Ieq.mask is MV22.nomask)):
            tl = Ieq
        else:
            tl = MV2.where(1 - Ieq.mask, Ieq, tl)
        t[ilev] = tl.astype(MV2.float32)

    ax = A.getAxisList()
    autobnds = cdms2.getAutoBounds()
    cdms2.setAutoBounds('off')
    lvl = cdms2.createAxis(MV2.array(levels).filled())
    cdms2.setAutoBounds(autobnds)
    try:
        lvl.units = I.units
    except:
        pass
    lvl.id = 'plev'

    try:
        t.units = I.units
    except:
        pass

    ax[0] = lvl
    t.setAxisList(ax)
    t.id = A.id
    for att in A.listattributes():
        setattr(t, att, getattr(A, att))
    return t(order=order)
Пример #5
0
def logLinearInterpolation(A,
                           P,
                           levels=[
                               100000, 92500, 85000, 70000, 60000, 50000,
                               40000, 30000, 25000, 20000, 15000, 10000, 7000,
                               5000, 3000, 2000, 1000
                           ],
                           status=None):
    """
    Log-linear interpolation
    to convert a field from sigma levels to pressure levels
    Value below surface are masked
    
    Input
    A :    array on sigma levels
    P :    pressure field from TOP (level 0) to BOTTOM (last level)
    levels : pressure levels to interplate to (same units as P), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]

    P and levels must have same units

    Output
    array on pressure levels (levels)
    
    Examples:
    A=logLinearInterpolation(A,P),levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
    """

    try:
        nlev = len(levels)  # Number of pressure levels
    except:
        nlev = 1  # if only one level len(levels) would breaks
        levels = [
            levels,
        ]
    order = A.getOrder()
    A = A(order='z...')
    P = P(order='z...')
    sh = list(P.shape)
    nsigma = sh[0]  #number of sigma levels
    sh[0] = nlev
    t = MV2.zeros(sh, typecode=MV2.float32)
    sh2 = P[0].shape
    prev = -1
    for ilev in range(nlev):  # loop through pressure levels
        if status is not None:
            prev = genutil.statusbar(ilev, nlev - 1., prev)
        lev = levels[ilev]  # get value for the level
        Pabv = MV2.ones(sh2, MV2.float)
        Aabv = -1 * Pabv  # Array on sigma level Above
        Abel = -1 * Pabv  # Array on sigma level Below
        Pbel = -1 * Pabv  # Pressure on sigma level Below
        Pabv = -1 * Pabv  # Pressure on sigma level Above
        Peq = MV2.masked_equal(Pabv, -1)  # Area where Pressure == levels
        for i in range(1, nsigma):  # loop from second sigma level to last one
            a = MV2.greater_equal(
                P[i], lev)  # Where is the pressure greater than lev
            b = MV2.less_equal(P[i - 1],
                               lev)  # Where is the pressure less than lev
            # Now looks if the pressure level is in between the 2 sigma levels
            # If yes, sets Pabv, Pbel and Aabv, Abel
            a = MV2.logical_and(a, b)
            Pabv = MV2.where(a, P[i], Pabv)  # Pressure on sigma level Above
            Aabv = MV2.where(a, A[i], Aabv)  # Array on sigma level Above
            Pbel = MV2.where(a, P[i - 1],
                             Pbel)  # Pressure on sigma level Below
            Abel = MV2.where(a, A[i - 1], Abel)  # Array on sigma level Below
            Peq = MV2.where(MV2.equal(P[i], lev), A[i], Peq)

        val = MV2.masked_where(
            MV2.equal(Pbel, -1),
            numpy.ones(Pbel.shape) *
            lev)  # set to missing value if no data below lev if there is

        tl = MV2.log(val / Pbel) / MV2.log(
            Pabv / Pbel) * (Aabv - Abel) + Abel  # Interpolation
        if ((Peq.mask is None) or (Peq.mask is MV2.nomask)):
            tl = Peq
        else:
            tl = MV2.where(1 - Peq.mask, Peq, tl)
        t[ilev] = tl.astype(MV2.float32)

    ax = A.getAxisList()
    autobnds = cdms2.getAutoBounds()
    cdms2.setAutoBounds('off')
    lvl = cdms2.createAxis(MV2.array(levels).filled())
    cdms2.setAutoBounds(autobnds)
    try:
        lvl.units = P.units
    except:
        pass
    lvl.id = 'plev'

    try:
        t.units = P.units
    except:
        pass

    ax[0] = lvl
    t.setAxisList(ax)
    t.id = A.id
    for att in A.listattributes():
        setattr(t, att, getattr(A, att))
    return t(order=order)
Пример #6
0
 # Create 4 ocean mask
 basinmask4 = basinmask[0,] ; # Trim off top layer
 # Try sftbyregion
 #mask = cdu.generateLandSeaMask(basinmask3)
 #sftb = cdu.sftbyrgn.generateSurfaceTypeByRegionMask(mask)
 # Southern Ocean
 # Case Atlantic
 lonmat = np.ma.zeros([len(latitude),len(longitude)],dtype='int16')
 if gridId == '1deg':
     lonlims = [-70.5,20.5]
 elif gridId == '0p25deg':
     lonlims = [-70.625,20.375]
 loninds = [np.where(longitude==np.float32(lonlims[0])),np.where(longitude==np.float32(lonlims[1]))]
 loninds = [loninds[0][0][0],loninds[1][0][0]]
 lonmat[:,loninds[0]:loninds[1]] = 1
 basinmask3 = mv.where(mv.logical_and(basinmask3==10,lonmat),1,basinmask3) ; # Case Atlantic
 basinmask4 = mv.where(mv.logical_and(basinmask4==10,lonmat),1,basinmask4) ; # Case Atlantic
 # Case Indian
 lonmat = np.ma.zeros([len(latitude),len(longitude)],dtype='int16')
 if gridId == '1deg':
     lonlims = [20.5,147.5]
 elif gridId == '0p25deg':
     lonlims = [20.375,147.625]
 loninds = [np.where(longitude==np.float32(lonlims[0])),np.where(longitude==np.float32(lonlims[1]))]
 loninds = [loninds[0][0][0],loninds[1][0][0]]
 lonmat[:,loninds[0]:loninds[1]] = 1
 basinmask3 = mv.where(mv.logical_and(basinmask3==10,lonmat),3,basinmask3) ; # Case Indian
 basinmask4 = mv.where(mv.logical_and(basinmask4==10,lonmat),3,basinmask4) ; # Case Indian
 # Case Pacific
 lonmat = np.ma.zeros([len(latitude),len(longitude)],dtype='int16')
 if gridId == '1deg':
Пример #7
0
def generateSurfaceTypeByRegionMask(mask,
                                    sftbyrgn=None,
                                    sftbyrgnmask=215,
                                    regions=range(201, 223),
                                    maximum_regions_per_cell=4,
                                    extend_up_to=3,
                                    verbose=True):
    """ Maps a "types" dataset onto a landsea mask
    Usage:
    mapped,found = generateSurfaceTypeByRegionMask(mask,sftbyrgn,sftbyrgnmask=None,regions=None,maximum_regions_per_cell=4,extend_up_to=3,verbode=True)
    Input:
    mask : land/sea mask (100/0) onto you wish to map our grid (will generate a ld/sea mask for you)
    sftbyrgn: mask you wish to map
              if None then uses our own "sftbyrgn" dataset (old ezget type)
    sftbyrgnmask: land/sea mask for sftbyrgn
                  or a number specifying limit in values of sftbygrn
                  which indicate the threshold land/sea (greater values are land)
    regions: Numbers from sftbyrgn array that you want to map onto mask
    maximum_regions_per_cell: maximum number f regions concidered in a cell
    extend_up_to : how many grid cells away around a cell can we extent to identify a guess
    verbose: prints to the screen what's going on (default is True)

    Output:
     mapped : mapped input mask
     found  : ???
    """
    ## OK first determine which regions are available
    ## Must be integer values
    if isinstance(mask, cdms2.grid.TransientRectGrid):
        mask = cdutil.generateLandSeaMask(mask) * 100.

    if sftbyrgn is None:
        sftbyrgn = cdms2.open(
            os.path.join(sys.prefix, 'sample_data', 'sftbyrgn.nc'))('sftbyrgn')

    if regions is None:
        if verbose: print 'Preparing regions'
        ##         regions = range(201,223)

        regions = []
        for i in range(0, 10000):
            genutil.statusbar(i, 9999)
            c = float(MV2.sum(MV2.ravel(MV2.equal(sftbyrgn, i)), 0))
            if c != 0: regions.append(i)

    if verbose: print 'Regions:', regions
    ## If no mask passed fr sftbyrgn, assumes everything greater 5000 is land)
    if isinstance(sftbyrgnmask, int):
        split = sftbyrgnmask
        n = MV2.maximum(mask)
        sftbyrgnmask = MV2.greater_equal(sftbyrgn, sftbyrgnmask) * n
    else:
        split = MV2.maximum(sftbyrgnmask) / 2.
    ## Now guess the type for each regions
    keys = {}
    ## ## Nice way to do it
    ##     for r in regions:
    ##         c=MV2.not_equal(sftbyrgn,r)
    ##         c=MV2.masked_where(c,sftbyrgnmask)
    ##         n=MV2.count(c)
    ##         c=float(MV2.sum(MV2.ravel(c),0)/n)
    ##         print r,c,n
    ##         keys[r]=c
    ## Fast but not so "general" way to do it
    for r in regions:
        if r < split:
            keys[r] = 0.
        else:
            keys[r] = 100.
    sh = list(mask.shape)
    sh.insert(0, maximum_regions_per_cell)
    potential = MV2.ones(sh, dtype='d') * -999
    potential_reg = MV2.ones(sh, dtype='d') * -999

    g1 = sftbyrgn.getGrid()
    g2 = mask.getGrid()
    r1 = regrid2.Regridder(g1, g2)
    w = cdutil.area_weights(sftbyrgn)

    if verbose: print 'First pass'
    itmp = 0.
    for ireg in keys.keys():
        genutil.statusbar(itmp, len(keys.keys()) - 1)
        itmp += 1.
        c = MV2.equal(sftbyrgn, ireg)
        w2 = 1. - c * w
        s2, w3 = r1(sftbyrgn, mask=w2.filled(), returnTuple=1)
        c2 = MV2.equal(mask, keys[ireg])
        loop(potential, potential_reg, c2, w3, ireg)

    found = MV2.zeros(sh[1:], typecode='f')
    for i in range(maximum_regions_per_cell):
        found = found + MV2.not_equal(potential[i], -999)
    sh2 = list(sh)
    for k in range(extend_up_to):
        sh2[1] = sh[1] + 2 * (k + 1)
        sh2[2] = sh[2] + 2 * (k + 1)
        ## Form the possible i/j couples !
        s = MV2.sum(MV2.ravel(MV2.equal(potential[0], -999)), 0)
        if verbose:
            print 'Expanding up to', k + 1, 'cells while trying to fix', s, 'cells'
        ##         if dump:
        ##             f=cdms2.open('tmp_'+str(k)+'.nc','w')
        ##             f.write(sumregions(potential_reg,potential).astype('f'),id='sftbyrgn',axes=mask.getAxisList())
        ##             f.close()
        ##         g=sumregions(potential_reg,potential).astype('d')
        ##         g=MV2.masked_equal(g,-999)
        ##         g=MV2.greater(g,4999)*100.
        ##         g=MV2.absolute(mask-g)
        ##         g=MV2.masked_equal(g,0.)
        ##         print 'Number of differences:',MV2.count(g)

        if float(s) != 0:
            c0 = MV2.equal(potential[0], -999)
            couples = []
            sft2 = MV2.zeros(sh2[1:], dtype='d') - 888.
            sft2[k + 1:-k - 1, k + 1:-k - 1] = mask
            for i in range(-k - 1, k + 2):
                for j in range(-k - 1, k + 2):
                    if abs(i) > k or abs(j) > k: couples.append([i, j])
            ntot = len(keys.keys()) * len(couples) - 1
            itmp = 0
            for ireg in keys.keys():
                c = MV2.equal(sftbyrgn, ireg)
                w2 = 1. - c * w
                s2, w3 = r1(sftbyrgn, mask=w2.filled(), returnTuple=1)
                w4 = MV2.zeros(sh2[1:], typecode='d')
                w4[k + 1:-k - 1, k + 1:-k - 1] = w3
                for i, j in couples:
                    if verbose: genutil.statusbar(itmp, ntot)
                    itmp += 1.
                    c2 = MV2.equal(
                        sft2[j + k + 1:j + k + 1 + sh[1],
                             i + k + 1:i + k + 1 + sh[2]], keys[ireg])
                    c3 = MV2.equal(
                        sft2[j + k + 1:j + k + 1 + sh[1],
                             i + k + 1:i + k + 1 + sh[2]], mask)
                    c2 = MV2.logical_and(c2, c3)
                    c2 = MV2.logical_and(c2, c0)
                    loop(
                        potential, potential_reg, c2,
                        w4[j + k + 1:j + k + 1 + sh[1],
                           i + k + 1:i + k + 1 + sh[2]], ireg)

        found = MV2.where(MV2.equal(potential[0], -999), found - 1, found)

    out = sumregions(potential_reg, potential)
    out.setAxisList(mask.getAxisList())
    found.setAxisList(mask.getAxisList())
    found = found.astype('i')
    found.missing_value = -999
    found.id = 'found'
    out.id = 'sftbyrgn'
    out = out.astype('i')
    out.missing_value = -999
    del (out.name)
    del (found.name)
    return out, found
Пример #8
0
  -10.4827395   -9.93859485  -7.3394366   -5.39241468  -5.74825567
     -6.74967902  -7.09622319  -5.93836983  -4.04592997  -2.65591499
        -1.68180032  -0.86935245  -0.40114047  -0.54273785  -1.36178957
           -2.67488251  -3.87524401  -4.84708491  -5.49186142  -5.28618944
              -4.30557389  -2.89804038  -1.53825408  -1.84771029  -2.74948361
                 -2.23517037  -1.73306118  -0.71200646   0.76416785   1.51511193
                    -0.04018418  -1.54564706  -1.88664877  -0.43751604   0.89988184
                        0.33437949  -1.70341844  -3.79880014  -4.03570169  -4.7740073
                           -5.04626101  -3.77609961  -3.18667176  -2.21038272  -1.3666902
                              -0.54267951  -0.16472441  -0.52871418  -0.83520848  -0.90315403
                                 -0.21747426   0.01922666   0.89621996   1.75691927   3.12657503
                                     4.55749531   6.04921304   7.20744489   7.65294958""".split()
data = numpy.array(data,dtype=numpy.float)
data = MV2.array(data)

data=MV2.masked_where(MV2.logical_and(data>-4,data<-2),data)

#yx.datawc_x1 = 0
#yx.datawc_x2 = 80
##yx.datawc_y1 =-12 
#yx.datawc_y2 = 12 


x.plot(data,yx,bg=1)
fnm = "test_vcs_1d_missing.png"
x.png(fnm)

print "fnm:",fnm
print "src:",src
ret = checkimage.check_result_image(fnm,src,checkimage.defaultThreshold)
sys.exit(ret)
Пример #9
0
def harmonic(data, k=3):
    
    data = data.reorder('t...')
    cdutil.setAxisTimeBoundsDaily(data.getTime())
    axislist = data.getAxisList()
    dataid = data.id 
    
    daily = True 
    monthly = False
    
    timeAxis = axislist[0]
    N = 365. #len(timeAxis)
#    P = 10. # 10 year, yearly harmonic oscilation
#    P = 10*12 # 10 year, monthly harmonic oscilation
#    P = 10*365 # 10 year, daily harmonic oscilation 
#    if P > N:
#        raise ValueError("P('%d') value should not exceed N(%d)" % (P,N))
        
    if k > N/2:
        raise ValueError("k value should not exceed (%d) i.e. N/2 value" % (N/2))
    
    if len(timeAxis) > 366:
        print 'found more than 1 year data.'
#        y_t = dailyClimatology(data, action='sum')
    else:
        y_t = data 
    # end of if len(timeAxis) > 366:
    
    Y_0 = cdutil.averager(data, axis='t', action='average', weights='equal')

    # make memory free
    del data 
        
    t = numpy.arange(1, N+1, dtype='float')
    
    otheraxis = list(Y_0.shape)
    ax_product = 1
    for ax in otheraxis:
        ax_product *= ax
    otheraxis.insert(0,N)
    t = t.repeat(ax_product).reshape(otheraxis)    
    angle = 2 * math.pi * t/N
    Y_k = 0.
    
    for i in range(1,k+1):
    
        kangle = angle*i
       
        A_k = (2./N) * cdutil.averager(y_t * numpy.cos(kangle), axis='t', action='sum')
        B_k = (2./N) * cdutil.averager(y_t * numpy.sin(kangle), axis='t', action='sum')   
        C_k = MV2.sqrt((A_k*A_k) + (B_k*B_k))
        
        # if A_k is positiv, then retain this phase_angle as it is.
        # phase_angle should be in degrees
        phase_angle = phase_arc_angle = MV2.arctan(B_k/A_k) 
        
        # if A_k is zero, then replace phase_angle with pi/2 else retain same
        phase_angle = MV2.where(MV2.equal(A_k, 0.), math.pi/2.0, phase_arc_angle)
               
        # if A_k is negative, then add pi with phase_angle (if it is <= pi ) 
        condition1 = MV2.logical_and(MV2.less(A_k, 0.), MV2.less_equal(phase_arc_angle, math.pi))
        phase_angle = MV2.where(condition1, phase_arc_angle+math.pi, phase_arc_angle)
        # if A_k is negative, then subtract pi from phase_angle (if it is > pi ) 
        condition2 = MV2.logical_and(MV2.less(A_k, 0.), MV2.greater(phase_arc_angle, math.pi)) 
        condition3 = MV2.logical_or(condition1, condition2)
        phase_angle = MV2.where(condition3, phase_arc_angle-math.pi, phase_arc_angle)
    
        # make memory free 
        del phase_arc_angle
        
        if daily and not monthly:
            # subtract 15 days lag to adjust phase_angle w.r.t daily
            print "Daily Subtraction"
            phase_angle -= (15.*2*math.pi)/N
        # end of if daily and not monthly:

        phase_angle = numpy.array(phase_angle)
#        phase_angle = numpy.tile(phase_angle, N).reshape(kangle.shape)         
        kangle = numpy.array(kangle)
        Y_k += C_k * MV2.cos(kangle - phase_angle)
    # end of for i in range(1,k+1):
    
    # add mean to the sum of first k-th harmonic of data 
    Y_k += Y_0
    
    # make memory free
    del y_t, Y_0
    
    sumOfMean_and_first_k_harmonic = cdms2.createVariable(Y_k, id=dataid)
    sumOfMean_and_first_k_harmonic.setAxisList(axislist)
    sumOfMean_and_first_k_harmonic.comments = 'sumOfMean_and_first_%d_harmonic' % k
    
    # make memory free
    del Y_k
    
    # return result
    return sumOfMean_and_first_k_harmonic
Пример #10
0
def generateSurfaceTypeByRegionMask(mask,sftbyrgn=None,sftbyrgnmask=215,regions=range(201,223),maximum_regions_per_cell=4,extend_up_to=3,verbose=True):
    """
    Maps a "regions" dataset onto a user provided land/sea mask or grid
    
    Usage:
    -----
    mapped,found = generateSurfaceTypeByRegionMask(mask,sftbyrgn=None,sftbyrgnmask=None,regions=None,maximum_regions_per_cell=4,extend_up_to=3,verbose=True)

    Input:
    -----
    mask                        User provided land/sea mask (100/0) or grid (the land/sea mask will be generated automagically) which will be mapped using the "sftbyrgn" internal dataset (will generate a land/sea mask for you)
    sftbyrgn                    Mask you wish to map onto your grid (if None uses internal "sftbyrgn" dataset (old ezget type))
    sftbyrgnmask                Land/sea mask for sftbyrgn (or a number specifying value limits for sftbyrgn which indicates land/sea threshold (greater values are land) - see URL below for integer region map)
    regions                     Numbers from sftbyrgn array that you want to map onto mask (integers from 201-222)
    maximum_regions_per_cell    Maximum number of regions considered for a single cell
    extend_up_to                How many grid cells around a cell can we extend to identify a guess
    verbose                     Prints to the screen what's going on (default is True)

    Output:
    -----
    mapped                      Mapped input grid/mask using provided (or default) regions - sftbyrgn -> user provided grid/mask
    found                       Matrix containing number of regions matched for each output cell
    
    Notes:
    -----
    - More detailed information, including a region map and tabulated region numbers are available from http://www-pcmdi.llnl.gov/publications/pdf/34.pdf
    """
    
    cdat_info.pingPCMDIdb("cdat","cdutil.generateSurfaceTypeByRegionMask")
    ## OK first determine which regions are available
    ## Must be integer values
    if isinstance(mask,cdms2.grid.TransientRectGrid):
        mask = cdutil.generateLandSeaMask(mask)*100.

    if sftbyrgn is None:
        sftbyrgn = cdms2.open(os.path.join(cdat_info.get_prefix(),'share','cdutil','sftbyrgn.nc'))('sftbyrgn')
        
    if regions is None:
        if verbose: print 'Preparing regions'
        #regions = range(201,223)

        regions = []
        for i in range(0,10000):
            genutil.statusbar(i,9999)
            c = float(MV2.sum(MV2.ravel(MV2.equal(sftbyrgn,i)),0))
            if c != 0: regions.append(i)

    if verbose: print 'Regions:',regions
    ## If no mask passed fr sftbyrgn, assumes everything greater 5000 is land)
    if isinstance(sftbyrgnmask,int):
        split           = sftbyrgnmask
        n               = MV2.maximum(mask)
        sftbyrgnmask    = MV2.greater_equal(sftbyrgn,sftbyrgnmask)*n
    else:
        split           = MV2.maximum(sftbyrgnmask)/2.
    ## Now guess the type for each regions
    keys = {}
    ## ## Nice way to do it
    ##     for r in regions:
    ##         c=MV2.not_equal(sftbyrgn,r)
    ##         c=MV2.masked_where(c,sftbyrgnmask)
    ##         n=MV2.count(c)
    ##         c=float(MV2.sum(MV2.ravel(c),0)/n)
    ##         print r,c,n
    ##         keys[r]=c
    ## Fast but not so "general" way to do it
    for r in regions:
        if r< split:
            keys[r] = 0.
        else:
            keys[r] = 100.
    sh              = list(mask.shape)
    sh.insert(0,maximum_regions_per_cell)
    potential       = MV2.ones(sh,dtype='d')*-999
    potential_reg   = MV2.ones(sh,dtype='d')*-999

    g1  = sftbyrgn.getGrid()
    g2  = mask.getGrid()
    r1  = regrid2.Horizontal(g1,g2)
    w   = cdutil.area_weights(sftbyrgn)

    if verbose: print 'First pass'
    itmp = 0.
    for ireg in keys.keys():
        genutil.statusbar(itmp,len(keys.keys())-1)
        itmp += 1.
        c       = MV2.equal(sftbyrgn,ireg)
        w2      = 1.-c*w
        s2,w3   = r1(sftbyrgn,mask=w2.filled(),returnTuple=1)
        c2      = MV2.equal(mask,keys[ireg])
        loop(potential,potential_reg,c2,w3,ireg)

    found = MV2.zeros(sh[1:],typecode='f')
    for i in range(maximum_regions_per_cell):
        found = found+MV2.not_equal(potential[i],-999)
    sh2 = list(sh)
    for k in range(extend_up_to):
        sh2[1] = sh[1]+2*(k+1)
        sh2[2] = sh[2]+2*(k+1)
        ## Form the possible i/j couples !
        s = MV2.sum(MV2.ravel(MV2.equal(potential[0],-999)),0)
        if verbose: print 'Expanding up to',k+1,'cells while trying to fix',s,'cells'
            #if dump:
                #f=cdms2.open('tmp_'+str(k)+'.nc','w')
                #f.write(sumregions(potential_reg,potential).astype('f'),id='sftbyrgn',axes=mask.getAxisList())
                #f.close()
                #g=sumregions(potential_reg,potential).astype('d')
                #g=MV2.masked_equal(g,-999)
                #g=MV2.greater(g,4999)*100.
                #g=MV2.absolute(mask-g)
                #g=MV2.masked_equal(g,0.)
                #print 'Number of differences:',MV2.count(g)

        if float(s) != 0:
            c0 = MV2.equal(potential[0],-999)
            couples = []
            sft2 = MV2.zeros(sh2[1:],dtype='d')-888.
            sft2[k+1:-k-1,k+1:-k-1] = mask
            for i in range(-k-1,k+2):
                for j in range(-k-1,k+2):
                    if abs(i)>k or abs(j)>k: couples.append([i,j])
            ntot = len(keys.keys())*len(couples)-1
            itmp = 0
            for ireg in keys.keys():
                c = MV2.equal(sftbyrgn,ireg)
                w2 = 1.-c*w
                s2,w3 = r1(sftbyrgn,mask=w2.filled(),returnTuple=1)
                w4 = MV2.zeros(sh2[1:],typecode='d')
                w4[k+1:-k-1,k+1:-k-1] = w3
                for i,j in couples:
                    if verbose: genutil.statusbar(itmp,ntot)
                    itmp += 1.
                    c2 = MV2.equal(sft2[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],keys[ireg])
                    c3 = MV2.equal(sft2[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],mask)
                    c2 = MV2.logical_and(c2,c3)
                    c2 = MV2.logical_and(c2,c0)
                    loop(potential,potential_reg,c2,w4[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],ireg)
           
        found = MV2.where(MV2.equal(potential[0],-999),found-1,found)

    out = sumregions(potential_reg,potential)
    out.setAxisList(mask.getAxisList())
    out.id = 'sftbyrgn'
    out = out.astype('i')
    out.missing_value = -999
    found.setAxisList(mask.getAxisList())
    found.id = 'found'
    found = found.astype('i')
    found.missing_value = -999

    del(out.name)
    del(found.name)
    return out,found
Пример #11
0
 #mask = cdu.generateLandSeaMask(basinmask3)
 #sftb = cdu.sftbyrgn.generateSurfaceTypeByRegionMask(mask)
 # Southern Ocean
 # Case Atlantic
 lonmat = np.ma.zeros([len(latitude), len(longitude)], dtype='int16')
 if gridId == '1deg':
     lonlims = [-70.5, 20.5]
 elif gridId == '0p25deg':
     lonlims = [-70.625, 20.375]
 loninds = [
     np.where(longitude == np.float32(lonlims[0])),
     np.where(longitude == np.float32(lonlims[1]))
 ]
 loninds = [loninds[0][0][0], loninds[1][0][0]]
 lonmat[:, loninds[0]:loninds[1]] = 1
 basinmask3 = mv.where(mv.logical_and(basinmask3 == 10, lonmat), 1,
                       basinmask3)
 # Case Atlantic
 basinmask4 = mv.where(mv.logical_and(basinmask4 == 10, lonmat), 1,
                       basinmask4)
 # Case Atlantic
 # Case Indian
 lonmat = np.ma.zeros([len(latitude), len(longitude)], dtype='int16')
 if gridId == '1deg':
     lonlims = [20.5, 147.5]
 elif gridId == '0p25deg':
     lonlims = [20.375, 147.625]
 loninds = [
     np.where(longitude == np.float32(lonlims[0])),
     np.where(longitude == np.float32(lonlims[1]))
 ]
Пример #12
0
def getAreaOfAllClosedDomains(data, condition, **kwarg):

    """
    Input : cdms data with proper lat, lon axis.

    condition : it must be MV2 or numpy.ma masked condition.
        eg1 : condition = MV2.masked_equal(data, 0)

        Using this condition, user can seperate out or distinguish between
        needed domains and unwanted domains.

       eg2:
            >>> condition1 = MV2.masked_less(data, 3)
            >>> condition2 = MV2.masked_greater(data, 5)
            >>> condition3 = MV2.logical_and(condition1, condition2)
            >>> outdict = getAllBoundaryOfClosedAreas(data, condition3)

         The above example2 makes clear that we are masking less than 3 and
         greater than 5 values. So accoring to our `condition3`, we are
         masking out of the range (< 3 && > 5). From this condition3 masked
         data, this function calls `getAllBoundaryOfClosedAreas()` to get
         all closed regions boundary latitudes, longitudes, its no of pixels
         and its weighted area in m^2.

    Kwarg :
        update_mask : Takes boolean True | False (by default)
                      If it is True, then the data's mask will be
                      overwrite with updated mask array out side regions other
                      than closed boundaries pixels or (lats, lons).


    Return : It returns dictionary whose keys are 'region%d' % area_number
             starting from 1 to N (available irregular closed regions)

             Each key ['regionN'] contains another dictionary which contains
             following keys & values

             'area'     -> lat, lon weighted area value in m^2 of that
                           particular closed domain/region

             'unit'     -> area unit is m^2

             'bpixels'  -> list of tuples contain (i, j) or (x, y) or
                           (row, col) of boundary pixels of closed domain

             'blatlons' -> list of tuples contain actual (lat, lon) of
                           boundary pixels of closed domain [i.e equivalent
                           (lats, lons) to `bpixels` (rows, cols) ]

             'cpixels'  -> contains dictionary whose keys are 'row' & 'col'.
                         'row' has (min boundary row, max boundary row) tuple,
                         'col' has (min boundary col, max boundary col) tuple
                          of corner pixels of closed irregular domain/region.
                          # Using this user can extract regular rectangle
                          # shaped data by slicing input data.

             'clatlons' -> contains dictionary whose keys are 'lat' & 'lon'.
                         'lat' has (min boundary lat, max boundary lat) tuple,
                         'lon' has (min boundary lon, max boundary lon) tuple
                          of corner pixels of closed irregular domain/region.
                          [i.e. equivalent to 'cpixels' (row, col)]
                          # Using this user can extract regular rectangle
                          # shaped data by passing argument to input cdms var
                          # data(latitude=lat, longitude=lon).

             'region'   -> cdms selector variable (At this moment no use !)

             'totalPixelsCount' -> total no of pixels in that particular
                            closed domain/region


    eg:

    Input :
    *******

    data =
   ([[ 0.  0.  0.  0.  0.  0.  0.]
     [ 0.  0.  0.  3.  0.  0.  0.]
     [ 0.  0.  0.  3.  0.  0.  0.]
     [ 0.  0.  3.  2.  3.  0.  0.]
     [ 0.  4.  2.  1.  1.  2.  0.]
     [ 0.  1.  4.  3.  5.  4.  0.]
     [ 0.  2.  2.  1.  3.  5.  0.]
     [ 0.  0.  3.  2.  3.  0.  0.]
     [ 0.  0.  3.  0.  1.  0.  0.]
     [ 0.  0.  3.  0.  1.  0.  0.]
     [ 0.  0.  0.  0.  0.  0.  0.]],

     mask = False,
     fill_value = 1e+20)

 >>> condition = MV2.masked_equal(data, 0)
 >>> outdict = getAllBoundaryOfClosedAreas(data, condition, update_mask=True)

    Outputs :
    *********

    data =
([[--    --    --    --    --    --    --]
  [--    --    --   3.0    --    --    --]
  [--    --    --   3.0    --    --    --]
  [--    --   3.0   2.0   3.0    --    --]
  [--   4.0   2.0   1.0   1.0   2.0    --]
  [--   1.0   4.0   3.0   5.0   4.0    --]
  [--   2.0   2.0   1.0   3.0   5.0    --]
  [--    --   3.0   2.0   3.0    --    --]
  [--    --   3.0    --   1.0    --    --]
  [--    --   3.0    --   1.0    --    --]
  [--    --    --    --    --    --    --]],

     mask =
[[ True  True  True  True  True  True  True]
 [ True  True  True False  True  True  True]
 [ True  True  True False  True  True  True]
 [ True  True False False False  True  True]
 [ True False False False False False  True]
 [ True False False False False False  True]
 [ True False False False False False  True]
 [ True  True False False False  True  True]
 [ True  True False  True False  True  True]
 [ True  True False  True False  True  True]
 [ True  True  True  True  True  True  True]],

     fill_value = 1e+20)

    # keys contains no of independent closed boundary pixels count
    >>> outdict.keys()
    ['region1', 'region2', 'region3', 'region4']
    [40, 27, 270, 54]

    # eg : region2
    >>> outdict['region2'].keys()
    ['area', 'region', 'bpixels', 'blatlons',
    'cpixels', 'clatlons', 'totalPixelsCount', 'unit']

    # total no of valid pixels within the irregular closed domain
    >>> outdict['region2']['totalPixelsCount']
    27

    # weighted area of particular closed boundary region (here 27 pixels)
    >>> outdict['region2']['area']
    902159.07029304397

    # area unit
    >>> outdict['region2']['unit']
    'm^2'

    # boundary lat, lon of particular closed boundary region
    >>> outdict['region2']['blatlons']
    [(-87.5, -174.5), (-86.5, -174.5), (-86.5, -173.5), (-85.5, -173.5),
    (-85.5, -172.5), (-84.5, -172.5), (-83.5, -172.5), (-83.5, -173.5),
    (-82.5, -173.5), (-81.5, -173.5), (-80.5, -173.5), (-82.5, -174.5),
    (-82.5, -175.5), (-81.5, -175.5), (-80.5, -175.5), (-83.5, -175.5),
    (-83.5, -176.5), (-84.5, -176.5), (-85.5, -176.5), (-85.5, -175.5),
    (-86.5, -175.5), (-88.5, -174.5)]

    # boundary row, col of particular closed boundary region
    >>> outdict['region2']['bpixels']
    [(2, 5), (3, 5), (3, 6), (4, 6), (4, 7), (5, 7), (6, 7), (6, 6), (7, 6),
    (8, 6), (9, 6), (7, 5), (7, 4), (8, 4), (9, 4), (6, 4), (6, 3), (5, 3),
    (4, 3), (4, 4), (3, 4), (1, 5)]

    # corner lat, lon of above closed irregular region
    >>> dic['region2']['clatlons']
    {'lat': (-88.5, -80.5), 'lon': (-176.5, -172.5)}

    # corner row, col of above closed irregular region
    >>> dic['region2']['cpixels']
    {'col': (3, 7), 'row': (1, 9)}


    # eg : region4
    # total no of valid pixels within the irregular closed domain
    >>> outdict['region4']['totalPixelsCount']
    54

    # area of 54 pixels
    >>> outdict['region4']['area']
    843696.5895938098

    >>> outdict['region4']['blatlons']
    [(-89.5, -58.5), (-89.5, -57.5), (-89.5, -56.5), (-89.5, -55.5),
    (-89.5, -54.5), (-89.5, -53.5), (-89.5, -52.5), (-89.5, -51.5),
    (-88.5, -51.5), (-87.5, -51.5), (-86.5, -51.5), (-85.5, -51.5),
    (-84.5, -51.5), (-84.5, -52.5), (-84.5, -53.5), (-84.5, -54.5),
    (-84.5, -55.5), (-84.5, -56.5), (-84.5, -57.5), (-84.5, -58.5),
    (-84.5, -59.5), (-85.5, -59.5), (-86.5, -59.5), (-87.5, -59.5),
    (-88.5, -59.5), (-89.5, -59.5)]

    # By comparing above Area of 'region2' (27 pixels) is greater than
    # Area of 'region4' (54 pixels) since its weighted area.
    # i.e. it is totally depends on the lat, lon positions

    Note : outdict 'blatlons' contains only outer boundary lat,lons only.
           But area will be calculated w.r.t no of pixels inside the
           closed boundary region and over on the boundary of region.

    Author : Arulalan.T <*****@*****.**>

    Date : 08.07.2014

    """

    update_mask = kwarg.get('update_mask', False)
    # update condition arg to kwarg dictionary
    kwarg['condition'] = condition

    dshape = data.shape
    # it must start with 1, since we masked out side areas/ regions with 0s.
    dummy = numpy.arange(1, data.size + 1, 1)
    dummy = dummy.reshape(dshape)

    # apply user passed condition and fill with our dummy data whereever mask
    # is false (i.e. actual data) and fill with 0s whereever mask is true
    # (i.e. no data in those pixels)
    dummy = MV2.where(condition, dummy, 0)
    # set missing_value as 0. so that filled() return 0s in masked pixels.
    dummy.missing_value = 0
    # Now dummy contains zeros other than needed areas and
    # inside & boundar of needed areas filled with some nos.
    # Here set missing_value as big no & set original data mask to dummy.
    dummy = cdms2.createVariable(dummy.filled(), id=('dummy'),
                        missing_value=data.fill_value, mask=data.mask)
    dummy.setAxisList(data.getAxisList())

    area_irregular_domains = getAllBoundaryOfClosedAreas(dummy, **kwarg)

    if update_mask:
        # update input data mask with dummy mask (masked other than needed
        # irregular regions) along with user passed condition

        # apply logical_and condition with (not of dummy.mask)
        finalmask = MV2.logical_and(condition, MV2.logical_not(dummy.mask))
        # apply original data whereever both condition and dummy's mask
        # becomes true, apply nan whereever false comes.
        data.mask = MV2.where(finalmask, data, numpy.nan).mask
    # end of if update_mask:

    # return the dictionary of area_irregular_domains
    return area_irregular_domains
Пример #13
0
## masked_not_equal(x, value) 
##   masked_not_equal(x, value) = x masked where x != value

## masked_outside(x, v1, v2) 
##   x with mask of all values of x that are outside [v1,v2]
xmo = MV2.masked_outside(xouter, 120, 160)

## count(a, axis=None) 
##   Count of the non-masked elements in a, or along a certain axis.
xcount = MV2.count(xmo,0)
xcount2 = MV2.count(xmo,1)

## masked_where(condition, x, copy=1) 
##   Return x as an array masked where condition is true. 
##   Also masked where x or condition masked.
xmwhere = MV2.masked_where(MV2.logical_and(MV2.greater(xouter,120),MV2.less(xouter,160)),xouter)

## maximum(a, b=None) 
##   returns maximum element of a single array, or elementwise
maxval = MV2.maximum(xouter)
xmax = MV2.maximum(ud,vd)
xmax = MV2.maximum.reduce(ud)
xmax = MV2.maximum.reduce(vd)
xmax2 = numpy.ma.maximum.reduce(vd.subSlice(),axis=0)
if not MV2.allclose(xmax, xmax2): markError('maximum.reduce')

## minimum(a, b=None) 
##   returns minimum element of a single array, or elementwise
minval = MV2.minimum(xouter)
xmin = MV2.minimum(ud,vd)
xmin = MV2.minimum.reduce(ud)
Пример #14
0
def harmonic(data, k=3, time_type='daily', phase_shift=15):
    """     
    Inputs : 
        data : climatology data 
        k : Integer no to compute K th harmonic. By default it takes 3.
        time_type : daily | monthly | full (time type of input climatology)
                    'daily' -> it returns 365 days harmonic,
                    'monthly' -> it returns 12 month harmonic,
                    'full' -> it retuns harmonic for full length of 
                    input data. 
                    
        phase_shift : Used to subtract 'phase_shift' days lag to adjust
                      phase_angle w.r.t daily or monthly. By default it takes
                      15 days lag to adjust phase_angle w.r.t daily data.
                      User can pass None disable this option.
    
    Returns :
        Returns "sum mean of mean and first K th harmonic" of input 
        climatology data. 
    
    Concept :
    
    Earth science data consists of a strong seasonality component as 
    indicated by the cycles of repeated patterns in climate variables such 
    as air pressure, temperature and precipitation. The seasonality forms 
    the strongest signals in this data and in order to find other patterns,
    the seasonality is removed by subtracting the monthly mean values of the
    raw data for each month. However since the raw data like air temperature,
    pressure, etc. are constantly being generated with the help of satellite
    observations, the climate scientists usually use a moving reference base 
    interval of some years of raw data to calculate the mean in order to 
    generate the anomaly time series and study the changes with respect to
    that. 
    
    Fourier series analysis decomposes a signal into an infinite series of 
    harmonic components. Each of these components is comprised initially of 
    a sine wave and a cosine wave of equal integer frequency. These two waves
    are then combined into a single cosine wave, which has characteristic 
    amplitude (size of the wave) and phase angle (offset of the wave). 
    Convergence has been established for bounded piecewise continuous 
    functions on a closed interval, with special conditions at points of
    discontinuity. Its convergence has been established for other conditions
    as well, but these are not relevant to the analysis at hand.
    
    Reference: Daniel S Wilks, 'Statistical Methods in the Atmospheric 
               Sciences' second Edition, page no(372-378).
               
    Written By : Arulalan.T
    
    Date : 16.05.2014
    
    """
    
    data = data.reorder('t...')
    cdutil.setAxisTimeBoundsDaily(data.getTime())
    axislist = data.getAxisList()
    timeAxis = axislist[0]
    dataid = data.id     
    
    if time_type in ['daily']:
        N = 365.0   # must be float 
    elif time_type[:3] in ['mon']:
        N = 12.0    # must be float 
    elif time_type in ['full']:
        N = float(len(timeAxis))
        
    if k > N/2:
        raise ValueError("k value should not exceed (%d) i.e. N/2 value" % (N/2))
    
    if len(timeAxis) > 366:
        print 'found more than 1 year data.'
        raise ValueError("Kindly pass only climatology data")
    else:
        y_t = data 
    # end of if len(timeAxis) > 366:
    
    Y_0 = cdutil.averager(data, axis='t', action='average', weights='equal')

    # make memory free
    del data 
        
    t = numpy.arange(1, N+1, dtype='float')
    
    otheraxis = list(Y_0.shape)
    ax_product = 1
    for ax in otheraxis:
        ax_product *= ax
    otheraxis.insert(0,N)
    t = t.repeat(ax_product).reshape(otheraxis)    
    angle = 2 * math.pi * t/N
    Y_k = 0.
    
    for i in range(1,k+1):
    
        kangle = angle*i
       
        A_k = (2./N) * cdutil.averager(y_t * numpy.cos(kangle), axis='t', action='sum')
        B_k = (2./N) * cdutil.averager(y_t * numpy.sin(kangle), axis='t', action='sum')   
        C_k = MV2.sqrt((A_k*A_k) + (B_k*B_k))
        
        # if A_k is positiv, then retain this phase_angle as it is.
        # phase_angle should be in degrees
        phase_angle = phase_arc_angle = MV2.arctan(B_k/A_k) 
        
        # if A_k is zero, then replace phase_angle with pi/2 else retain same
        phase_angle = MV2.where(MV2.equal(A_k, 0.), math.pi/2.0, phase_arc_angle)
               
        # if A_k is negative, then add pi with phase_angle (if it is <= pi ) 
        condition1 = MV2.logical_and(MV2.less(A_k, 0.), MV2.less_equal(phase_arc_angle, math.pi))
        phase_angle = MV2.where(condition1, phase_arc_angle+math.pi, phase_arc_angle)
        # if A_k is negative, then subtract pi from phase_angle (if it is > pi ) 
        condition2 = MV2.logical_and(MV2.less(A_k, 0.), MV2.greater(phase_arc_angle, math.pi)) 
        condition3 = MV2.logical_or(condition1, condition2)
        phase_angle = MV2.where(condition3, phase_arc_angle-math.pi, phase_arc_angle)
    
        # make memory free 
        del phase_arc_angle
        
        if phase_shift:
            # subtract 15 days lag to adjust phase_angle w.r.t daily
            phase_angle -= (phase_shift *2 * math.pi) / N
        # end of if daily and not monthly:

        phase_angle = numpy.array(phase_angle)
        kangle = numpy.array(kangle)
        Y_k += C_k * MV2.cos(kangle - phase_angle)
    # end of for i in range(1,k+1):
    
    # add mean to the sum of first k-th harmonic of data 
    Y_k += Y_0
    
    # make memory free
    del y_t, Y_0
    
    sumOfMean_and_first_k_harmonic = cdms2.createVariable(Y_k, id=dataid)
    sumOfMean_and_first_k_harmonic.setAxisList(axislist)
    sumOfMean_and_first_k_harmonic.comments = 'sumOfMean_and_first_%d_harmonic' % k
    
    # make memory free
    del Y_k
    
    # return result
    return sumOfMean_and_first_k_harmonic
Пример #15
0
def linearInterpolation(A,
                        Idx,
                        levels=[
                            100000, 92500, 85000, 70000, 60000, 50000, 40000,
                            30000, 25000, 20000, 15000, 10000, 7000, 5000,
                            3000, 2000, 1000
                        ],
                        status=None,
                        axis='z'):
    """
    Linear interpolation to interpolate a field from some levels to another set of levels
    Values below "surface" are masked.


    :param A: array to interpolate
    :type A:
    :param I: interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level)
            i.e P value going up with each level.
    :type I:
    :param levels: levels to interpolate to (same units as I).
                    Default levels:[100000, 92500, 85000, 70000, 60000, 50000, 40000,
                        30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]
    :type levels:
    :param axis: Axis over which to do the linear interpolation.
                Can provide either an int representing axis index, or the axis name.
                Default: 'z'.
    :type axis: str or int

    .. note::

        I and levels must have same units

    :returns: array on new levels (levels)

    :Examples:

        .. doctest:: vertical_linearInterpolation

            >>> A=interpolate(A,I) # interpolates A over default levels
    """

    try:
        nlev = len(levels)  # Number of pressure levels
    except BaseException:
        nlev = 1  # if only one level len(levels) would breaks
        levels = [
            levels,
        ]
    order = A.getOrder()
    A = A(order='%s...' % axis)
    Idx = Idx(order='%s...' % axis)
    sh = list(Idx.shape)
    nsigma = sh[0]  # number of sigma levels
    sh[0] = nlev
    t = MV2.zeros(sh, typecode=MV2.float32)
    sh2 = Idx[0].shape
    prev = -1
    for ilev in range(nlev):  # loop through pressure levels
        if status is not None:
            prev = genutil.statusbar(ilev, nlev - 1., prev)
        lev = levels[ilev]  # get value for the level
        Iabv = MV2.ones(sh2, MV2.float)
        Aabv = -1 * Iabv  # Array on sigma level Above
        Abel = -1 * Iabv  # Array on sigma level Below
        Ibel = -1 * Iabv  # Pressure on sigma level Below
        Iabv = -1 * Iabv  # Pressure on sigma level Above
        Ieq = MV2.masked_equal(Iabv, -1)  # Area where Pressure == levels
        for i in range(1, nsigma):  # loop from second sigma level to last one
            a = MV2.greater_equal(
                Idx[i], lev)  # Where is the pressure greater than lev
            b = MV2.less_equal(Idx[i - 1],
                               lev)  # Where is the pressure less than lev
            # Now looks if the pressure level is in between the 2 sigma levels
            # If yes, sets Iabv, Ibel and Aabv, Abel
            a = MV2.logical_and(a, b)
            Iabv = MV2.where(a, Idx[i], Iabv)  # Pressure on sigma level Above
            Aabv = MV2.where(a, A[i], Aabv)  # Array on sigma level Above
            Ibel = MV2.where(a, Idx[i - 1],
                             Ibel)  # Pressure on sigma level Below
            Abel = MV2.where(a, A[i - 1], Abel)  # Array on sigma level Below
            Ieq = MV2.where(MV2.equal(Idx[i], lev), A[i], Ieq)

        val = MV2.masked_where(MV2.equal(Ibel, -1.),
                               numpy.ones(Ibel.shape) * lev)
        # set to missing value if no data below lev if
        # there is

        tl = (val - Ibel) / (Iabv - Ibel) * \
            (Aabv - Abel) + Abel  # Interpolation
        if ((Ieq.mask is None) or (Ieq.mask is MV2.nomask)):
            tl = Ieq
        else:
            tl = MV2.where(1 - Ieq.mask, Ieq, tl)
        t[ilev] = tl.astype(MV2.float32)

    ax = A.getAxisList()
    autobnds = cdms2.getAutoBounds()
    cdms2.setAutoBounds('off')
    lvl = cdms2.createAxis(MV2.array(levels).filled())
    cdms2.setAutoBounds(autobnds)
    try:
        lvl.units = Idx.units
    except BaseException:
        pass
    lvl.id = 'plev'

    try:
        t.units = Idx.units
    except BaseException:
        pass

    ax[0] = lvl
    t.setAxisList(ax)
    t.id = A.id
    for att in A.listattributes():
        setattr(t, att, getattr(A, att))
    return t(order=order)
Пример #16
0
def logLinearInterpolation(A,P,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000],status=None):
    """
    Log-linear interpolation
    to convert a field from sigma levels to pressure levels
    Value below surface are masked
    
    Input
    A :    array on sigma levels
    P :    pressure field from TOP (level 0) to BOTTOM (last level)
    levels : pressure levels to interplate to (same units as P), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]

    P and levels must have same units

    Output
    array on pressure levels (levels)
    
    Examples:
    A=logLinearInterpolation(A,P),levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
    """
    
    try:
        nlev=len(levels)  # Number of pressure levels
    except:
        nlev=1  # if only one level len(levels) would breaks
        levels=[levels,]
    order=A.getOrder()
    A=A(order='z...')
    P=P(order='z...')
    sh=list(P.shape)
    nsigma=sh[0] #number of sigma levels
    sh[0]=nlev
    t=MV2.zeros(sh,typecode=MV2.float32)
    sh2=P[0].shape
    prev=-1
    for ilev in range(nlev): # loop through pressure levels
        if status is not None:
            prev=genutil.statusbar(ilev,nlev-1.,prev)
        lev=levels[ilev] # get value for the level
        Pabv=MV2.ones(sh2,MV2.float)
        Aabv=-1*Pabv # Array on sigma level Above
        Abel=-1*Pabv # Array on sigma level Below
        Pbel=-1*Pabv # Pressure on sigma level Below
        Pabv=-1*Pabv # Pressure on sigma level Above
        Peq=MV2.masked_equal(Pabv,-1) # Area where Pressure == levels
        for i in range(1,nsigma): # loop from second sigma level to last one
            a=MV2.greater_equal(P[i],  lev) # Where is the pressure greater than lev
            b=   MV2.less_equal(P[i-1],lev) # Where is the pressure less than lev
            # Now looks if the pressure level is in between the 2 sigma levels
            # If yes, sets Pabv, Pbel and Aabv, Abel
            a=MV2.logical_and(a,b)
            Pabv=MV2.where(a,P[i],Pabv) # Pressure on sigma level Above
            Aabv=MV2.where(a,A[i],Aabv) # Array on sigma level Above
            Pbel=MV2.where(a,P[i-1],Pbel) # Pressure on sigma level Below
            Abel=MV2.where(a,A[i-1],Abel) # Array on sigma level Below
            Peq= MV2.where(MV2.equal(P[i],lev),A[i],Peq)

        val=MV2.masked_where(MV2.equal(Pbel,-1),numpy.ones(Pbel.shape)*lev) # set to missing value if no data below lev if there is
        
        tl=MV2.log(val/Pbel)/MV2.log(Pabv/Pbel)*(Aabv-Abel)+Abel # Interpolation
        if ((Peq.mask is None) or (Peq.mask is MV2.nomask)):
            tl=Peq
        else:
            tl=MV2.where(1-Peq.mask,Peq,tl)
        t[ilev]=tl.astype(MV2.float32)
        
    ax=A.getAxisList()
    autobnds=cdms2.getAutoBounds()
    cdms2.setAutoBounds('off')
    lvl=cdms2.createAxis(MV2.array(levels).filled())
    cdms2.setAutoBounds(autobnds)
    try:
        lvl.units=P.units
    except:
        pass
    lvl.id='plev'
    
    try:
      t.units=P.units
    except:
      pass
  
    ax[0]=lvl
    t.setAxisList(ax)
    t.id=A.id
    for att in A.listattributes():
        setattr(t,att,getattr(A,att))
    return t(order=order)
Пример #17
0
def linearInterpolation(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000], status=None):
    """
    Linear interpolation
    to interpolate a field from some levels to another set of levels
    Value below "surface" are masked
    
    Input
    A :      array to interpolate
    I :      interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level), i.e P value going up with each level
    levels : levels to interplate to (same units as I), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]

    I and levels must have same units

    Output
    array on new levels (levels)
    
    Examples:
    A=interpolate(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
    """
    
    try:
        nlev=len(levels)  # Number of pressure levels
    except:
        nlev=1  # if only one level len(levels) would breaks
        levels=[levels,]
    order=A.getOrder()
    A=A(order='z...')
    I=I(order='z...')
    sh=list(I.shape)
    nsigma=sh[0] #number of sigma levels
    sh[0]=nlev
    t=MV2.zeros(sh,typecode=MV2.float32)
    sh2=I[0].shape
    prev=-1
    for ilev in range(nlev): # loop through pressure levels
        if status is not None:
            prev=genutil.statusbar(ilev,nlev-1.,prev)
        lev=levels[ilev] # get value for the level
        Iabv=MV2.ones(sh2,MV2.float)
        Aabv=-1*Iabv # Array on sigma level Above
        Abel=-1*Iabv # Array on sigma level Below
        Ibel=-1*Iabv # Pressure on sigma level Below
        Iabv=-1*Iabv # Pressure on sigma level Above
        Ieq=MV2.masked_equal(Iabv,-1) # Area where Pressure == levels
        for i in range(1,nsigma): # loop from second sigma level to last one
            a = MV2.greater_equal(I[i],  lev) # Where is the pressure greater than lev
            b =    MV2.less_equal(I[i-1],lev) # Where is the pressure less than lev
            # Now looks if the pressure level is in between the 2 sigma levels
            # If yes, sets Iabv, Ibel and Aabv, Abel
            a=MV2.logical_and(a,b)
            Iabv=MV2.where(a,I[i],Iabv) # Pressure on sigma level Above
            Aabv=MV2.where(a,A[i],Aabv) # Array on sigma level Above
            Ibel=MV2.where(a,I[i-1],Ibel) # Pressure on sigma level Below
            Abel=MV2.where(a,A[i-1],Abel) # Array on sigma level Below
            Ieq= MV2.where(MV2.equal(I[i],lev),A[i],Ieq)

        val=MV2.masked_where(MV2.equal(Ibel,-1.),numpy.ones(Ibel.shape)*lev) # set to missing value if no data below lev if there is
        
        tl=(val-Ibel)/(Iabv-Ibel)*(Aabv-Abel)+Abel # Interpolation
        if ((Ieq.mask is None) or (Ieq.mask is MV22.nomask)):
            tl=Ieq
        else:
            tl=MV2.where(1-Ieq.mask,Ieq,tl)
        t[ilev]=tl.astype(MV2.float32)

    ax=A.getAxisList()
    autobnds=cdms2.getAutoBounds()
    cdms2.setAutoBounds('off')
    lvl=cdms2.createAxis(MV2.array(levels).filled())
    cdms2.setAutoBounds(autobnds)
    try:
        lvl.units=I.units
    except:
        pass
    lvl.id='plev'
    
    try:
      t.units=I.units
    except:
      pass
  
    ax[0]=lvl
    t.setAxisList(ax)
    t.id=A.id
    for att in A.listattributes():
        setattr(t,att,getattr(A,att))
    return t(order=order)
Пример #18
0
def improve(mask,
            navy_frac_t,
            threshold_1,
            threshold_2,
            UL,
            UC,
            UR,
            ML,
            MR,
            LL,
            LC,
            LR,
            regridTool='regrid2'):
    mask_approx = map2four(mask, mask.getGrid(), regridTool=regridTool)
    diff = navy_frac_t - mask_approx
    ## Land point conversion
    c1 = MV2.greater(diff, threshold_1)
    c2 = MV2.greater(navy_frac_t, threshold_2)
    c = MV2.logical_and(c1, c2)
    ##     x.plot(c.astype("i"))
    ##     raw_input()
    ##     x.clear()
    ## Now figures out local maxima
    cUL, cUC, cUR, cML, cMR, cLL, cLC, cLR = create_surrounds(c)
    L = c.getAxis(1)
    bL = L.getBounds()
    if L.isCircular() and bL[-1][1] - bL[0][0] % L.modulo == 0:
        c = c[1:-1]  # elimnitates north and south poles
        tmp = navy_frac_t[1:-1]
    else:
        c = c[1:-1, 1:-1]  # elimnitates north and south poles
        tmp = navy_frac_t[1:-1, 1:-1]
    m = MV2.logical_and(c, MV2.greater(tmp, MV2.where(cUL, UL, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cUC, UC, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cUR, UR, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cML, ML, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cMR, MR, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cLL, LL, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cLC, LC, 0.)))
    m = MV2.logical_and(m, MV2.greater(tmp, MV2.where(cLR, LR, 0.)))
    # Ok now update the mask by setting these points to land
    mask2 = mask * 1.
    if L.isCircular() and bL[-1][1] - bL[0][0] % L.modulo == 0:
        mask2[1:-1] = MV2.where(m, 1, mask[1:-1])
    else:
        mask2[1:-1, 1:-1] = MV2.where(m, 1, mask[1:-1, 1:-1])

    ## ocean point conversion
    c1 = MV2.less(diff, -threshold_1)
    c2 = MV2.less(navy_frac_t, 1. - threshold_2)
    c = MV2.logical_and(c1, c2)
    cUL, cUC, cUR, cML, cMR, cLL, cLC, cLR = create_surrounds(c)
    L = c.getAxis(1)
    bL = L.getBounds()
    if L.isCircular() and bL[-1][1] - bL[0][0] % L.modulo == 0:
        c = c[1:-1]  # elimnitates north and south poles
        tmp = navy_frac_t[1:-1]
    else:
        c = c[1:-1, 1:-1]  # elimnitates north and south poles
        tmp = navy_frac_t[1:-1, 1:-1]
    ## Now figures out local maxima
    m = MV2.logical_and(c, MV2.less(tmp, MV2.where(cUL, UL, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cUC, UC, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cUR, UR, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cML, ML, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cMR, MR, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cLL, LL, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cLC, LC, 1.)))
    m = MV2.logical_and(m, MV2.less(tmp, MV2.where(cLR, LR, 1.)))
    # Ok now update the mask by setting these points to ocean
    if L.isCircular() and bL[-1][1] - bL[0][0] % L.modulo == 0:
        mask2[1:-1] = MV2.where(m, 0, mask2[1:-1])
    else:
        mask2[1:-1, 1:-1] = MV2.where(m, 0, mask2[1:-1, 1:-1])
    mask2.setAxisList(mask.getAxisList())
    return mask2
Пример #19
0

f = cdms2.open('data/snc.nc')
data = f('snc', time=slice(1), squeeze=1)

print "Contions \n 1. Mask less than 100 \n 2. Mask less than 30 and greater than 70"
con = input('Enter Condion Option 1 or 2 : ')

if con == 1:
    mask_condition = MV2.masked_less(data, 100.)
    value = 'value equal to 100'
    dirname = 'outplots_eq_100'
elif con == 2:
    c1 = MV2.masked_greater(data, 70.)
    c2 = MV2.masked_less(data, 30.)
    mask_condition = MV2.logical_and(c1, c2)
    value = 'value equal to within 30 to 70'
    dirname = 'outplots_eq_30_to_70'
# end of if con == 1:

if not os.path.isdir(dirname):  os.mkdir(dirname)
print "Output plots will be saved in '%s' directory" % dirname

v = vcs.init()
# Assign the variable "cf_asd" to the persistent 'ASD' isofill graphics methods.
cf_asd = v.createboxfill()

cf_asd.level_1 = data.min()         # change to default minimum level
cf_asd.level_2 = data.max()         # change to default maximum level

# set missing color as white
Пример #20
0
def improve(mask,navy_frac_t,threshold_1,threshold_2,UL,UC,UR,ML,MR,LL,LC,LR,regridTool='regrid2'):
    mask_approx = map2four(mask,mask.getGrid(),regridTool=regridTool)
    diff =  navy_frac_t - mask_approx
    ## Land point conversion
    c1 = MV2.greater(diff,threshold_1)
    c2 = MV2.greater(navy_frac_t,threshold_2)
    c= MV2.logical_and(c1,c2)
##     x.plot(c.astype("i"))
##     raw_input()
##     x.clear()
    ## Now figures out local maxima
    cUL,cUC,cUR,cML,cMR,cLL,cLC,cLR = create_surrounds(c)
    L=c.getAxis(1)
    bL=L.getBounds()
    if L.isCircular() and bL[-1][1]-bL[0][0] % L.modulo == 0:
        c=c[1:-1] # elimnitates north and south poles
        tmp = navy_frac_t[1:-1]
    else:
        c=c[1:-1,1:-1] # elimnitates north and south poles
        tmp = navy_frac_t[1:-1,1:-1]
    m = MV2.logical_and(c,MV2.greater(tmp,MV2.where(cUL,UL,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cUC,UC,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cUR,UR,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cML,ML,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cMR,MR,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cLL,LL,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cLC,LC,0.)))
    m = MV2.logical_and(m,MV2.greater(tmp,MV2.where(cLR,LR,0.)))
    # Ok now update the mask by setting these points to land
    mask2 = mask*1.
    if L.isCircular() and bL[-1][1]-bL[0][0] % L.modulo == 0:
        mask2[1:-1] = MV2.where(m,1,mask[1:-1])
    else:
        mask2[1:-1,1:-1] = MV2.where(m,1,mask[1:-1,1:-1])

    ## ocean point conversion
    c1 = MV2.less(diff,-threshold_1)
    c2 = MV2.less(navy_frac_t,1.-threshold_2)
    c= MV2.logical_and(c1,c2)
    cUL,cUC,cUR,cML,cMR,cLL,cLC,cLR = create_surrounds(c)
    L=c.getAxis(1)
    bL=L.getBounds()
    if L.isCircular() and bL[-1][1]-bL[0][0] % L.modulo == 0:
        c=c[1:-1] # elimnitates north and south poles
        tmp = navy_frac_t[1:-1]
    else:
        c=c[1:-1,1:-1] # elimnitates north and south poles
        tmp = navy_frac_t[1:-1,1:-1]
    ## Now figures out local maxima
    m = MV2.logical_and(c,MV2.less(tmp,MV2.where(cUL,UL,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cUC,UC,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cUR,UR,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cML,ML,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cMR,MR,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cLL,LL,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cLC,LC,1.)))
    m = MV2.logical_and(m,MV2.less(tmp,MV2.where(cLR,LR,1.)))
    # Ok now update the mask by setting these points to ocean
    if L.isCircular() and bL[-1][1]-bL[0][0] % L.modulo == 0:
        mask2[1:-1] = MV2.where(m,0,mask2[1:-1])
    else:
        mask2[1:-1,1:-1] = MV2.where(m,0,mask2[1:-1,1:-1])
    mask2.setAxisList(mask.getAxisList())
    return mask2
Пример #21
0
##   masked_not_equal(x, value) = x masked where x != value

## masked_outside(x, v1, v2)
##   x with mask of all values of x that are outside [v1,v2]
xmo = MV2.masked_outside(xouter, 120, 160)

## count(a, axis=None)
##   Count of the non-masked elements in a, or along a certain axis.
xcount = MV2.count(xmo, 0)
xcount2 = MV2.count(xmo, 1)

## masked_where(condition, x, copy=1)
##   Return x as an array masked where condition is true.
##   Also masked where x or condition masked.
xmwhere = MV2.masked_where(
    MV2.logical_and(MV2.greater(xouter, 120), MV2.less(xouter, 160)), xouter)

## maximum(a, b=None)
##   returns maximum element of a single array, or elementwise
maxval = MV2.maximum(xouter)
xmax = MV2.maximum(ud, vd)
xmax = MV2.maximum.reduce(ud)
xmax = MV2.maximum.reduce(vd)
xmax2 = numpy.ma.maximum.reduce(vd.subSlice(), axis=0)
if not MV2.allclose(xmax, xmax2): markError('maximum.reduce')

## minimum(a, b=None)
##   returns minimum element of a single array, or elementwise
minval = MV2.minimum(xouter)
xmin = MV2.minimum(ud, vd)
xmin = MV2.minimum.reduce(ud)
Пример #22
0
def generateSurfaceTypeByRegionMask(mask,sftbyrgn=None,sftbyrgnmask=215,regions = range(201,223), maximum_regions_per_cell=4,extend_up_to=3,verbose=True):
    """ Maps a "types" dataset onto a landsea mask
    Usage:
    mapped,found = generateSurfaceTypeByRegionMask(mask,sftbyrgn,sftbyrgnmask=None,regions=None,maximum_regions_per_cell=4,extend_up_to=3,verbode=True)
    Input:
    mask : land/sea mask (100/0) onto you wish to map our grid (will generate a ld/sea mask for you)
    sftbyrgn: mask you wish to map
              if None then uses our own "sftbyrgn" dataset (old ezget type)
    sftbyrgnmask: land/sea mask for sftbyrgn
                  or a number specifying limit in values of sftbygrn
                  which indicate the threshold land/sea (greater values are land)
    regions: Numbers from sftbyrgn array that you want to map onto mask
    maximum_regions_per_cell: maximum number f regions concidered in a cell
    extend_up_to : how many grid cells away around a cell can we extent to identify a guess
    verbose: prints to the screen what's going on (default is True)

    Output:
     mapped : mapped input mask
     found  : ???
    """
    ## OK first determine which regions are available
    ## Must be integer values
    if isinstance(mask, cdms2.grid.TransientRectGrid):
        mask = cdutil.generateLandSeaMask(mask)*100.

    if sftbyrgn is None:
        sftbyrgn = cdms2.open(os.path.join(sys.prefix,'sample_data','sftbyrgn.nc'))('sftbyrgn')
        
    if regions is None:
        if verbose: print 'Preparing regions'
##         regions = range(201,223)

        regions=[]
        for i in range(0,10000):
            genutil.statusbar(i,9999)
            c=float(MV2.sum(MV2.ravel(MV2.equal(sftbyrgn,i)),0))
            if c!=0: regions.append(i)

    if verbose: print 'Regions:',regions
    ## If no mask passed fr sftbyrgn, assumes everything greater 5000 is land)
    if isinstance(sftbyrgnmask,int):
        split = sftbyrgnmask
        n=MV2.maximum(mask)
        sftbyrgnmask=MV2.greater_equal(sftbyrgn,sftbyrgnmask)*n
    else:
        split = MV2.maximum(sftbyrgnmask)/2.
    ## Now guess the type for each regions
    keys={}
## ## Nice way to do it
##     for r in regions:
##         c=MV2.not_equal(sftbyrgn,r)
##         c=MV2.masked_where(c,sftbyrgnmask)
##         n=MV2.count(c)
##         c=float(MV2.sum(MV2.ravel(c),0)/n)
##         print r,c,n
##         keys[r]=c
## Fast but not so "general" way to do it
    for r in regions:
        if r< split:
            keys[r]=0.
        else:
            keys[r]=100.
    sh=list(mask.shape)
    sh.insert(0,maximum_regions_per_cell)
    potential=MV2.ones(sh,dtype='d')*-999
    potential_reg=MV2.ones(sh,dtype='d')*-999

    g1=sftbyrgn.getGrid()
    g2=mask.getGrid()
    r1=regrid2.Regridder(g1,g2)
    w=cdutil.area_weights(sftbyrgn)

    if verbose: print 'First pass'
    itmp=0.
    for ireg in keys.keys():
        genutil.statusbar(itmp,len(keys.keys())-1)
        itmp+=1.
        c=MV2.equal(sftbyrgn,ireg)
        w2=1.-c*w
        s2,w3=r1(sftbyrgn,mask=w2.filled(),returnTuple=1)
        c2=MV2.equal(mask,keys[ireg])
        loop(potential,potential_reg,c2,w3,ireg)

    found=MV2.zeros(sh[1:],typecode='f')
    for i in range(maximum_regions_per_cell):
        found=found+MV2.not_equal(potential[i],-999)
    sh2=list(sh)
    for k in range(extend_up_to):
        sh2[1]=sh[1]+2*(k+1)
        sh2[2]=sh[2]+2*(k+1)
        ## Form the possible i/j couples !
        s=MV2.sum(MV2.ravel(MV2.equal(potential[0],-999)),0)
        if verbose: print 'Expanding up to',k+1,'cells while trying to fix',s,'cells'
##         if dump:
##             f=cdms2.open('tmp_'+str(k)+'.nc','w')
##             f.write(sumregions(potential_reg,potential).astype('f'),id='sftbyrgn',axes=mask.getAxisList())
##             f.close()
##         g=sumregions(potential_reg,potential).astype('d')
##         g=MV2.masked_equal(g,-999)
##         g=MV2.greater(g,4999)*100.
##         g=MV2.absolute(mask-g)
##         g=MV2.masked_equal(g,0.)
##         print 'Number of differences:',MV2.count(g)

        if float(s)!=0:
            c0=MV2.equal(potential[0],-999)
            couples=[]
            sft2=MV2.zeros(sh2[1:],dtype='d')-888.
            sft2[k+1:-k-1,k+1:-k-1]=mask
            for i in range(-k-1,k+2):
                for j in range(-k-1,k+2):
                    if abs(i)>k or abs(j)>k: couples.append([i,j])
            ntot=len(keys.keys())*len(couples)-1
            itmp=0
            for ireg in keys.keys():
                c=MV2.equal(sftbyrgn,ireg)
                w2=1.-c*w
                s2,w3=r1(sftbyrgn,mask=w2.filled(),returnTuple=1)
                w4=MV2.zeros(sh2[1:],typecode='d')
                w4[k+1:-k-1,k+1:-k-1]=w3
                for i,j in couples:
                    if verbose: genutil.statusbar(itmp,ntot)
                    itmp+=1.
                    c2=MV2.equal(sft2[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],keys[ireg])
                    c3=MV2.equal(sft2[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],mask)
                    c2=MV2.logical_and(c2,c3)
                    c2=MV2.logical_and(c2,c0)
                    loop(potential,potential_reg,c2,w4[j+k+1:j+k+1+sh[1],i+k+1:i+k+1+sh[2]],ireg)
           
        found=MV2.where(MV2.equal(potential[0],-999),found-1,found)

    out=sumregions(potential_reg,potential)
    out.setAxisList(mask.getAxisList())
    found.setAxisList(mask.getAxisList())
    found=found.astype('i')
    found.missing_value=-999
    found.id='found'
    out.id='sftbyrgn'
    out=out.astype('i')
    out.missing_value=-999
    del(out.name)
    del(found.name)
    return out,found