Esempio n. 1
0
def _interim2cesm_fv(year, month, day, hour, ntimes, state_xmlfile_dir,
                     state_xmlfile_name, hybrid_file, topo_file, file_tag):
    #--------------------------------------------------------------------------
    """
    See file header.
    """

    # Base time is set from first time slice selected.
    #-------------------------------------------------
    cbaset = cdtime.comptime(year, month, day, hour)
    cendt = cbaset.add(((ntimes - 1) * DELTAT), cdtime.Hours)

    ddi = di.dataInterim(state_xmlfile_dir=state_xmlfile_dir,
                         state_xmlfile_name=state_xmlfile_name)

    lats, lons, model_grid, phisfcm_in, tfin = \
        _get_topo_vars(topo_file)

    plat = len(lats)
    plon = len(lons)

    gwts, hfin, model_grid_us, model_grid_vs, ntrk, ntrm, ntrn, slats, slons, \
    w_stagwts = \
        _get_hybrid_vars(hybrid_file)

    pslat = len(slats)
    pslon = len(slons)

    hybridv_file = hybrid_file

    ilevs, levs, hyai, hyam, hybi, hybm, p0 = \
        _get_hybridv_vars(hybridv_file)

    date, datesec, fout, lev, phis, ps, psus, psvs, q, t, time, u, us, v, \
    vs = \
        _setup_outfile(cbaset, cendt, file_tag, gwts, hyai, hyam, hybi, hybm, \
                       ilevs, lats, levs, lons, ntrk, ntrm, ntrn, p0, slats, \
                       slons, w_stagwts)

    # Now access Interim data to obtain grid/level parameters of the analysis.
    #-------------------------------------------------------------------------
    ta = ddi.get_state_data('T', cbaset)
    print 'ta shape: ', ta.shape

    gdas_grid = ddi.grid

    # Model levels.
    #--------------
    plevm = len(lev)

    # Analysis levels.
    #-----------------
    plevr = ta.shape[0]
    plevrp1 = plevr + 1

    # Set up regridder functions for all needed tranformations.
    #----------------------------------------------------------
    rgfa2m = regrid2.Regridder(gdas_grid, model_grid)

    rgfa2mus = regrid2.Regridder(gdas_grid, model_grid_us)
    rgfa2mvs = regrid2.Regridder(gdas_grid, model_grid_vs)

    rgfm2us = regrid2.Regridder(model_grid, model_grid_us)
    rgfm2vs = regrid2.Regridder(model_grid, model_grid_vs)

    rgfus2m = regrid2.Regridder(model_grid_us, model_grid)
    rgfvs2m = regrid2.Regridder(model_grid_vs, model_grid)

    phisfcm_in = phisfcm_in.filled()
    phisfcm_in = n.squeeze(phisfcm_in)

    phisfcr_in = _get_phisfcr_in(ddi, rgfa2m)
    phisfcr_in = ff.filter_field(phisfcr_in.filled(), FIL_TYPE, FIL_IDX)

    # Time loop.
    #-----------
    for tidx in range(ntimes):
        ctime = cbaset.add((tidx * DELTAT), cdtime.Hours)
        print 'In time loop, tidx, ctime: ', tidx, ctime

        time[tidx] = (tidx * DELTAT) / 24.0
        print 'time[tidx], DELTAT: ', time[tidx], DELTAT

        date[tidx] = (ctime.year * 10000) + (ctime.month * 100) + ctime.day
        datesec[tidx] = (ctime.hour * 60 * 60) + (ctime.minute * 60) + \
                        ctime.second
        print 'date[tidx], datesec[tidx]: ', date[tidx], datesec[tidx]

        _do_one_timestep(ctime, ddi, hyam, hybm, p0, phis, phisfcm_in,
                         phisfcr_in, plat, plevm, plevr, plevrp1, plon, ps,
                         pslat, pslon, psus, psvs, q, rgfa2m, rgfa2mus,
                         rgfa2mvs, rgfm2us, rgfm2vs, rgfus2m, rgfvs2m, t, tidx,
                         u, us, v, vs)

        fout.sync()

    fout.close()
    hfin.close()
    tfin.close()

    return
Esempio n. 2
0
    def get(self, returnTuple=1):
        # Ok now the tough part try to figure out everything for the user...

        # overwrite the defintion for the variableConditioners cdmsArguments
        if self.cdmsArguments != []:
            setattr(self.V1, 'cdmsArguments', self.cdmsArguments)
            setattr(self.V2, 'cdmsArguments', self.cdmsArguments)
            if not self.EV is None:
                setattr(self.EV, 'cdmsArguments', self.cdmsArguments)

        # overwrite the defintion for the variableConditioners cdmsKeyowrds
        for k in self.cdmsKeywords.keys():
            self.V1.cdmsKeywords[k] = self.cdmsKeywords[k]
            self.V2.cdmsKeywords[k] = self.cdmsKeywords[k]
            if not self.EV is None:
                self.EV.cdmsKeywords[k] = self.cdmsKeywords[k]

        # Checks the time:
        # 2003-9-15: Added options if both var don't have time then still works
        d1 = None
        d2 = None
        frc1 = None
        frc2 = None
        autotime = None

        if not self.V1.cdmsKeywords.has_key('time'):
            if self.V2.cdmsKeywords.has_key('time'):
                d2 = self.V2(returnTuple=returnTuple)
                if returnTuple:
                    t = d2[0].getTime().asComponentTime()
                else:
                    t = d2.getTime().asComponentTime()
                self.V1.cdmsKeywords['time'] = (t[0], t[-1])
                d1 = self.V1(returnTuple=returnTuple)
                del (self.V1.cdmsKeywords['time'])
            else:  # Automatically gets the maximum common time
                d2 = self.V2(returnTuple=returnTuple)
                if returnTuple:
                    t = d2[0].getTime()
                    if not t is None:
                        t = t.asComponentTime()
                else:
                    t = d2.getTime()
                    if not t is None:
                        t = t.asComponentTime()
                if not t is None:
                    self.V1.cdmsKeywords['time'] = (t[0], t[-1])
                d1 = self.V1(returnTuple=returnTuple)
                if returnTuple:
                    t1 = d1[0].getTime()
                    if not t1 is None:
                        t1 = t1.asComponentTime()
                else:
                    t1 = d1.getTime()
                    if not t1 is None:
                        t1 = t1.asComponentTime()
                if not t1 is None:
                    autotime = [t1[0], t1[-1], 'ccb']
                    if cdtime.compare(t1[0], t[0]) == -1:
                        autotime[0] = t[0]
                    if cdtime.compare(t1[-1], t[-1]) == 1:
                        autotime[1] = t[-1]
                    self.V1.cdmsKeywords['time'] = autotime
                d1 = self.V1(returnTuple=returnTuple)
                if not t1 is None:
                    del (self.V1.cdmsKeywords['time'])
                    self.V2.cdmsKeywords['time'] = autotime
                    d2 = self.V2(returnTuple=returnTuple)
                    del (self.V2.cdmsKeywords['time'])
        elif not self.V2.cdmsKeywords.has_key('time'):
            d1 = self.V1(returnTuple=returnTuple)
            if returnTuple:
                t = d1[0].getTime().asComponentTime()
            else:
                t = d1.getTime().asComponentTime()
            if not t is None:
                self.V2.cdmsKeywords['time'] = (t[0], t[-1])
            d2 = self.V2(returnTuple=returnTuple)
            if not t is None: del (self.V2.cdmsKeywords['time'])

        # Now get the variableConditioners 1 and 2 if necessary
        if d1 is None:
            d1 = self.V1(returnTuple=returnTuple)
        if d2 is None:
            d2 = self.V2(returnTuple=returnTuple)

        if returnTuple:
            # break the output if necessary
            frc2 = d2[1]
            d2 = d2[0]
            frc1 = d1[1]
            d1 = d1[0]
            frc1 = MV2.array(frc1)
            frc2 = MV2.array(frc2)
        else:
            frc1 = MV2.ones(d1.shape, typecode=MV2.float32)
            frc2 = MV2.ones(d2.shape, typecode=MV2.float32)

        frc1.setAxisList(d1.getAxisList())
        frc2.setAxisList(d2.getAxisList())

        ##         # Gets the common time period, only if time keyword isn't defined
        ##         if not(d1.getTime() is None) and not (d2.getTime() is None):
        ##             if len(d1.getTime())!=len(d2.getTime()) and not self.V1.cdmsKeywords.has_key('time') and not self.V2.cdmsKeywords.has_key('time'):
        ##                 t1=d1.getTime().asComponentTime()
        ##                 t2=d2.getTime().asComponentTime()
        ##                 t=[t1[0],t1[-1]]
        ##                 if cdtime.compare(t1[0],t2[0])<0:
        ##                     t[0]=t2[0]
        ##                 if cdtime.compare(t1[-1],t2[-1])>0:
        ##                     t[1]=t2[-1]
        ##                 d1   = d1  (time=(t[0],t[1]))
        ##                 frc1 = frc1(time=(t[0],t[1]))
        ##                 d2   = d2  (time=(t[0],t[1]))
        ##                 frc2 = frc2(time=(t[0],t[1]))

        ##         # remember the number of element in d1 to see if we add non dummy dimensions
        ##         nd1=MV2.count(d1)
        ##         nd2=MV2.count(d2)

        ##         # Now tries to grow extra dims (like dummy levels, etc...)
        ##         o1=d1.getOrder(ids=1)
        ##         o2=d2.getOrder(ids=1)

        if d1.shape != d2.shape:
            if d1.rank() > d2.rank():
                d1, d2 = genutil.grower(d1, d2, singleton=1)
                frc1, frc2 = genutil.grower(frc1, frc2, singleton=1)
            else:
                d2, d1 = genutil.grower(d2, d1, singleton=1)
                frc2, frc1 = genutil.grower(frc2, frc1, singleton=1)

        # External variableConditioner ?
        if not self.EV is None:
            ed = None
            if not self.EV.cdmsKeywords.has_key('time'):
                t = d1.getTime().asComponentTime()
                if not t is None: self.EV.cdmsKeywords['time'] = (t[0], t[-1])
                ed = self.EV(returnTuple=1)
                frced = ed[1]
                ed = ed[0]
                frced = MV2.array(frced)
                frced.setAxisList(ed.getAxisList())

##                 # Gets the common time between d1 and ed
##                 if not t is None: del(self.EV.cdmsKeywords['time'])
##                 if (not ed.getTime() is None) and (not d1.getTime() is None):
##                     if (len(ed.getTime())!=len(d1.getTime())):
##                         t1=d1.getTime().asComponentTime()
##                         t2=ed.getTime().asComponentTime()
##                         t=[t1[0],t1[-1]]
##                         if cdtime.compare(t1[0],t2[0])<0:
##                             t[0]=t2[0]
##                         if cdtime.compare(t1[-1],t2[-1])>0:
##                             t[1]=t2[-1]
##                         d1    = d1  (time=(t[0],t[1]))
##                         d2    = d2  (time=(t[0],t[1]))
##                         ed    = ed  (time=(t[0],t[1]))

##                         frc1  = frc1(time=(t[0],t[1]))
##                         frc2  = frc2(time=(t[0],t[1]))
##                         frced = wed(time=(t[0],t[1]))

            if ed is None:
                ed = self.EV(returnTuple=1)
                frced = ed[1]
                ed = ed[0]
                frced = MV2.array(frced)
                frced.setAxisList(ed.getAxisList())
            g = ed.getGrid()
            g1 = d1.getGrid()
            rf = regrid2.Regridder(g1, g)
            d1, frc1 = rf(d1, mask=1. - frc1.filled(0.), returnTuple=1)
            g2 = d2.getGrid()
            rf = regrid2.Regridder(g2, g)
            d2, frc2 = rf(d2, mask=1. - frc2.filled(0.), returnTuple=1)
            frc1 = MV2.array(frc1)
            frc1.setAxisList(d1.getAxisList())
            frc2 = MV2.array(frc2)
            frc2.setAxisList(d2.getAxisList())
            d1, ed = genutil.grower(d1, ed, singleton=1)
            d2, ed = genutil.grower(d2, ed, singleton=1)
            ed, frced = genutil.grower(ed, frced, singleton=1)

            frc1 = numpy.ma.where(numpy.ma.equal(frc1.filled(0.), 0.), 0.,
                                  frced.filled(0.))
            frc2 = numpy.ma.where(numpy.ma.equal(frc2.filled(0.), 0.), 0.,
                                  frced.filled(0.))

            d1 = MV2.masked_where(MV2.equal(frc1.filled(0.), 0.), d1)
            d2 = MV2.masked_where(MV2.equal(frc2.filled(0.), 0.), d2)

        # Final grid ?
        g = self.weightedGridMaker()
        if not g is None:
            g1 = d1.getGrid()
            g2 = d2.getGrid()
            rf1 = regrid2.Regridder(g1, g)
            rf2 = regrid2.Regridder(g2, g)
            d1, frc1 = rf1(d1, mask=1. - frc1.filled(0.), returnTuple=1)
            ##             m=1.-frc2.filled(0.)
            d2, frc2 = rf2(d2, mask=1. - frc2.filled(0.), returnTuple=1)
            frc1 = MV2.array(frc1)
            frc1.setAxisList(d1.getAxisList())
            frc2 = MV2.array(frc2)
            frc2.setAxisList(d2.getAxisList())
            m = self.weightedGridMaker.weightsMaker(d1)
            if not m is None:
                d1, m = genutil.grower(d1, m)
                frc1, m = genutil.grower(frc1, m)
                frc1 = m.filled(0.)
                d1 = MV2.masked_where(MV2.equal(frc1, 0.), d1)
                m = d1.mask
                if not m is None:
                    frc1 = numpy.where(m, 0., frc1)
            m = self.weightedGridMaker.weightsMaker(d2)
            if not m is None:
                d2, m = genutil.grower(d2, m)
                frc2, m = genutil.grower(frc2, m)
                frc2 = m.filled(0.)
                d2 = MV2.masked_where(MV2.equal(frc2, 0.), d2)
                m = d2.mask
                if not m is numpy.ma.nomask:
                    frc2 = numpy.where(m, 0., frc2)
        elif d1.getGrid() != d2.getGrid():
            g1 = d1.getGrid()
            g2 = d2.getGrid()
            rf = regrid2.Regridder(g2, g1)
            d2, frc2 = rf(d2, mask=1. - frc2.filled(0.), returnTuple=1)
        frc1 = MV2.array(frc1)
        frc1.setAxisList(d1.getAxisList())
        frc2 = MV2.array(frc2)
        frc2.setAxisList(d2.getAxisList())

        # CdmsArguments or CdmsKeywords
        if not self.cdmsArguments is None:
            d1 = d1(*self.cdmsArguments)
            d2 = d2(*self.cdmsArguments)
            frc1 = frc1(*self.cdmsArguments)
            frc2 = frc2(*self.cdmsArguments)

        if not self.cdmsKeywords is None:
            d1 = d1(**self.cdmsKeywords)
            d2 = d2(**self.cdmsKeywords)
            frc1 = frc1(**self.cdmsKeywords)
            frc2 = frc2(**self.cdmsKeywords)

        d1 = MV2.masked_where(MV2.equal(frc1, 0.), d1)
        d2 = MV2.masked_where(MV2.equal(frc2, 0.), d2)
        if not ((d1.mask is None) or (d1.mask is MV2.nomask)):
            if numpy.ma.allclose(d1.mask, 0.):
                d1._mask = numpy.ma.nomask
        if not ((d2.mask is None) or (d2.mask is MV2.nomask)):
            if numpy.ma.allclose(d2.mask, 0.):
                d2._mask = numpy.ma.nomask
        if returnTuple:
            if not ((frc1.mask is None) or (frc1.mask is MV2.nomask)):
                if numpy.ma.allclose(frc1.mask, 0.):
                    frc1._mask = numpy.ma.nomask
            if not ((frc2.mask is None) or (frc2.mask is MV2.nomask)):
                if numpy.ma.allclose(frc2.mask, 0.):
                    frc2._mask = numpy.ma.nomask
            return (d1, frc1), (d2, frc2)
        else:
            return d1, d2
Esempio n. 3
0
    g.ilookup[k, LBNPT] = nlon_target
    # Need to hold float values in an integer array
    g.rlookup[k, BDY] = g.realhead[RC_LatSpacing]
    g.rlookup[k, BDX] = g.realhead[RC_LongSpacing]
    g.rlookup[k, BZY] = lat0
    g.rlookup[k, BZX] = lon0

    data = f.readfld(k)

    # May be different to the overall file settings if it's not a proper
    # ancillary file
    lat1 = rlookup[BZY] + rlookup[BDY]
    lon1 = rlookup[BZX] + rlookup[BDX]
    ingrid = cdms2.createUniformGrid(lat1, nrows, rlookup[BDY], lon1, npts,
                                     rlookup[BDX])

    regridfunc = regrid2.Regridder(ingrid, outgrid)

    newdata = regridfunc(data)

    # If this is a global grid force polar values to be the zonal means
    if (f.fixhd[FH_HorizGrid] == 0
            and np.allclose(rlookup[BZY] + rlookup[BDY], -90.)
            and np.allclose(rlookup[BZX] + rlookup[BDX], 0.)):
        newdata[0, :] = newdata[0, :].mean()
        newdata[-1, :] = newdata[-1, :].mean()

    g.writefld(newdata, k)

g.close()
Esempio n. 4
0
    def get(self, returnTuple=1):
        value = self.data
        frc = None
        if type(value) in [types.TupleType, types.ListType]:
            value, frc = value
        if isinstance(value, numpy.ndarray) or numpy.ma.isMA(
                value):  # Variable defined from array
            if frc is None:
                frc = numpy.ma.ones(value.shape, dtype=numpy.float32)
            kw = {}
            args = []
            # Add user defined cdmsArguments
            for a in self.cdmsArguments:
                args.append(a)
            # Add user defined cdmsKeywords
            for k in self.cdmsKeywords.keys():
                kw[k] = self.cdmsKeywords[k]
            # try to apply, if not forget about it
            try:
                v = value(*args, **kw)
                frc = frc(*args, **kw)
                # Now removes the slice types
                # because they can't be used twice
                for k in kw.keys():
                    if type(kw[k]) == types.SliceType:
                        del (kw[k])
                for i in range(len(args)):
                    if type(args[i]) == types.SliceType:
                        pop(args, i)
                        i = i - 1
            except:
                v = value
        else:  # Variable comes from a file, need to be retrieved
            f = cdms2.open(self.file)
            kw = {}
            args = []
            # Add user defined cdmsArguments
            for a in self.cdmsArguments:
                args.append(a)
            # Add user defined cdmsKeywords
            for k in self.cdmsKeywords.keys():
                kw[k] = self.cdmsKeywords[k]
            v = f(self.var, *args, **kw)
            f.close()
            # Now removes the slice types
            # because they can't be used twice
            for k in kw.keys():
                if type(kw[k]) == types.SliceType:
                    del (kw[k])
            for i in range(len(args)):
                if type(args[i]) == types.SliceType:
                    pop(args, i)
                    i = i - 1

        ## At that stage applied the preprocess function
        if self.preprocess is not None:
            v = apply(self.preprocess, (v, ), self.preprocessKeywords)

        # Create the fractions
        if frc is None:
            frc = v.mask
            if frc is numpy.ma.nomask:  #no mask
                # Create a bunch of ones (100%)
                frc = numpy.ones(v.shape, numpy.float32)
            else:
                # Fraction are actually just the opposite of the mask at that stage !
                frc = frc.astype(
                    MV2.float32)  # Sometimes if it is bytes it doesn't work
                frc = 1. - frc
                frc = frc.astype(
                    MV2.float32)  # no need for double precision here !
        else:
            m = v.mask
            if not m is numpy.ma.nomask:
                frc = MV2.where(m, 0., frc).filled(0.)
        # Now get the associted weights object
        # Note that we pass v in case some of the values are defined as "input"
        # in which case it would use v instead of the weights for weightsing
        m = self.weightsMaker(v)
        if not m is None:
            # grows the variable and the weights for possible Xtra dimensions
            m = m(*args, **kw)
            v, m = genutil.grower(v, m)
            # make sure variable and weights are compatible
            if m.shape != v.shape:
                raise VariableConditionerError, 'weights and variable have different shapes: weights is ' + str(
                    m.shape) + ' and grid is ' + str(v.shape)
            # make sure they're on the same grid (in case one starts at 0 and one at -180 for example

            if not m.getGrid() is v.getGrid():
                m = m.regrid(v.getGrid())

            # Mask the dataset where the fraction are 0.
            v = MV2.masked_where(MV2.equal(m.filled(0), 0.), v)
            # Update the fractions
            frc = m.filled(0.)
            m = v.mask
            if not m is numpy.ma.nomask:
                frc = numpy.where(m, 0., frc)
##             # Filll the mask with ones, i.e. set fraction to 0 when the mask is masked hahah
##             frc = numpy.where(m.filled(1),0.,frc)
# Now get the target grid
        g = self.weightedGridMaker()
        if not g is None:  # we do have a target grid to go to !
            # Create the regridder object
            rf = regrid2.Regridder(v.getGrid(), g)
            # and regrid passing the weights to use to each grid cell
            # at this point it should be only 0/1
            v, frc = rf(v, mask=1. - frc, returnTuple=1)
            frc = MV2.array(frc)
            frc.setAxisList(v.getAxisList())
            v = v(*args, **kw)
            frc = frc(*args, **kw).filled(0.)
            # Note that now frc is not necessarily 0. and 1. but actuall fraction
            # of the grid cell that has real data in it.
            # do we weights after this regridding ?
            # once again pass v in case the weightsing wants
            # to work on the variable
            m = self.weightedGridMaker.weightsMaker(v)
            if not m is None:  # we have a weights
                m = m(*args, **kw)  # apply the extra cdmsKeywords to it
                v, m = genutil.grower(v, m)
                # make sure variable and weights are compatible
                if m.shape != v.shape:
                    raise VariableConditionerError, 'weights and variable have different shapes: weights is ' + str(
                        m.shape) + ' and grid is ' + str(v.shape)
                # make sure they're on the same grid (in case one starts at 0 and one at -180 for example

                if not m.getGrid() is v.getGrid():
                    m = m.regrid(v.getGrid())

                v = MV2.masked_where(MV2.equal(m.filled(0.), 0.), v)
                # weights the fraction where needed
                frc = m.filled(0.)
                m = v.mask
                if not m is numpy.ma.nomask:
                    frc = numpy.where(m, 0., frc)


##                 frc=numpy.where(m.filled(1),0.,frc)
# Now make the fraction an MV2 and puts the dim from v on it
        frc = MV2.array(frc)
        frc.setAxisList(v.getAxisList())
        # just in case applies the cdmsKeywords again
        # usefull in case your final grid is global
        # and you specified Nino3 region for example.
        v = v(*args, **kw)
        frc = frc(*args, **kw).filled(0.)
        if v.missing_value is None:
            v.missing_value = 1.e20
        v = MV2.masked_where(MV2.equal(frc, 0.), v)
        # Now applies the slope and offset if necessary
        if self.slope != 1.:
            v = v * self.slope
        if self.offset != 0.:
            v = v + self.offset

        if not ((v.mask is None) or (v.mask is MV2.nomask)):
            if numpy.ma.allclose(v.mask, 0.):
                v._mask = numpy.ma.nomask
        # Returns the variable and the fractions or just the variable
        if returnTuple:
            ##             if not ((frc.mask is None) or (frc.mask is MV2.nomask)):
            ##                 if numpy.ma.allclose(frc.mask,0.):
            ##                     frc._mask=None
            return v, frc
        else:
            return v
Esempio n. 5
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  : ???
    """
    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(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