示例#1
0
def get_itp_dict(sta_dict, G):
    # get interpolants
    itp_dict = dict()
    for sta_name in sta_dict.keys():
        # target position
        Lon = np.array(sta_dict[sta_name][0])
        Lat = np.array(sta_dict[sta_name][1])
        # get interpolants for this point
        Xi0 = dict()
        Yi0 = dict()
        Xi1 = dict()
        Yi1 = dict()
        Aix = dict()
        Aiy = dict()
        for grd in ['rho', 'u', 'v']:
            xx = G['lon_' + grd][1, :]
            yy = G['lat_' + grd][:, 1]
            xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
            yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
            Xi0[grd] = xi0
            Yi0[grd] = yi0
            Xi1[grd] = xi1
            Yi1[grd] = yi1
            # create little arrays that are used in the actual interpolation
            Aix[grd] = np.array([1 - xfr, xfr]).reshape((1, 1, 2))
            Aiy[grd] = np.array([1 - yfr, yfr]).reshape((1, 2))
        itp_dict[sta_name] = (Xi0, Yi0, Xi1, Yi1, Aix, Aiy)

    return itp_dict
示例#2
0
def get_itp_dict(sta_dict, G):
    # get interpolants
    itp_dict = dict()
    for sta_name in sta_dict.keys():
        # target position
        Lon = np.array(sta_dict[sta_name][0])
        Lat = np.array(sta_dict[sta_name][1])
        # get interpolants for this point
        Xi0 = dict(); Yi0 = dict()
        Xi1 = dict(); Yi1 = dict()
        Aix = dict(); Aiy = dict()
        for grd in ['rho', 'u', 'v']:
            xx = G['lon_' + grd][1,:]
            yy = G['lat_' + grd][:,1]
            xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
            yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
            Xi0[grd] = xi0
            Yi0[grd] = yi0
            Xi1[grd] = xi1
            Yi1[grd] = yi1
            # create little arrays that are used in the actual interpolation
            Aix[grd] = np.array([1-xfr, xfr]).reshape((1,1,2))
            Aiy[grd] = np.array([1-yfr, yfr]).reshape((1,2))
        itp_dict[sta_name] = (Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        
    return itp_dict
示例#3
0
def get_interpolated(G, S, b, lon, lat, z, N):
    # start input dict
    c = dict()
    # 2D fields
    for vn in ['ssh', 'ubar', 'vbar']:
        xr, yr = get_xyr(G, vn)
        Mr, Lr = xr.shape
        u = b[vn]
        uu = zfun.interp_scattered_on_plaid(xr, yr, lon, lat, u)
        uu = np.reshape(uu, xr.shape)
        if np.isnan(uu).any():
            print('Warning: nans in output array for ' + vn)
        else:
            c[vn] = uu
    # 3D fields
    for vn in ['theta', 's3d', 'u3d', 'v3d']:
        xr, yr = get_xyr(G, vn)
        zr = get_zr(G, S, vn)
        Nr, Mr, Lr = zr.shape
        v = b[vn]
        # create an intermediate array, which is on the ROMS lon, lat grid
        # but has the HyCOM vertical grid
        # get interpolants
        xi0, xi1, xf = zfun.get_interpolant(xr, lon, extrap_nan=True)
        yi0, yi1, yf = zfun.get_interpolant(yr, lat, extrap_nan=True)
        # bi linear interpolation
        u00 = v[:, yi0, xi0]
        u10 = v[:, yi1, xi0]
        u01 = v[:, yi0, xi1]
        u11 = v[:, yi1, xi1]
        vi = (1 - yf) * ((1 - xf) * u00 + xf * u01) + yf * (
            (1 - xf) * u10 + xf * u11)
        vi = vi.reshape((N, Mr, Lr))
        # make interpolants to go from the HyCOM vertical grid to the
        # ROMS vertical grid
        I0, I1, FR = zfun.get_interpolant(zr, z, extrap_nan=True)
        zrs = zr.shape
        vif = vi.flatten()
        LL = np.tile(np.arange(Lr), Mr * Nr)
        MM = np.tile(np.repeat(np.arange(Mr), Lr), Nr)
        f0 = LL + MM * Lr + I0 * Mr * Lr
        f1 = LL + MM * Lr + I1 * Mr * Lr
        vv = (1 - FR) * vif[f0] + FR * vif[f1]
        vv = vv.reshape(zrs)
        if np.isnan(vv).any():
            print('Warning: nans in output array for ' + vn)
        else:
            c[vn] = vv
    return c
示例#4
0
def get_interpolated(G, S, b, lon, lat, z, N):
    # start input dict
    c = dict()
    # 2D fields
    for vn in ['ssh', 'ubar', 'vbar']:
        xr, yr = get_xyr(G, vn)
        Mr, Lr = xr.shape
        u = b[vn]
        uu = zfun.interp_scattered_on_plaid(xr, yr, lon, lat, u)
        uu = np.reshape(uu, xr.shape)
        if np.isnan(uu).any():
            print('Warning: nans in output array for ' + vn)
        else:
            c[vn] = uu
    # 3D fields
    for vn in ['theta', 's3d', 'u3d', 'v3d']:
        xr, yr = get_xyr(G, vn)
        zr = get_zr(G, S, vn)
        Nr, Mr, Lr = zr.shape
        v = b[vn]
        # create an intermediate array, which is on the ROMS lon, lat grid
        # but has the HyCOM vertical grid
        # get interpolants
        xi0, xi1, xf = zfun.get_interpolant(xr, lon, extrap_nan=True)
        yi0, yi1, yf = zfun.get_interpolant(yr, lat, extrap_nan=True)
        # bi linear interpolation
        u00 = v[:,yi0,xi0]
        u10 = v[:,yi1,xi0]
        u01 = v[:,yi0,xi1]
        u11 = v[:,yi1,xi1]
        vi = (1-yf)*((1-xf)*u00 + xf*u01) + yf*((1-xf)*u10 + xf*u11)
        vi = vi.reshape((N, Mr, Lr))
        # make interpolants to go from the HyCOM vertical grid to the
        # ROMS vertical grid
        I0, I1, FR = zfun.get_interpolant(zr, z, extrap_nan=True)
        zrs = zr.shape    
        vif = vi.flatten()
        LL = np.tile(np.arange(Lr), Mr*Nr)
        MM = np.tile(np.repeat(np.arange(Mr), Lr), Nr)
        f0 = LL + MM*Lr + I0*Mr*Lr
        f1 = LL + MM*Lr + I1*Mr*Lr
        vv = (1-FR)*vif[f0] + FR*vif[f1]
        vv = vv.reshape(zrs)
        if np.isnan(vv).any():
            print('Warning: nans in output array for ' + vn)
        else:
            c[vn] = vv
    return c
示例#5
0
        
        # get coordinates
        indir = indir0 + ocn + '/Data/'
        coord_dict = pickle.load(open(indir + 'coord_dict.p', 'rb'))
        lon = coord_dict['lon']
        lat = coord_dict['lat']

        # get fields
        # note that when we use the "xfh" fields there should be no nans
        xfh = pickle.load(open(indir + '/xfh' + mds + '.p', 'rb'))
        zeta = xfh['ssh']

        # get indices around certain regions, and their data
        #
        # (a) Mouth of Strait of Juan de Fuca
        i0, i1, fr = zfun.get_interpolant(np.array([-124.7, -124.5]), lon, extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([48.4, 48.6]), lat, extrap_nan=False)
        zeta_jdf = zeta[j0[0]:j1[1]+1, i0[0]:i1[1]+1]
        #
        # (b) Northern Strait of Georgia
        i0, i1, fr = zfun.get_interpolant(np.array([-125.5, -124.5]), lon, extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([50.25, 50.45]), lat, extrap_nan=False)
        zeta_sog = zeta[j0[0]:j1[1]+1, i0[0]:i1[1]+1]
        #
        # (c) Offshore
        i0, i1, fr = zfun.get_interpolant(np.array([-127, -126]), lon, extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([46, 47]), lat, extrap_nan=False)
        zeta_off = zeta[j0[0]:j1[1]+1, i0[0]:i1[1]+1]
        
        mdt = datetime.strptime(mds,'%Y.%m.%d')
        zdf.loc[mdt, 'z_jdf'] = zeta_jdf.mean()
示例#6
0
def get_V(vn_list, ds, plon, plat, pcs, R, surface, bound='stop'):

    from warnings import filterwarnings
    filterwarnings('ignore')  # skip some warning messages

    # get interpolant arrays
    i0lon_d = dict()
    i1lon_d = dict()
    frlon_d = dict()
    i0lat_d = dict()
    i1lat_d = dict()
    frlat_d = dict()
    for gg in ['r', 'u', 'v']:
        exn = False
        i0lon_d[gg], i1lon_d[gg], frlon_d[gg] = zfun.get_interpolant(
            plon, R['rlon' + gg], extrap_nan=exn)
        i0lat_d[gg], i1lat_d[gg], frlat_d[gg] = zfun.get_interpolant(
            plat, R['rlat' + gg], extrap_nan=exn)
    i0csr, i1csr, frcsr = zfun.get_interpolant(pcs, R['rcsr'], extrap_nan=exn)
    i0csw, i1csw, frcsw = zfun.get_interpolant(pcs, R['rcsw'], extrap_nan=exn)
    NV = len(vn_list)
    NP = len(plon)
    # get interpolated values
    V = np.nan * np.ones((NP, NV))
    vcount = 0
    for vn in vn_list:
        if vn in ['w']:
            i0cs = i0csw
            i1cs = i1csw
            frcs = frcsw
        else:
            i0cs = i0csr
            i1cs = i1csr
            frcs = frcsr
# Bartos - adding 'AKs_turb' and 'dAKs_dz' to list
        if vn in [
                'salt', 'temp', 'zeta', 'h', 'Uwind', 'Vwind', 'w', 'AKs',
                'dAKs_dz'
        ]:
            gg = 'r'
        elif vn in ['u']:
            gg = 'u'
        elif vn in ['v']:
            gg = 'v'
        i0lat = i0lat_d[gg]
        i1lat = i1lat_d[gg]
        frlat = frlat_d[gg]
        i0lon = i0lon_d[gg]
        i1lon = i1lon_d[gg]
        frlon = frlon_d[gg]
        # get the data field and put nan's in masked points
        if vn in ['salt', 'temp', 'u', 'v', 'w'] and surface == True:
            v0 = ds[vn][0, -1, :, :].squeeze()
        else:
            v0 = ds[vn][:].squeeze()
        try:
            vv = v0.data
            vv[v0.mask] = np.nan
        except AttributeError:
            # it is not a masked array
            vv = v0
# Bartos - adding 'AKs' to list
        if vn in ['salt', 'temp', 'AKs', 'u', 'v', 'w'] and surface == False:
            # For variables with depth axis
            # Get just the values around our particle positions.
            # each row in VV corresponds to a "box" around a point
            VV = np.nan * np.ones((NP, 8))
            VV[:, 0] = vv[i0cs, i0lat, i0lon]
            VV[:, 1] = vv[i0cs, i0lat, i1lon]
            VV[:, 2] = vv[i0cs, i1lat, i0lon]
            VV[:, 3] = vv[i0cs, i1lat, i1lon]
            VV[:, 4] = vv[i1cs, i0lat, i0lon]
            VV[:, 5] = vv[i1cs, i0lat, i1lon]
            VV[:, 6] = vv[i1cs, i1lat, i0lon]
            VV[:, 7] = vv[i1cs, i1lat, i1lon]
            # Work on edge values.  If all in a box are masked
            # then that row will be nan's, and also:
            # Bartos - adding reflective boundary condition and 'AKs_turb' to velocity list
            if bound == 'stop':
                if vn in ['u', 'v', 'w', 'AKs']:
                    # set all velocities to zero if any in the box are masked
                    VV[np.isnan(VV).any(axis=1), :] = 0
            elif bound == 'reflect':
                # get magnitude of average velocity
                newval_mag = abs(np.nanmean(VV, axis=1).reshape(NP, 1))
                if vn in ['w', 'AKs']:
                    # set vertical velocity and AKs to zero if any in the box are masked
                    VV[np.isnan(VV).any(axis=1), :] = 0
                elif vn in ['u']:
                    # mask0 for masked points on i0lon
                    mask0 = np.isnan(VV[:, [0, 2, 4, 6]]).any(axis=1)
                    # mask1 for masked points on i1lon
                    mask1 = np.isnan(VV[:, [1, 3, 5, 7]]).any(axis=1)
                    # set u-velocity away from mask
                    VV[mask0, :] = newval_mag[mask0]
                    VV[mask1, :] = -newval_mag[mask1]
                elif vn in ['v']:
                    # mask0 for masked points on i0lat
                    mask0 = np.isnan(VV[:, [0, 1, 4, 5]]).any(axis=1)
                    # mask1 for masked points on i1lat
                    mask1 = np.isnan(VV[:, [2, 3, 6, 7]]).any(axis=1)
                    # set v-velocity away from mask
                    VV[mask0, :] = newval_mag[mask0]
                    VV[mask1, :] = -newval_mag[mask1]
            elif vn in ['salt', 'temp']:
                # set all tracers to their average if any in the box are masked
                newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones(
                    (1, 8))
                mask = np.isnan(VV)
                VV[mask] = newval[mask]
            # now do the interpolation in each box
            vl = ((1 - frlat) * ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) +
                  frlat * ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
            vu = ((1 - frlat) * ((1 - frlon) * VV[:, 4] + frlon * VV[:, 5]) +
                  frlat * ((1 - frlon) * VV[:, 6] + frlon * VV[:, 7]))
            v = (1 - frcs) * vl + frcs * vu
        elif vn in ['salt', 'temp', 'u', 'v', 'w'] and surface == True:
            VV = np.nan * np.ones((NP, 4))
            VV[:, 0] = vv[i0lat, i0lon]
            VV[:, 1] = vv[i0lat, i1lon]
            VV[:, 2] = vv[i1lat, i0lon]
            VV[:, 3] = vv[i1lat, i1lon]
            # Work on edge values.  If all in a box are masked
            # then that row will be nan's, and also:
            # Bartos - adding reflective boundary condition and 'AKs_turb' to velocity list
            if bound == 'stop':
                if vn in ['u', 'v', 'w', 'AKs']:
                    # set all velocities to zero if any in the box are masked
                    VV[np.isnan(VV).any(axis=1), :] = 0
            elif bound == 'reflect':
                # get magnitude of average velocity
                newval_mag = abs(np.nanmean(VV, axis=1).reshape(NP, 1))
                if vn in ['w', 'AKs']:
                    # set vertical velocity and AKs to zero if any in the box are masked
                    VV[np.isnan(VV).any(axis=1), :] = 0
                elif vn in ['u']:
                    # mask0 for masked points on i0lon
                    mask0 = np.isnan(VV[:, [0, 2]]).any(axis=1)
                    # mask1 for masked points on i1lon
                    mask1 = np.isnan(VV[:, [1, 3]]).any(axis=1)
                    # set u-velocity away from mask
                    VV[mask0, :] = newval_mag[mask0]
                    VV[mask1, :] = -newval_mag[mask1]
                elif vn in ['v']:
                    # mask0 for masked points on i0lat
                    mask0 = np.isnan(VV[:, [0, 1]]).any(axis=1)
                    # mask1 for masked points on i1lat
                    mask1 = np.isnan(VV[:, [2, 3]]).any(axis=1)
                    # set v-velocity away from mask
                    VV[mask0, :] = newval_mag[mask0]
                    VV[mask1, :] = -newval_mag[mask1]
            elif vn in ['salt', 'temp']:
                # set all tracers to their average if any in the box are masked
                newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones(
                    (1, 4))
                mask = np.isnan(VV)
                VV[mask] = newval[mask]
            newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones((1, 4))
            mask = np.isnan(VV)
            VV[mask] = newval[mask]
            v = ((1 - frlat) * ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) +
                 frlat * ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
        elif vn in ['zeta', 'Uwind', 'Vwind', 'h']:
            # For variables without depth axis
            VV = np.nan * np.ones((NP, 4))
            VV[:, 0] = vv[i0lat, i0lon]
            VV[:, 1] = vv[i0lat, i1lon]
            VV[:, 2] = vv[i1lat, i0lon]
            VV[:, 3] = vv[i1lat, i1lon]
            newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones((1, 4))
            mask = np.isnan(VV)
            VV[mask] = newval[mask]
            v = ((1 - frlat) * ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) +
                 frlat * ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
        V[:, vcount] = v
        vcount += 1

    return V
示例#7
0
文件: svar_1.py 项目: eabrasse/etools
    h_list = os.listdir(dir0 + f_dir)
    h_list.sort()
    h_list = [x for x in h_list if x[:9] == 'ocean_his']
    if tt == 0:
        pass
    else:
        h_list = h_list[1:]  # drop the zero hour for all but the first day
    #
    for hi in h_list:
        fn = dir0 + f_dir + '/' + hi
        ds = nc.Dataset(fn)
        if tt == 0:
            G, S, T = zrfun.get_basic_info(fn)
            lon_vec = G['lon_rho'][0, :].squeeze()
            lat_vec = G['lat_rho'][:, 0].squeeze()
            ii0, ii1, ifr = zfun.get_interpolant(np.array([0.02, 1.5]),
                                                 lon_vec)
            jj0, jj1, jfr = zfun.get_interpolant(np.array([44.8, 45.2]),
                                                 lat_vec)
            i0 = ii0[0]
            i1 = ii1[1]
            j0 = jj0[0]
            j1 = jj1[1]
            h = G['h'][j0:j1, i0:i1]
            dx = G['DX'][j0:j1, i0:i1]
            dy = G['DY'][j0:j1, i0:i1]
            da = dx * dy
            ny, nx = da.shape

        zeta = ds['zeta'][0, j0:j1, i0:i1].squeeze()
        salt = ds['salt'][0, :, j0:j1, i0:i1].squeeze()
        zr, zw = zrfun.get_z(h, zeta, S)
示例#8
0
dista = np.tile(distr, [N, 1])  # array

# pack fields to process in dicts
d2 = dict()
d2['zbot'] = zbot
d2['zeta'] = zeta
d2['lon'] = lon
d2['lat'] = lat
d3 = dict()
d3['zr'] = zr
d3['salt'] = salt

# get vectors describing the (plaid) grid
xx = lon[1, :]
yy = lat[:, 1]
xit = zfun.get_interpolant(x, xx)
yit = zfun.get_interpolant(y, yy)

# and prepare them to do the bilinear interpolation
xita = np.array(xit)
yita = np.array(yit)
col0 = xita[:, 0].astype(int)
col1 = xita[:, 1].astype(int)
colf = xita[:, 2]
colff = 1 - colf
row0 = yita[:, 0].astype(int)
row1 = yita[:, 1].astype(int)
rowf = yita[:, 2]
rowff = 1 - rowf

# now actually do the interpolation
示例#9
0
def get_V(vn_list, ds, plon, plat, pcs, R, surface):
    """
    The all-purpose tool for getting properties at
    particle locations using interpolation.
    """

    from warnings import filterwarnings
    filterwarnings('ignore')  # skip some warning messages

    # get interpolant arrays
    i0lon_d = dict()
    i1lon_d = dict()
    frlon_d = dict()
    i0lat_d = dict()
    i1lat_d = dict()
    frlat_d = dict()

    for gg in ['r', 'u', 'v']:
        exn = True  # nan-out particles that leave domain
        i0lon_d[gg], i1lon_d[gg], frlon_d[gg] = zfun.get_interpolant(
            plon, R['rlon' + gg], extrap_nan=exn)
        i0lat_d[gg], i1lat_d[gg], frlat_d[gg] = zfun.get_interpolant(
            plat, R['rlat' + gg], extrap_nan=exn)
    i0csr, i1csr, frcsr = zfun.get_interpolant(pcs, R['rcsr'], extrap_nan=exn)
    i0csw, i1csw, frcsw = zfun.get_interpolant(pcs, R['rcsw'], extrap_nan=exn)

    NV = len(vn_list)
    NP = len(plon)

    # get interpolated values
    V = np.nan * np.ones((NP, NV))
    vcount = 0
    for vn in vn_list:
        if vn in ['w', 'AKs']:
            i0cs = i0csw
            i1cs = i1csw
            frcs = frcsw
        else:
            i0cs = i0csr
            i1cs = i1csr
            frcs = frcsr
        if vn == 'u':
            gg = 'u'
        elif vn == 'v':
            gg = 'v'
        else:
            gg = 'r'
        i0lat = i0lat_d[gg]
        i1lat = i1lat_d[gg]
        frlat = frlat_d[gg]
        i0lon = i0lon_d[gg]
        i1lon = i1lon_d[gg]
        frlon = frlon_d[gg]
        # get the data field and put nan's in masked points
        # (later we do more massaging)
        if vn in ['salt', 'temp', 'u', 'v', 'w'] and surface == True:
            v0 = ds[vn][0, -1, :, :].squeeze()
        else:
            v0 = ds[vn][:].squeeze()
        try:
            vv = v0.data
            vv[v0.mask] = np.nan
        except AttributeError:
            # it is not a masked array
            vv = v0

        if vn in ['salt', 'temp', 'AKs', 'u', 'v', 'w'] and surface == False:
            # Get just the values around our particle positions.
            # each row in VV corresponds to a "box" around a point
            #
            VV = np.nan * np.ones((NP, 8))
            # using "fancy indexing" in which the three indexing arrays
            # are the same length and the resulting vector has the same length
            # (works for numpy arrays, not for NetCDF)
            VV[:, 0] = vv[i0cs, i0lat, i0lon]
            VV[:, 1] = vv[i0cs, i0lat, i1lon]
            VV[:, 2] = vv[i0cs, i1lat, i0lon]
            VV[:, 3] = vv[i0cs, i1lat, i1lon]
            VV[:, 4] = vv[i1cs, i0lat, i0lon]
            VV[:, 5] = vv[i1cs, i0lat, i1lon]
            VV[:, 6] = vv[i1cs, i1lat, i0lon]
            VV[:, 7] = vv[i1cs, i1lat, i1lon]
            # Work on edge values.  If all in a box are masked
            # then that row will be 8 nan's, and also:
            if vn in ['u', 'v', 'w', 'AKs']:
                # set all velocities and AKs to zero if any in the box are nan
                mask = np.isnan(VV)
                VV[mask] = 0
            elif vn in ['salt', 'temp']:
                # set all tracers to their average if any in the box are masked
                newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones(
                    (1, 8))
                mask = np.isnan(VV)
                VV[mask] = newval[mask]
            # now do the interpolation in each box
            vl = ((1 - frlat) * ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) +
                  frlat * ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
            vu = ((1 - frlat) * ((1 - frlon) * VV[:, 4] + frlon * VV[:, 5]) +
                  frlat * ((1 - frlon) * VV[:, 6] + frlon * VV[:, 7]))
            v = (1 - frcs) * vl + frcs * vu
        elif vn in ['salt', 'temp', 'u', 'v', 'w'] and surface == True:
            #from time import time
            #tt0 = time()
            if vn == 'w':
                v = np.zeros(NP)
            else:
                VV = np.nan * np.ones((NP, 4))
                VV[:, 0] = vv[i0lat, i0lon]
                VV[:, 1] = vv[i0lat, i1lon]
                VV[:, 2] = vv[i1lat, i0lon]
                VV[:, 3] = vv[i1lat, i1lon]
                # Work on edge values.  If all in a box are masked
                # then that row will be nan's, and also:
                if vn in ['u', 'v', 'w']:
                    # set all velocities to zero if any in the box are masked
                    # wait... this looks like it just sets masked velocities to
                    # zero, not all of them... 2019.11.08
                    mask = np.isnan(VV)
                    VV[mask] = 0
                elif vn in ['salt', 'temp']:
                    # set all tracers to their average if any in the box are masked
                    newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones(
                        (1, 4))
                    mask = np.isnan(VV)
                    VV[mask] = newval[mask]
                v = ((1 - frlat) *
                     ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) + frlat *
                     ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
            #print('%s  took %0.3f seconds' % (vn, time() - tt0))
        elif vn in ['zeta', 'Uwind', 'Vwind', 'h']:
            VV = np.nan * np.ones((NP, 4))
            VV[:, 0] = vv[i0lat, i0lon]
            VV[:, 1] = vv[i0lat, i1lon]
            VV[:, 2] = vv[i1lat, i0lon]
            VV[:, 3] = vv[i1lat, i1lon]
            newval = np.nanmean(VV, axis=1).reshape(NP, 1) * np.ones((1, 4))
            mask = np.isnan(VV)
            VV[mask] = newval[mask]
            v = ((1 - frlat) * ((1 - frlon) * VV[:, 0] + frlon * VV[:, 1]) +
                 frlat * ((1 - frlon) * VV[:, 2] + frlon * VV[:, 3]))
        V[:, vcount] = v
        vcount += 1

    return V
示例#10
0
def get_cast(gridname, tag, ex_name, date_string, station, lon_str, lat_str):

    # get the dict Ldir
    Ldir = Lfun.Lstart(gridname, tag)
    Ldir['gtagex'] = Ldir['gtag'] + '_' + ex_name
    Ldir['date_string'] = date_string
    Ldir['station'] = station
    Ldir['lon_str'] = lon_str
    Ldir['lat_str'] = lat_str

    # make sure the output directory exists
    outdir0 = Ldir['LOo'] + 'cast/'
    Lfun.make_dir(outdir0)
    outdir = outdir0 + Ldir['gtagex'] + '/'
    Lfun.make_dir(outdir)

    dt = Ldir['date_string']

    #%% function definitions

    def get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy):
        dims = ds.variables[vv].dimensions
        if 'eta_rho' in dims:
            grd = 'rho'
        elif 'eta_u' in dims:
            grd = 'u'
        elif 'eta_v' in dims:
            grd = 'v'
        else:
            print('grid error!')
        xi0 = Xi0[grd]
        yi0 = Yi0[grd]
        xi1 = Xi1[grd]
        yi1 = Yi1[grd]
        aix = Aix[grd]
        aiy = Aiy[grd]

        xi01 = np.array([xi0, xi1]).flatten()
        yi01 = np.array([yi0, yi1]).flatten()
        return xi01, yi01, aix, aiy

    #%% set up for the extraction

    # target position
    Lon = np.array(float(Ldir['lon_str']))
    Lat = np.array(float(Ldir['lat_str']))

    # get grid info
    indir = Ldir['roms'] + 'output/' + Ldir['gtagex'] + '/f' + dt + '/'
    fn = indir + 'ocean_his_0021.nc'  # approx. noon local standard time

    if os.path.isfile(fn):
        pass
    else:
        print('Not found: ' + fn)
        return

    G = zrfun.get_basic_info(fn, only_G=True)
    S = zrfun.get_basic_info(fn, only_S=True)

    lon = G['lon_rho']
    lat = G['lat_rho']
    mask = G['mask_rho']
    xvec = lon[0, :].flatten()
    yvec = lat[:, 0].flatten()

    i0, i1, frx = zfun.get_interpolant(np.array([float(Ldir['lon_str'])]),
                                       xvec)
    j0, j1, fry = zfun.get_interpolant(np.array([float(Ldir['lat_str'])]),
                                       yvec)
    i0 = int(i0)
    j0 = int(j0)
    # find indices of nearest good point
    if mask[j0, i0] == 1:
        print('- ' + station + ': point OK')
    elif mask[j0, i0] == 0:
        print('- ' + station + ':point masked')
        i0, j0 = get_ij_good(lon, lat, xvec, yvec, i0, j0, mask)
        new_lon = xvec[i0]
        new_lat = yvec[j0]
        Lon = np.array(new_lon)
        Lat = np.array(new_lat)

    # get interpolants for this point
    Xi0 = dict()
    Yi0 = dict()
    Xi1 = dict()
    Yi1 = dict()
    Aix = dict()
    Aiy = dict()
    for grd in ['rho', 'u', 'v']:
        xx = G['lon_' + grd][1, :]
        yy = G['lat_' + grd][:, 1]
        xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
        yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
        Xi0[grd] = xi0
        Yi0[grd] = yi0
        Xi1[grd] = xi1
        Yi1[grd] = yi1
        # create little arrays that are used in the actual interpolation
        Aix[grd] = np.array([1 - xfr, xfr]).reshape((1, 1, 2))
        Aiy[grd] = np.array([1 - yfr, yfr]).reshape((1, 2))

    # generating some lists
    v0_list = ['h', 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v']
    v1_list = ['ocean_time']
    v2_list = []
    v3_list_rho = []
    v3_list_w = []
    ds = nc.Dataset(fn)
    for vv in ds.variables:
        vdim = ds.variables[vv].dimensions
        if (('ocean_time' in vdim) and ('s_rho' not in vdim)
                and ('s_w' not in vdim) and (vv != 'ocean_time')):
            v2_list.append(vv)
        elif (('ocean_time' in vdim) and ('s_rho' in vdim)):
            v3_list_rho.append(vv)
        elif (('ocean_time' in vdim) and ('s_w' in vdim)):
            v3_list_w.append(vv)

    V = dict()
    V_long_name = dict()
    V_units = dict()
    v_all_list = v0_list + v1_list + v2_list + v3_list_rho + v3_list_w
    for vv in v_all_list:
        V[vv] = np.array([])
        try:
            V_long_name[vv] = ds.variables[vv].long_name
        except:
            V_long_name[vv] = ''
        try:
            V_units[vv] = ds.variables[vv].units
        except:
            V_units[vv] = ''

    # get static variables
    for vv in v0_list:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][yi01, xi01].squeeze()
        V[vv] = (aiy * ((aix * vvtemp).sum(-1))).sum(-1)

    ds.close()

    #%% extract time-dependent fields

    print('-- Working on date: ' + dt)
    sys.stdout.flush()

    ds = nc.Dataset(fn)
    for vv in v1_list:
        vtemp = ds.variables[vv][:].squeeze()
        V[vv] = np.append(V[vv], vtemp)
    for vv in v2_list:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, yi01, xi01].squeeze()
        vtemp = (aiy * ((aix * vvtemp).sum(-1))).sum(-1)
        V[vv] = np.append(V[vv], vtemp)
    for vv in v3_list_rho:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, :, yi01, xi01].squeeze()
        vtemp = (aiy * ((aix * vvtemp).sum(-1))).sum(-1)
        V[vv] = vtemp.reshape((S['N'], 1))
    for vv in v3_list_w:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, :, yi01, xi01].squeeze()
        vtemp = (aiy * ((aix * vvtemp).sum(-1))).sum(-1)
        V[vv] = vtemp.reshape((S['N'] + 1, 1))

    ds.close()

    # create z_rho and z_w (has to be done after we have V['zeta'])
    hh = V['h'][:] * np.ones_like(V['zeta'])
    z_rho, z_w = zrfun.get_z(hh, V['zeta'][:], S)
    V['hh'] = hh
    V_long_name['hh'] = 'bottom depth (positive down) as a vector'
    V_units['hh'] = 'm'
    V['z_rho'] = z_rho
    V_long_name['z_rho'] = 'z on rho points (positive up)'
    V_units['z_rho'] = 'm'
    V['z_w'] = z_w
    V_long_name['z_w'] = 'z on w points (positive up)'
    V_units['z_w'] = 'm'
    v2_list.append('hh')
    v3_list_rho.append('z_rho')
    v3_list_w.append('z_w')

    #%% save the output to NetCDF
    out_fn = (outdir + Ldir['station'] + '_' + Ldir['date_string'] + '.nc')
    # get rid of the old version, if it exists
    try:
        os.remove(out_fn)
    except OSError:
        pass  # assume error was because the file did not exist
    foo = nc.Dataset(out_fn, 'w')

    N = S['N']
    NT = len(V['ocean_time'][:])

    foo.createDimension('scalar', 1)
    foo.createDimension('s_rho', N)
    foo.createDimension('s_w', N + 1)
    foo.createDimension('ocean_time', NT)

    for vv in v0_list:
        v_var = foo.createVariable(vv, float, ('scalar'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v1_list:
        v_var = foo.createVariable(vv, float, ('ocean_time', ))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v2_list:
        v_var = foo.createVariable(vv, float, ('ocean_time', ))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v3_list_rho:
        v_var = foo.createVariable(vv, float, ('s_rho', 'ocean_time'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v3_list_w:
        v_var = foo.createVariable(vv, float, ('s_w', 'ocean_time'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]

    foo.close()
示例#11
0
def get_extrapolated(in_fn,
                     L,
                     M,
                     N,
                     X,
                     Y,
                     lon,
                     lat,
                     z,
                     Ldir,
                     add_CTD=False,
                     fix_NSoG=False):
    b = pickle.load(open(in_fn, 'rb'))
    vn_list = list(b.keys())

    # check that things are the expected shape
    def check_coords(shape_tuple, arr_shape):
        if arr_shape != shape_tuple:
            print('WARNING: array shape mismatch')

    for vn in vn_list:
        if vn == 'dt':
            pass
        elif vn == 'ssh':
            check_coords((M, L), b[vn].shape)
        else:
            check_coords((N, M, L), b[vn].shape)
    # creat output array and add dt to it.
    vn_list.remove('dt')
    V = dict()
    for vn in vn_list:
        V[vn] = np.nan + np.ones(b[vn].shape)
    V['dt'] = b['dt']
    # extrapolate ssh
    vn = 'ssh'
    v = b[vn]
    if fix_NSoG:
        print(' ^^ Fixing NSoG ^^')
        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        # (a) Mouth of Strait of Juan de Fuca
        i0, i1, fr = zfun.get_interpolant(np.array([-124.7, -124.5]),
                                          lon,
                                          extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([48.4, 48.6]),
                                          lat,
                                          extrap_nan=False)
        zeta_jdf = v[j0[0]:j1[1] + 1, i0[0]:i1[1] + 1]
        #
        # (b) Northern Strait of Georgia
        i0, i1, fr = zfun.get_interpolant(np.array([-125.5, -124.5]),
                                          lon,
                                          extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([50.15, 50.45]),
                                          lat,
                                          extrap_nan=False)
        v[j0[0]:j1[1] + 1, i0[0]:i1[1] + 1] = np.nanmean(zeta_jdf) + 0.1
        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    vv = extrap_nearest_to_masked(X, Y, v)
    V[vn] = vv
    vn_list.remove('ssh')
    # extrapolate 3D fields
    for vn in vn_list:
        v = b[vn]
        if vn == 't3d':
            v0 = np.nanmin(v)
        elif vn == 's3d':
            v0 = np.nanmax(v)
        if vn in ['t3d', 's3d']:
            print(' -- extrapolating ' + vn)
            if add_CTD == False:
                for k in range(N):
                    fld = v[k, :, :]
                    fldf = extrap_nearest_to_masked(X, Y, fld, fld0=v0)
                    V[vn][k, :, :] = fldf
            elif add_CTD == True:
                print(vn + ' Adding CTD data before extrapolating')
                Cast_dict, sta_df = Ofun_CTD.get_casts(Ldir)
                for k in range(N):
                    fld = v[k, :, :]
                    zz = z[k]
                    xyorig, fldorig = Ofun_CTD.get_orig(
                        Cast_dict, sta_df, X, Y, fld, lon, lat, zz, vn)
                    fldf = Ofun_CTD.extrap_nearest_to_masked_CTD(
                        X, Y, fld, xyorig=xyorig, fldorig=fldorig, fld0=v0)
                    V[vn][k, :, :] = fldf
        elif vn in ['u3d', 'v3d']:
            print(' -- extrapolating ' + vn)
            vv = v.copy()
            vv = np.ma.masked_where(np.isnan(vv), vv)
            vv[vv.mask] = 0
            V[vn] = vv.data
    # Create ubar and vbar.
    # Note: this is slightly imperfect because the z levels are at the same
    # position as the velocity levels.
    dz = np.nan * np.ones((N, 1, 1))
    dz[1:, 0, 0] = np.diff(z)
    dz[0, 0, 0] = dz[1, 0, 0]

    # account for the fact that the new hycom fields do not show up masked
    u3d = np.ma.masked_where(np.isnan(b['u3d']), b['u3d'])
    v3d = np.ma.masked_where(np.isnan(b['v3d']), b['v3d'])
    dz3 = dz * np.ones_like(u3d)  # make dz a masked array
    b['ubar'] = np.sum(u3d * dz3, axis=0) / np.sum(dz3, axis=0)
    b['vbar'] = np.sum(v3d * dz3, axis=0) / np.sum(dz3, axis=0)

    for vn in ['ubar', 'vbar']:
        v = b[vn]
        vv = v.copy()
        vv = np.ma.masked_where(np.isnan(vv), vv)
        vv[vv.mask] = 0
        V[vn] = vv.data
    # calculate potential temperature
    press_db = -z.reshape((N, 1, 1))
    V['theta'] = seawater.ptmp(V['s3d'], V['t3d'], press_db)
    return V
示例#12
0
dista = np.tile(distr, [N, 1]) # array

# pack fields to process in dicts
d2 = dict()
d2['zbot'] = zbot
d2['zeta'] = zeta
d2['lon'] = lon
d2['lat'] = lat
d3 = dict()
d3['zr'] = zr
d3['salt'] = salt

# get vectors describing the (plaid) grid
xx = lon[1,:]
yy = lat[:,1]
xit = zfun.get_interpolant(x, xx)
yit = zfun.get_interpolant(y, yy)

# and prepare them to do the bilinear interpolation
xita = np.array(xit)
yita = np.array(yit)
col0 = xita[:, 0].astype(int)
col1 = xita[:, 1].astype(int)
colf = xita[:, 2]
colff = 1 - colf
row0 = yita[:, 0].astype(int)
row1 = yita[:, 1].astype(int)
rowf = yita[:, 2]
rowff = 1 - rowf

# now actually do the interpolation
            qnet_up_b = np.cumsum(q_up)
            qnet_down_b = np.cumsum(q_down)
            qnet_r_b = np.cumsum(q_r)
            qnet_b = qnet_up_b - qnet_down_b

            dQ_a = qnet_a[0] - q_s[0]
            dQ_b = qnet_b[-1] - q_s[-1]

            qnet_aa = np.append(qnet_a, 0)
            qnet_bb = np.append(0, qnet_b)

            qnet_aa -= dQ_a
            qnet_bb -= dQ_b

            # now let's find a way to interpolate to get the amount to split
            i0, i1, fr = zfun.get_interpolant(np.array([0]), qnet_bb)
            i0 = i0[0]
            i1 = i1[0]
            print('i0=%d, i1=%d, fr=%0.2f' % (i0, i1, fr))

            # qnet[0:i0+1] = qnet_aa[0:i0+1]
            # qnet[i1:] = qnet_bb[i1:]
            qnet[0:i0 + 1] = qnet_aa[0:i0 + 1] - (qnet_aa[i0] + fr *
                                                  (qnet_aa[i1] - qnet_aa[i0]))
            qnet[i1:] = qnet_bb[i1:] - (qnet_bb[i0] + fr *
                                        (qnet_bb[i1] - qnet_bb[i0]))

            # Now apply the same split to the other vectors
            qnet_up_aa = np.append(qnet_up_a, 0)
            qnet_up_bb = np.append(0, qnet_up_b)
            qnet_down_aa = np.append(qnet_down_a, 0)
示例#14
0
def get_section(ds, vn, x, y, in_dict):

    # PLOT CODE
    from warnings import filterwarnings
    filterwarnings('ignore')  # skip a warning message

    # GET DATA
    G, S, T = zrfun.get_basic_info(in_dict['fn'])
    h = G['h']
    zeta = ds['zeta'][:].squeeze()
    zr = zrfun.get_z(h, zeta, S, only_rho=True)

    sectvar = ds[vn][:].squeeze()

    L = G['L']
    M = G['M']
    N = S['N']

    lon = G['lon_rho']
    lat = G['lat_rho']
    mask = G['mask_rho']
    maskr = mask.reshape(1, M, L).copy()
    mask3 = np.tile(maskr, [N, 1, 1])
    zbot = -h  # don't need .copy() because of the minus operation

    # make sure fields are masked
    zeta[mask == False] = np.nan
    zbot[mask == False] = np.nan
    sectvar[mask3 == False] = np.nan

    # create dist
    earth_rad = zfun.earth_rad(np.mean(lat[:, 0]))  # m
    xrad = np.pi * x / 180
    yrad = np.pi * y / 180
    dx = earth_rad * np.cos(yrad[1:]) * np.diff(xrad)
    dy = earth_rad * np.diff(yrad)
    ddist = np.sqrt(dx**2 + dy**2)
    dist = np.zeros(len(x))
    dist[1:] = ddist.cumsum() / 1000  # km
    # find the index of zero
    i0, i1, fr = zfun.get_interpolant(np.zeros(1), dist)
    idist0 = i0
    distr = dist.reshape(1, len(dist)).copy()
    dista = np.tile(distr, [N, 1])  # array
    # pack fields to process in dicts
    d2 = dict()
    d2['zbot'] = zbot
    d2['zeta'] = zeta
    d2['lon'] = lon
    d2['lat'] = lat
    d3 = dict()
    d3['zr'] = zr
    d3['sectvar'] = sectvar
    # get vectors describing the (plaid) grid
    xx = lon[1, :]
    yy = lat[:, 1]
    col0, col1, colf = zfun.get_interpolant(x, xx)
    row0, row1, rowf = zfun.get_interpolant(y, yy)
    # and prepare them to do the bilinear interpolation
    colff = 1 - colf
    rowff = 1 - rowf
    # now actually do the interpolation
    # 2-D fields
    v2 = dict()
    for fname in d2.keys():
        fld = d2[fname]
        fldi = (rowff * (colff * fld[row0, col0] + colf * fld[row0, col1]) +
                rowf * (colff * fld[row1, col0] + colf * fld[row1, col1]))
        if type(fldi) == np.ma.core.MaskedArray:
            fldi = fldi.data  # just the data, not the mask
        v2[fname] = fldi
    # 3-D fields
    v3 = dict()
    for fname in d3.keys():
        fld = d3[fname]
        fldi = (rowff *
                (colff * fld[:, row0, col0] + colf * fld[:, row0, col1]) +
                rowf *
                (colff * fld[:, row1, col0] + colf * fld[:, row1, col1]))
        if type(fldi) == np.ma.core.MaskedArray:
            fldid = fldi.data  # just the data, not the mask
            fldid[fldi.mask == True] = np.nan
        v3[fname] = fldid
    v3['dist'] = dista  # distance in km
    # make "full" fields by padding top and bottom
    nana = np.nan * np.ones((N + 2, len(dist)))  # blank array
    v3['zrf'] = nana.copy()
    v3['zrf'][0, :] = v2['zbot']
    v3['zrf'][1:-1, :] = v3['zr']
    v3['zrf'][-1, :] = v2['zeta']
    #
    v3['sectvarf'] = nana.copy()
    v3['sectvarf'][0, :] = v3['sectvar'][0, :]
    v3['sectvarf'][1:-1, :] = v3['sectvar']
    v3['sectvarf'][-1, :] = v3['sectvar'][-1, :]
    #
    v3['distf'] = nana.copy()
    v3['distf'][0, :] = v3['dist'][0, :]
    v3['distf'][1:-1, :] = v3['dist']
    v3['distf'][-1, :] = v3['dist'][-1, :]

    # attempt to skip over nan's
    v3.pop('zr')
    v3.pop('sectvar')
    v3.pop('dist')
    mask3 = ~np.isnan(v3['sectvarf'][:])
    #print(mask3.shape)
    mask2 = mask3[-1, :]
    dist = dist[mask2]
    NC = len(dist)
    NR = mask3.shape[0]
    for k in v2.keys():
        #print('v2 key: ' + k)
        v2[k] = v2[k][mask2]
    for k in v3.keys():
        #print('v3 key: ' + k)
        v3[k] = v3[k][mask3]
        v3[k] = v3[k].reshape((NR, NC))
        #print(v3[k].shape)

    return v2, v3, dist, idist0
示例#15
0
def get_inds(x0, x1, y0, y1, G):
    
    # determine the direction of the section
    # and make sure indices are *increasing*
    if (x0==x1) and (y0!=y1):
        sdir = 'NS'
        a = [y0, y1]; a.sort()
        y0 = a[0]; y1 = a[1]
    elif (x0!=x1) and (y0==y1):
        sdir = 'EW'
        a = [x0, x1]; a.sort()
        x0 = a[0]; x1 = a[1]
    else:
        print('Input points do not form a proper section')
        sdir='bad'
        sys.exit()
    
    # we assume a plaid grid, as usual
    if sdir == 'NS':
        lon = G['lon_u'][0,:].squeeze()
        lat = G['lat_u'][:,0].squeeze()
    elif sdir == 'EW':
        lon = G['lon_v'][0,:].squeeze()
        lat = G['lat_v'][:,0].squeeze()
        
    # we get all 4 i's or j's but only 3 are used
    i0, i1, fr = zfun.get_interpolant(np.array([x0]), lon, extrap_nan=True)
    if np.isnan(fr):
        print('Bad x point')
        sys.exit()
    else:
        ii0 = int(i0)
    i0, i1, fr = zfun.get_interpolant(np.array([x1]), lon, extrap_nan=True)
    if np.isnan(fr):
        print('Bad x point')
        sys.exit()
    else:
        ii1 = int(i1)
    j0, j1, fr = zfun.get_interpolant(np.array([y0]), lat, extrap_nan=True)
    if np.isnan(fr):
        print('Bad y0 point')
        sys.exit()
    else:
        jj0 = int(j0)
    j0, j1, fr = zfun.get_interpolant(np.array([y1]), lat, extrap_nan=True)
    if np.isnan(fr):
        print('Bad y1 point')
        sys.exit()
    else:
        jj1 = int(j1)

    # get mask and trim indices
    # Note: the mask in G is True on water points
    if sdir == 'NS':
        mask = G['mask_u'][jj0:jj1+1, ii0]
        # Note: argmax finds the index of the first True in this case
        igood0 = np.argmax(mask)
        igood1 = np.argmax(mask[::-1])
        # check to see if section is "closed"
        if (igood0==0) | (igood1==0):
            print('Warning: not closed one or both ends')
        # keep only to end of water points, to allow for ocean sections
        Mask = mask[igood0:-igood1]
        # and change the indices to match.  These will be the indices
        # of the start and end points.
        jj0 = jj0 + igood0
        jj1 = jj1 - igood1
        print('  sdir=%2s: jj0=%4d, jj1=%4d, ii0=%4d' % (sdir, jj0, jj1, ii0))
        Lat = lat[jj0:jj1+1]
        Lon = lon[ii0] * np.ones_like(Mask)
    elif sdir == 'EW':
        mask = G['mask_v'][jj0, ii0:ii1+1]
        igood0 = np.argmax(mask)
        igood1 = np.argmax(mask[::-1])
        # check to see if section is "closed"
        if (igood0==0) | (igood1==0):
            print('Warning: not closed one or both ends')
        Mask = mask[igood0:-igood1]
        ii0 = ii0 + igood0
        ii1 = ii1 - igood1
        print('  sdir=%2s: jj0=%4d, ii0=%4d, ii1=%4d' % (sdir, jj0, ii0, ii1))
        Lon = lon[ii0:ii1+1]
        Lat = lat[jj0] * np.ones_like(Mask)
        
    return ii0, ii1, jj0, jj1, sdir, Lon, Lat, Mask
lon_vec = G['lon_rho'][0, :]
lat_vec = G['lat_rho'][:, 0]

# test values for cascadia1
# XBS = [55, 80]  # x-limits
# YBS = [295, 325]  # y-limits

# Bounds of subdomain (rho grid) from Susan Allen 2018_11
lon0 = -125.016452048434
lon1 = -124.494612925929
lat0 = 48.3169463809796
lat1 = 48.7515055163539

# find indices containing these bonds
i0, i1, ifr = zfun.get_interpolant(np.array([lon0, lon1]),
                                   lon_vec,
                                   extrap_nan=True)
j0, j1, jfr = zfun.get_interpolant(np.array([lat0, lat1]),
                                   lat_vec,
                                   extrap_nan=True)
if np.nan in ifr:
    print('Warning: nan in ifr')
if np.nan in jfr:
    print('Warning: nan in jfr')
XBS = [i0[0], i1[1]]
YBS = [j0[0], j1[1]]
print(XBS)
print(YBS)

from datetime import datetime, timedelta
start_time = datetime.now()
示例#17
0
else:
    inname = 'cascadia1_base_lo1_47N124.5W_low_pass_2013.01.02_2015.12.31.p'
  
import pickle
V, v1_list, v2_list, v3_list, G, S, Lon, Lat, sta_name, h = pickle.load( open( indir + inname, 'rb' ) )

#%% messing with z
z_rho, z_w = zfun.get_z(h, 0*h, S)

z_rho_ext = zfun.make_full((-h, z_rho, np.array([0.,])))

zees = np.array([-70, -35, -20, -10, -0])
zcolor = ['k', 'b', 'g', 'orange', 'r']
nz = len(zees)

int_arr = zfun.get_interpolant(zees, z_rho_ext)

v3_list_alt = ['temp', 'salt', 'v']
v3_names = ['Temperature $(^{\circ}C)$', 'Salinity',
            'NS Velocity $(m s^{-1})$']
v3_lims = [(6,19), (34,26), (-.6,.6)]
v3_limdict = dict(zip(v3_list_alt, v3_lims))
v3_namedict = dict(zip(v3_list_alt, v3_names))

v2_list_alt = ['pe_mix_v', 'svstr', 'shflux']
v2_names = ['Energy to Mix $(Jm^{-3})$', 'NS wind Stress (Pa)',
            'Surface Net Heat Flux $(Wm^{-2})$']
v2_lims = [(0,160), (-.15,.25), (-300,300)]
v2_limdict = dict(zip(v2_list_alt, v2_lims))
v2_namedict = dict(zip(v2_list_alt, v2_names))
示例#18
0
def get_cast(gridname, tag, ex_name, date_string, station, lon_str, lat_str):

    # get the dict Ldir
    Ldir = Lfun.Lstart(gridname, tag)
    Ldir['gtagex'] = Ldir['gtag'] + '_' + ex_name
    Ldir['date_string'] = date_string
    Ldir['station'] = station
    Ldir['lon_str'] = lon_str
    Ldir['lat_str'] = lat_str
    
    # make sure the output directory exists
    outdir0 = Ldir['LOo'] + 'cast/'
    Lfun.make_dir(outdir0)
    outdir = outdir0 + Ldir['gtagex'] + '/'
    Lfun.make_dir(outdir)
    
    dt = Ldir['date_string']
    
    #%% function definitions
    
    def get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy):
        dims = ds.variables[vv].dimensions
        if 'eta_rho' in dims:
            grd = 'rho'
        elif 'eta_u' in dims:
            grd = 'u'
        elif 'eta_v' in dims:
            grd = 'v'
        else:
            print('grid error!')
        xi0 = Xi0[grd]; yi0 = Yi0[grd]
        xi1 = Xi1[grd]; yi1 = Yi1[grd]
        aix = Aix[grd]; aiy = Aiy[grd]
    
        xi01 = np.array([xi0, xi1]).flatten()
        yi01 = np.array([yi0, yi1]).flatten()
        return xi01, yi01, aix, aiy
    
    #%% set up for the extraction
        
    # target position
    Lon = np.array(float(Ldir['lon_str']))
    Lat = np.array(float(Ldir['lat_str']))
    
    
    # get grid info
    indir = Ldir['roms'] + 'output/' + Ldir['gtagex'] + '/f' + dt + '/'
    fn = indir + 'ocean_his_0021.nc' # approx. noon local standard time
    
    if os.path.isfile(fn):
        pass
    else:
        print('Not found: ' + fn)
        return
    
    G = zrfun.get_basic_info(fn, only_G=True)
    S = zrfun.get_basic_info(fn, only_S=True)

    lon = G['lon_rho']
    lat = G['lat_rho']
    mask = G['mask_rho']
    xvec = lon[0,:].flatten()
    yvec = lat[:,0].flatten()
    
    i0, i1, frx = zfun.get_interpolant(np.array([float(Ldir['lon_str'])]), xvec)
    j0, j1, fry = zfun.get_interpolant(np.array([float(Ldir['lat_str'])]), yvec)
    i0 = int(i0)
    j0 = int(j0)
    # find indices of nearest good point
    if mask[j0,i0] == 1:
        print('- ' + station + ': point OK')
    elif mask[j0,i0] == 0:
        print('- ' + station + ':point masked')
        i0, j0 = get_ij_good(lon, lat, xvec, yvec, i0, j0, mask)
        new_lon = xvec[i0]
        new_lat = yvec[j0]
        Lon = np.array(new_lon)
        Lat = np.array(new_lat)
   
    # get interpolants for this point
    Xi0 = dict(); Yi0 = dict()
    Xi1 = dict(); Yi1 = dict()
    Aix = dict(); Aiy = dict()
    for grd in ['rho', 'u', 'v']:
        xx = G['lon_' + grd][1,:]
        yy = G['lat_' + grd][:,1]
        xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
        yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
        Xi0[grd] = xi0
        Yi0[grd] = yi0
        Xi1[grd] = xi1
        Yi1[grd] = yi1
        # create little arrays that are used in the actual interpolation
        Aix[grd] = np.array([1-xfr, xfr]).reshape((1,1,2))
        Aiy[grd] = np.array([1-yfr, yfr]).reshape((1,2))
    
    # generating some lists
    v0_list = ['h', 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v']
    v1_list = ['ocean_time']
    v2_list = []
    v3_list_rho = []
    v3_list_w = []
    ds = nc.Dataset(fn)
    for vv in ds.variables:
        vdim = ds.variables[vv].dimensions
        if ( ('ocean_time' in vdim)
            and ('s_rho' not in vdim)
            and ('s_w' not in vdim)
            and (vv != 'ocean_time') ):
            v2_list.append(vv)
        elif ( ('ocean_time' in vdim) and ('s_rho' in vdim) ):
            v3_list_rho.append(vv)
        elif ( ('ocean_time' in vdim) and ('s_w' in vdim) ):
            v3_list_w.append(vv)
    
    V = dict()
    V_long_name = dict()
    V_units = dict()
    v_all_list = v0_list + v1_list + v2_list + v3_list_rho + v3_list_w
    for vv in v_all_list:
        V[vv] = np.array([])
        try:
            V_long_name[vv] = ds.variables[vv].long_name
        except:
            V_long_name[vv] = ''
        try:
            V_units[vv] = ds.variables[vv].units
        except:
            V_units[vv] = ''
    
    # get static variables
    for vv in v0_list:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][yi01, xi01].squeeze()
        V[vv] =   ( aiy*((aix*vvtemp).sum(-1)) ).sum(-1)
    
    ds.close()
    
    #%% extract time-dependent fields
        
    print('-- Working on date: ' + dt)
    sys.stdout.flush()
    
    ds = nc.Dataset(fn)
    for vv in v1_list:
        vtemp = ds.variables[vv][:].squeeze()
        V[vv] = np.append(V[vv], vtemp)
    for vv in v2_list:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, yi01, xi01].squeeze()
        vtemp = ( aiy*((aix*vvtemp).sum(-1)) ).sum(-1)
        V[vv] = np.append(V[vv], vtemp)
    for vv in v3_list_rho:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, :, yi01, xi01].squeeze()
        vtemp = ( aiy*((aix*vvtemp).sum(-1)) ).sum(-1)
        V[vv] = vtemp.reshape((S['N'],1))
    for vv in v3_list_w:
        xi01, yi01, aix, aiy = get_its(ds, vv, Xi0, Yi0, Xi1, Yi1, Aix, Aiy)
        vvtemp = ds.variables[vv][:, :, yi01, xi01].squeeze()
        vtemp = ( aiy*((aix*vvtemp).sum(-1)) ).sum(-1)
        V[vv] = vtemp.reshape((S['N']+1,1))
    
    ds.close()
    
    # create z_rho and z_w (has to be done after we have V['zeta'])
    hh = V['h'][:] * np.ones_like(V['zeta'])
    z_rho, z_w = zrfun.get_z(hh, V['zeta'][:], S)
    V['hh'] = hh
    V_long_name['hh'] = 'bottom depth (positive down) as a vector'
    V_units['hh'] = 'm'
    V['z_rho'] = z_rho
    V_long_name['z_rho'] = 'z on rho points (positive up)'
    V_units['z_rho'] = 'm'
    V['z_w'] = z_w
    V_long_name['z_w'] = 'z on w points (positive up)'
    V_units['z_w'] = 'm'
    v2_list.append('hh')
    v3_list_rho.append('z_rho')
    v3_list_w.append('z_w')
    
    #%% save the output to NetCDF
    out_fn = (outdir +
        Ldir['station'] + '_' +
        Ldir['date_string'] +
        '.nc')
    # get rid of the old version, if it exists
    try:
        os.remove(out_fn)
    except OSError:
        pass # assume error was because the file did not exist
    foo = nc.Dataset(out_fn, 'w')
    
    N = S['N']
    NT = len(V['ocean_time'][:])
    
    foo.createDimension('scalar', 1)
    foo.createDimension('s_rho', N)
    foo.createDimension('s_w', N+1)
    foo.createDimension('ocean_time', NT)
    
    for vv in v0_list:
        v_var = foo.createVariable(vv, float, ('scalar'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v1_list:
        v_var = foo.createVariable(vv, float, ('ocean_time',))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v2_list:
        v_var = foo.createVariable(vv, float, ('ocean_time',))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v3_list_rho:
        v_var = foo.createVariable(vv, float, ('s_rho', 'ocean_time'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
    for vv in v3_list_w:
        v_var = foo.createVariable(vv, float, ('s_w', 'ocean_time'))
        v_var[:] = V[vv][:]
        v_var.long_name = V_long_name[vv]
        v_var.units = V_units[vv]
            
    foo.close()
示例#19
0
Lat = np.array(float(Ldir['lat_str']))

# get grid info
indir = Ldir['roms'] + 'output/' + Ldir['gtagex'] + '/f' + dt + '/'
fn = indir + 'ocean_his_0021.nc' # noon local standart time
G = zrfun.get_basic_info(fn, only_G=True)
S = zrfun.get_basic_info(fn, only_S=True)

# get interpolants for this point
Xi0 = dict(); Yi0 = dict()
Xi1 = dict(); Yi1 = dict()
Aix = dict(); Aiy = dict()
for grd in ['rho', 'u', 'v']:
    xx = G['lon_' + grd][1,:]
    yy = G['lat_' + grd][:,1]
    xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
    yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
    Xi0[grd] = xi0
    Yi0[grd] = yi0
    Xi1[grd] = xi1
    Yi1[grd] = yi1
    # create little arrays that are used in the actual interpolation
    Aix[grd] = np.array([1-xfr, xfr]).reshape((1,1,2))
    Aiy[grd] = np.array([1-yfr, yfr]).reshape((1,2))

# generating some lists
v0_list = ['h', 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v']
v1_list = ['ocean_time']
v2_list = []
v3_list_rho = []
v3_list_w = []
示例#20
0
def get_section(ds, vn, x, y, in_dict):
    
    # PLOT CODE
    from warnings import filterwarnings
    filterwarnings('ignore') # skip a warning message

    # GET DATA
    G, S, T = zrfun.get_basic_info(in_dict['fn'])
    h = G['h']
    zeta = ds['zeta'][:].squeeze()
    zr = zrfun.get_z(h, zeta, S, only_rho=True)

    sectvar = ds[vn][:].squeeze()

    L = G['L']
    M = G['M']
    N = S['N']

    lon = G['lon_rho']
    lat = G['lat_rho']
    mask = G['mask_rho']
    maskr = mask.reshape(1, M, L).copy()
    mask3 = np.tile(maskr, [N, 1, 1])
    zbot = -h # don't need .copy() because of the minus operation

    # make sure fields are masked
    zeta[mask==False] = np.nan
    zbot[mask==False] = np.nan
    sectvar[mask3==False] = np.nan

    # create dist
    earth_rad = zfun.earth_rad(np.mean(lat[:,0])) # m
    xrad = np.pi * x /180
    yrad = np.pi * y / 180
    dx = earth_rad * np.cos(yrad[1:]) * np.diff(xrad)
    dy = earth_rad * np.diff(yrad)
    ddist = np.sqrt(dx**2 + dy**2)
    dist = np.zeros(len(x))
    dist[1:] = ddist.cumsum()/1000 # km
    # find the index of zero
    i0, i1, fr = zfun.get_interpolant(np.zeros(1), dist)
    idist0 = i0
    distr = dist.reshape(1, len(dist)).copy()
    dista = np.tile(distr, [N, 1]) # array
    # pack fields to process in dicts
    d2 = dict()
    d2['zbot'] = zbot
    d2['zeta'] = zeta
    d2['lon'] = lon
    d2['lat'] = lat
    d3 = dict()
    d3['zr'] = zr
    d3['sectvar'] = sectvar
    # get vectors describing the (plaid) grid
    xx = lon[1,:]
    yy = lat[:,1]
    col0, col1, colf = zfun.get_interpolant(x, xx)
    row0, row1, rowf = zfun.get_interpolant(y, yy)
    # and prepare them to do the bilinear interpolation
    colff = 1 - colf
    rowff = 1 - rowf
    # now actually do the interpolation
    # 2-D fields
    v2 = dict()
    for fname in d2.keys():
        fld = d2[fname]
        fldi = (rowff*(colff*fld[row0, col0] + colf*fld[row0, col1])
        + rowf*(colff*fld[row1, col0] + colf*fld[row1, col1]))
        if type(fldi) == np.ma.core.MaskedArray:
            fldi = fldi.data # just the data, not the mask
        v2[fname] = fldi
    # 3-D fields
    v3 = dict()
    for fname in d3.keys():
        fld = d3[fname]
        fldi = (rowff*(colff*fld[:, row0, col0] + colf*fld[:, row0, col1])
        + rowf*(colff*fld[:, row1, col0] + colf*fld[:, row1, col1]))
        if type(fldi) == np.ma.core.MaskedArray:
            fldid = fldi.data # just the data, not the mask
            fldid[fldi.mask == True] = np.nan
        v3[fname] = fldid
    v3['dist'] = dista # distance in km
    # make "full" fields by padding top and bottom
    nana = np.nan * np.ones((N + 2, len(dist))) # blank array
    v3['zrf'] = nana.copy()
    v3['zrf'][0,:] = v2['zbot']
    v3['zrf'][1:-1,:] = v3['zr']
    v3['zrf'][-1,:] = v2['zeta']
    #
    v3['sectvarf'] = nana.copy()
    v3['sectvarf'][0,:] = v3['sectvar'][0,:]
    v3['sectvarf'][1:-1,:] = v3['sectvar']
    v3['sectvarf'][-1,:] = v3['sectvar'][-1,:]
    #
    v3['distf'] = nana.copy()
    v3['distf'][0,:] = v3['dist'][0,:]
    v3['distf'][1:-1,:] = v3['dist']
    v3['distf'][-1,:] = v3['dist'][-1,:]    
    
    # attempt to skip over nan's
    v3.pop('zr')
    v3.pop('sectvar')
    v3.pop('dist')
    mask3 = ~np.isnan(v3['sectvarf'][:])
    #print(mask3.shape)
    mask2 = mask3[-1,:]
    dist = dist[mask2]
    NC = len(dist)
    NR = mask3.shape[0]
    for k in v2.keys():
        #print('v2 key: ' + k)
        v2[k] = v2[k][mask2]
    for k in v3.keys():
        #print('v3 key: ' + k)
        v3[k] = v3[k][mask3]
        v3[k] = v3[k].reshape((NR, NC))
        #print(v3[k].shape)
    
    return v2, v3, dist, idist0
示例#21
0
 x = G['lon_rho']
 y = G['lat_rho']
 mask = G['mask_rho']
 F = ds0[name][:].squeeze()
 if name == 'zeta':
     fld = F.copy()
     fldf = fld.copy()  # initialize the "filled" field
     if tt == 0:
         # fill masked values using nearest neighbor
         xyorig = np.array((X[~fld.mask], Y[~fld.mask])).T
         xynew = np.array((X[fld.mask], Y[fld.mask])).T
         a = cKDTree(xyorig).query(xynew)
         aa_rho = a[1]
         # INTERPOLATION
         # get interpolants
         xi0_rho, xi1_rho, xf_rho = zfun.get_interpolant(
             x, X[0, :], extrap_nan=True)
         yi0_rho, yi1_rho, yf_rho = zfun.get_interpolant(
             y, Y[:, 0], extrap_nan=True)
     # create the filled field
     fldf[fld.mask] = fld[~fld.mask][aa_rho]
     fx = fldf.data
     # do the bi-linear interpolation
     u00 = fx[yi0_rho, xi0_rho]
     u10 = fx[yi1_rho, xi0_rho]
     u01 = fx[yi0_rho, xi1_rho]
     u11 = fx[yi1_rho, xi1_rho]
     fi = (1 - yf_rho) * (
         (1 - xf_rho) * u00 + xf_rho * u01) + yf_rho * (
             (1 - xf_rho) * u10 + xf_rho * u11)
     ff = np.reshape(fi, x.shape)
     fm = np.ma.masked_where(mask == False, ff)
示例#22
0
G, S, T = zrfun.get_basic_info(fn)
ds.close()
# get grid and indices (rho-grid) for extraction domain
# x0 = -122.85
# x1 = -122.6
# y0 = 47.6
# y1 = 47.9
x0 = -122.5
x1 = -122.3
y0 = 47.4
y1 = 47.55
Lon = G['lon_rho']
Lat = G['lat_rho']
Lon_vec = Lon[0,:]
Lat_vec = Lat[:,0]
i0, junk, junk = zfun.get_interpolant(np.array(x0), Lon_vec, extrap_nan=True)
junk, i1, junk = zfun.get_interpolant(np.array(x1), Lon_vec, extrap_nan=True)
j0, junk, junk = zfun.get_interpolant(np.array(y0), Lat_vec, extrap_nan=True)
junk, j1, junk = zfun.get_interpolant(np.array(y1), Lat_vec, extrap_nan=True)
i0 = i0[0]
i1 = i1[0] + 1
j0 = j0[0]
j1 = j1[0] + 1

lon_rho = Lon[j0:j1, i0:i1]
lat_rho = Lat[j0:j1, i0:i1]
h = G['h'][j0:j1, i0:i1]

NR, NC = lon_rho.shape
N = S['N']
             for iz in range(F.shape[0]):
                 # EXTRAPOLATION
                 fld = F[iz, :, :].squeeze()
                 # do the extrapolation using nearest neighbor
                 fldf = fld.copy() # initialize the "filled" field
                 if iz==0:
                     xyorig = np.array((X[~fld.mask],Y[~fld.mask])).T
                     xynew = np.array((X[fld.mask],Y[fld.mask])).T
                     a = cKDTree(xyorig).query(xynew)
                     aa = a[1]
                 fldf[fld.mask] = fld[~fld.mask][aa]
                 fx = fldf.data
                 # INTERPOLATION    
                 if iz==0:
                     # get interpolants
                     xi0, xi1, xf = zfun.get_interpolant(x,X[0,:], extrap_nan=True)
                     yi0, yi1, yf = zfun.get_interpolant(y,Y[:,0], extrap_nan=True)
                 # bi linear interpolation
                 u00 = fx[yi0,xi0]
                 u10 = fx[yi1,xi0]
                 u01 = fx[yi0,xi1]
                 u11 = fx[yi1,xi1]
                 fi = (1-yf)*((1-xf)*u00 + xf*u01) + yf*((1-xf)*u10 + xf*u11)
                 ff = np.reshape(fi, x.shape)
                 fm = np.ma.masked_where(mask==False, ff)
                 ds1[name][tt,iz,:,:] = fm
                 
         print(' -- %s took %0.1f seconds' % (name, time.time() - tt00))
         sys.stdout.flush()
                 
 print('Hour %d took %0.1f seconds' % (tt, time.time() - tt0))
G, S, T = zrfun.get_basic_info(fn)
ds.close()
# get grid and indices (rho-grid) for extraction domain
# x0 = -122.85
# x1 = -122.6
# y0 = 47.6
# y1 = 47.9
x0 = -122.5
x1 = -122.3
y0 = 47.4
y1 = 47.55
Lon = G['lon_rho']
Lat = G['lat_rho']
Lon_vec = Lon[0, :]
Lat_vec = Lat[:, 0]
i0, junk, junk = zfun.get_interpolant(np.array(x0), Lon_vec, extrap_nan=True)
junk, i1, junk = zfun.get_interpolant(np.array(x1), Lon_vec, extrap_nan=True)
j0, junk, junk = zfun.get_interpolant(np.array(y0), Lat_vec, extrap_nan=True)
junk, j1, junk = zfun.get_interpolant(np.array(y1), Lat_vec, extrap_nan=True)
i0 = i0[0]
i1 = i1[0] + 1
j0 = j0[0]
j1 = j1[0] + 1

lon_rho = Lon[j0:j1, i0:i1]
lat_rho = Lat[j0:j1, i0:i1]
h = G['h'][j0:j1, i0:i1]

NR, NC = lon_rho.shape
N = S['N']
示例#25
0
def get_tracks(fn_list, plon0, plat0, pcs0, TR, trim_loc=False):
    """
    This is the main function doing the particle tracking.
    """

    # unpack items needed from TR
    if TR['rev']:
        dir_tag = 'reverse'
    else:
        dir_tag = 'forward'
    surface = not TR['3d']
    turb = TR['turb']
    ndiv = TR['ndiv']
    windage = TR['windage']

    # get basic info
    G = zrfun.get_basic_info(fn_list[0], only_G=True)
    maskr = np.ones_like(G['mask_rho'])  # G['mask_rho'] = True in water
    maskr[G['mask_rho'] == False] = 0  # maskr = 1 in water
    S = zrfun.get_basic_info(fn_list[0], only_S=True)

    # get time vector of history files
    NT = len(fn_list)
    rot = np.nan * np.ones(NT)
    counter = 0
    for fn in fn_list:
        ds = nc4.Dataset(fn)
        rot[counter] = ds.variables['ocean_time'][:].squeeze()
        counter += 1
        ds.close

    # This is an attempt to fix a bug that happens avery couple of weeks,
    # one which I can't reliably reproduce!  In theory fn_list is sorted
    # by the calling function, but maybe ...??
    # Now (2019.11.08) I think this glitch was caused when the carbon code was
    # modifying the history files at the same time as the particle tracking was
    # going.
    rot.sort()

    delta_t = rot[1] - rot[0]  # second between saves

    # this is how we track backwards in time
    if dir_tag == 'reverse':
        delta_t = -delta_t
        fn_list = fn_list[::-1]

    # make vectors to feed to interpolant maker
    R = dict()
    R['rlonr'] = G['lon_rho'][0, :].squeeze()
    R['rlatr'] = G['lat_rho'][:, 0].squeeze()
    R['rlonu'] = G['lon_u'][0, :].squeeze()
    R['rlatu'] = G['lat_u'][:, 0].squeeze()
    R['rlonv'] = G['lon_v'][0, :].squeeze()
    R['rlatv'] = G['lat_v'][:, 0].squeeze()
    R['rcsr'] = S['Cs_r'][:]
    R['rcsw'] = S['Cs_w'][:]

    # these lists are used internally to get other variables as needed
    # (they must all be present in the history files)
    vn_list_vel = ['u', 'v', 'w']
    vn_list_zh = ['zeta', 'h']
    vn_list_wind = ['Uwind', 'Vwind']
    vn_list_other = ['salt', 'temp'] + vn_list_zh + vn_list_vel
    if windage > 0:
        vn_list_other = vn_list_other + vn_list_wind
    # plist_main is what ends up written to output
    plist_main = ['lon', 'lat', 'cs', 'ot', 'z'] + vn_list_other

    if save_dia:
        # diagnostic info
        vn_list_dia = ['hit_sidewall', 'hit_bottom', 'hit_top', 'bad_pcs']

    # Step through times.
    #
    counter = 0
    # rot is a list of all the ocean times (sec) in the current file list(e.g. 25)
    # and pot is a single one of these
    for pot in rot[:-1]:

        # get time indices of surrounding (in time) history files
        it0, it1, frt = zfun.get_interpolant(np.array(pot),
                                             rot,
                                             extrap_nan=False)
        # get Datasets
        ds0 = nc4.Dataset(fn_list[it0[0]])
        ds1 = nc4.Dataset(fn_list[it1[0]])

        if counter == 0:
            if trim_loc == True:
                # remove points on land
                pmask = zfun.interp_scattered_on_plaid(plon0,
                                                       plat0,
                                                       R['rlonr'],
                                                       R['rlatr'],
                                                       maskr,
                                                       exnan=True)
                # keep only points with pmask >= maskr_crit
                pcond = pmask >= maskr_crit
                plon = plon0[pcond]
                plat = plat0[pcond]
                pcs = pcs0[pcond]
            else:
                plon = plon0.copy()
                plat = plat0.copy()
                pcs = pcs0.copy()
            # create result arrays
            NP = len(plon)
            P = dict()
            for vn in plist_main:
                # NOTE: info is packed in a dict P of arrays
                # packed in order (time, particle)
                P[vn] = np.nan * np.ones((NT, NP))

            # initialize diagnostic arrays
            if save_dia:
                for vn in vn_list_dia:
                    P[vn] = np.zeros((NT, NP))  # 0=OK, 1=violation

            # write positions to the results arrays
            P['lon'][it0, :] = plon
            P['lat'][it0, :] = plat
            if surface == True:
                pcs[:] = S['Cs_r'][-1]
            P['cs'][it0, :] = pcs
            P = get_properties(vn_list_other, ds0, it0, P, plon, plat, pcs, R,
                               surface)

        delt = delta_t / ndiv
        # do the particle tracking for a single pair of history files in ndiv steps
        for nd in range(ndiv):

            fr0 = nd / ndiv
            fr1 = (nd + 1) / ndiv
            frmid = (fr0 + fr1) / 2

            # RK4 integration
            V0, ZH0 = get_vel(vn_list_vel, vn_list_zh, ds0, ds1, plon, plat,
                              pcs, R, fr0, surface)
            plon1, plat1, pcs1, dia_dict = update_position(
                R, maskr, V0, ZH0, S, delt / 2, plon, plat, pcs, surface)
            V1, ZH1 = get_vel(vn_list_vel, vn_list_zh, ds0, ds1, plon1, plat1,
                              pcs1, R, frmid, surface)
            plon2, plat2, pcs2, dia_dict = update_position(
                R, maskr, V1, ZH1, S, delt / 2, plon, plat, pcs, surface)
            V2, ZH2 = get_vel(vn_list_vel, vn_list_zh, ds0, ds1, plon2, plat2,
                              pcs2, R, frmid, surface)
            plon3, plat3, pcs3, dia_dict = update_position(
                R, maskr, V2, ZH2, S, delt, plon, plat, pcs, surface)
            V3, ZH3 = get_vel(vn_list_vel, vn_list_zh, ds0, ds1, plon3, plat3,
                              pcs3, R, fr1, surface)
            # add windage, calculated from the middle time
            if (surface == True) and (windage > 0):
                Vwind = get_wind(vn_list_wind, ds0, ds1, plon, plat, pcs, R,
                                 frmid, surface)
                Vwind3 = np.concatenate((windage * Vwind, np.zeros((NP, 1))),
                                        axis=1)
            else:
                Vwind3 = np.zeros((NP, 3))
            plon, plat, pcs, dia_dict = update_position(
                R, maskr, (V0 + 2 * V1 + 2 * V2 + V3) / 6 + Vwind3,
                (ZH0 + 2 * ZH1 + 2 * ZH2 + ZH3) / 6, S, delt, plon, plat, pcs,
                surface)
            if save_dia:
                # diagnostic info for horizontal advection
                P['hit_sidewall'][it1, :] = dia_dict['hit_sidewall']

            # add turbulence to vertical position change (advection already added above)
            if turb == True:
                # pull values of VdAKs and add up to 3-dimensions
                VdAKs = get_dAKs(vn_list_zh, ds0, ds1, plon, plat, pcs, R, S,
                                 frmid, surface)
                # print('VdAKs has %d nans out of %d' % (np.isnan(VdAKs).sum(), len(VdAKs)))
                VdAKs3 = np.concatenate((np.zeros(
                    (NP, 2)), VdAKs[:, np.newaxis]),
                                        axis=1)
                # update position advecting vertically with 1/2 of AKs gradient
                ZH = get_zh(vn_list_zh, ds0, ds1, plon, plat, pcs, R, frmid,
                            surface)
                plon_junk, plat_junk, pcs_half, dia_dict = update_position(
                    R, maskr, VdAKs3 / 2, ZH, S, delt, plon, plat, pcs,
                    surface)
                # get AKs at this height, and thence the turbulent velocity
                Vturb = get_turb(ds0, ds1, VdAKs, delt, plon, plat, pcs_half,
                                 R, frmid, surface)
                # update position vertically for real
                Vturb3 = np.concatenate((np.zeros(
                    (NP, 2)), Vturb[:, np.newaxis]),
                                        axis=1)
                plon_junk, plat_junk, pcs, dia_dict = update_position(
                    R, maskr, Vturb3, ZH, S, delt, plon, plat, pcs, surface)
            if save_dia:
                # diagnostic info for vertical advection
                P['bad_pcs'][it1, :] = dia_dict['bad_pcs']
                P['hit_top'][it1, :] = dia_dict['hit_top']
                P['hit_bottom'][it1, :] = dia_dict['hit_bottom']

        # write positions to the results arrays
        P['lon'][it1, :] = plon
        P['lat'][it1, :] = plat
        if surface == True:
            pcs[:] = S['Cs_r'][-1]
        P['cs'][it1, :] = pcs
        P = get_properties(vn_list_other, ds1, it1, P, plon, plat, pcs, R,
                           surface)

        ds0.close()
        ds1.close()

        counter += 1

    # by doing this the points are going forward in time
    if dir_tag == 'reverse':
        for vn in plist_main:
            P[vn] = P[vn][::-1, :]

    # and save the time vector (seconds in whatever the model reports)
    P['ot'] = rot

    return P
示例#26
0
lon_vec = G['lon_rho'][0,:]
lat_vec = G['lat_rho'][:,0]

# test values for cascadia1
# XBS = [55, 80]  # x-limits
# YBS = [295, 325]  # y-limits

# Bounds of subdomain (rho grid) from Susan Allen 2018_11
lon0 = -125.016452048434
lon1 = -124.494612925929
lat0 = 48.3169463809796
lat1 = 48.7515055163539

# find indices containing these bonds
i0, i1, ifr = zfun.get_interpolant(np.array([lon0,lon1]), lon_vec, extrap_nan=True)
j0, j1, jfr = zfun.get_interpolant(np.array([lat0,lat1]), lat_vec, extrap_nan=True)
if np.nan in ifr:
    print('Warning: nan in ifr')
if np.nan in jfr:
    print('Warning: nan in jfr')
XBS = [i0[0], i1[1]]
YBS = [j0[0], j1[1]]
print(XBS)
print(YBS)

from datetime import datetime, timedelta
start_time = datetime.now()

# the output file name
out_fn = (Ldir['roms'] + 'output/' + Ldir['gtagex'] +
示例#27
0
Lon = np.array(float(Ldir['lon_str']))
Lat = np.array(float(Ldir['lat_str']))

# get grid info
fn = fn_list[0]
G = zrfun.get_basic_info(fn, only_G=True)
S = zrfun.get_basic_info(fn, only_S=True)

# get interpolants for this point
Xi0 = dict(); Yi0 = dict()
Xi1 = dict(); Yi1 = dict()
Aix = dict(); Aiy = dict()
for grd in ['rho', 'u', 'v']:
    xx = G['lon_' + grd][1,:]
    yy = G['lat_' + grd][:,1]
    xi0, xi1, xfr = zfun.get_interpolant(Lon, xx, extrap_nan=True)
    yi0, yi1, yfr = zfun.get_interpolant(Lat, yy, extrap_nan=True)
    Xi0[grd] = xi0
    Yi0[grd] = yi0
    Xi1[grd] = xi1
    Yi1[grd] = yi1
    # create little arrays that are used in the actual interpolation
    Aix[grd] = np.array([1-xfr, xfr]).reshape((1,1,2))
    Aiy[grd] = np.array([1-yfr, yfr]).reshape((1,2))

# generating some lists
v0_list = ['h', 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v']
v1_list = ['ocean_time']
v2_list = []
v3_list_rho = []
v3_list_w = []
示例#28
0
Lon = np.array(float(Ldir['lon_str']))
Lat = np.array(float(Ldir['lat_str']))

# get grid info
indir = Ldir['roms'] + 'output/' + Ldir['gtagex'] + '/f' + date_list[0] + '/'
fn = indir + 'ocean_his_0002.nc'
[G, S] = zfun.get_basic_info(fn, getS=True, getT=False)

# get interpolants for this point
Xi0 = dict(); Yi0 = dict()
Xi1 = dict(); Yi1 = dict()
Aix = dict(); Aiy = dict()
for grd in ['rho', 'u', 'v']:
    xx = G['lon_' + grd][1,:]
    yy = G['lat_' + grd][:,1]
    xi0, xi1, xfr = zfun.get_interpolant(Lon, xx)
    yi0, yi1, yfr = zfun.get_interpolant(Lat, yy)
    Xi0[grd] = xi0
    Yi0[grd] = yi0
    Xi1[grd] = xi1
    Yi1[grd] = yi1
    # create little arrays that are used in the actual interpolation
    Aix[grd] = np.array([1-xfr, xfr]).reshape((1,1,2))
    Aiy[grd] = np.array([1-yfr, yfr]).reshape((1,2))

# generating some lists
v0_list = ['h', 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v']
v1_list = ['ocean_time']
v2_list = []
v3_list_rho = []
v3_list_w = []
示例#29
0
def get_inds(x0, x1, y0, y1, G, verbose=False):

    # determine the direction of the section
    # and make sure indices are *increasing*
    if (x0 == x1) and (y0 != y1):
        sdir = 'NS'
        a = [y0, y1]
        a.sort()
        y0 = a[0]
        y1 = a[1]
    elif (x0 != x1) and (y0 == y1):
        sdir = 'EW'
        a = [x0, x1]
        a.sort()
        x0 = a[0]
        x1 = a[1]
    else:
        print('Input points do not form a proper section')
        sdir = 'bad'
        sys.exit()

    # we assume a plaid grid, as usual
    if sdir == 'NS':
        lon = G['lon_u'][0, :].squeeze()
        lat = G['lat_u'][:, 0].squeeze()
    elif sdir == 'EW':
        lon = G['lon_v'][0, :].squeeze()
        lat = G['lat_v'][:, 0].squeeze()

    # we get all 4 i's or j's but only 3 are used
    i0, i1, fr = zfun.get_interpolant(np.array([x0]), lon, extrap_nan=True)
    if np.isnan(fr):
        print('Bad x point')
        sys.exit()
    else:
        ii0 = int(i0)
    i0, i1, fr = zfun.get_interpolant(np.array([x1]), lon, extrap_nan=True)
    if np.isnan(fr):
        print('Bad x point')
        sys.exit()
    else:
        ii1 = int(i1)
    j0, j1, fr = zfun.get_interpolant(np.array([y0]), lat, extrap_nan=True)
    if np.isnan(fr):
        print('Bad y0 point')
        sys.exit()
    else:
        jj0 = int(j0)
    j0, j1, fr = zfun.get_interpolant(np.array([y1]), lat, extrap_nan=True)
    if np.isnan(fr):
        print('Bad y1 point')
        sys.exit()
    else:
        jj1 = int(j1)

    # get mask and trim indices
    # Note: the mask in G is True on water points
    if sdir == 'NS':
        mask = G['mask_u'][jj0:jj1 + 1, ii0]
        # Note: argmax finds the index of the first True in this case
        igood0 = np.argmax(mask)
        igood1 = np.argmax(mask[::-1])
        # check to see if section is "closed"
        if (igood0 == 0) | (igood1 == 0):
            print('Warning: not closed one or both ends')
        # keep only to end of water points, to allow for ocean sections
        Mask = mask[igood0:-igood1]
        # and change the indices to match.  These will be the indices
        # of the start and end points.
        jj0 = jj0 + igood0
        jj1 = jj1 - igood1
        if verbose:
            print('  sdir=%2s: jj0=%4d, jj1=%4d, ii0=%4d' %
                  (sdir, jj0, jj1, ii0))
        Lat = lat[jj0:jj1 + 1]
        Lon = lon[ii0] * np.ones_like(Mask)
    elif sdir == 'EW':
        mask = G['mask_v'][jj0, ii0:ii1 + 1]
        igood0 = np.argmax(mask)
        igood1 = np.argmax(mask[::-1])
        # check to see if section is "closed"
        if (igood0 == 0) | (igood1 == 0):
            print('Warning: not closed one or both ends')
        Mask = mask[igood0:-igood1]
        ii0 = ii0 + igood0
        ii1 = ii1 - igood1
        if verbose:
            print('  sdir=%2s: jj0=%4d, ii0=%4d, ii1=%4d' %
                  (sdir, jj0, ii0, ii1))
        Lon = lon[ii0:ii1 + 1]
        Lat = lat[jj0] * np.ones_like(Mask)

    return ii0, ii1, jj0, jj1, sdir, Lon, Lat, Mask
示例#30
0
def get_extrapolated(in_fn, L, M, N, X, Y, lon, lat, z, Ldir, add_CTD=False, fix_NSoG=False):
    b = pickle.load(open(in_fn, 'rb'))
    vn_list = list(b.keys())    
    # check that things are the expected shape
    def check_coords(shape_tuple, arr_shape):
        if arr_shape != shape_tuple:
            print('WARNING: array shape mismatch')
    for vn in vn_list:
        if vn == 'dt':
            pass
        elif vn == 'ssh':
            check_coords((M, L), b[vn].shape)
        else:
            check_coords((N, M, L), b[vn].shape)    
    # creat output array and add dt to it.
    vn_list.remove('dt')
    V = dict()
    for vn in vn_list:
        V[vn] = np.nan + np.ones(b[vn].shape)
    V['dt'] = b['dt']    
    # extrapolate ssh
    vn = 'ssh'
    v = b[vn]
    if fix_NSoG:
        print(' ^^ Fixing NSoG ^^')
        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        # (a) Mouth of Strait of Juan de Fuca
        i0, i1, fr = zfun.get_interpolant(np.array([-124.7, -124.5]), lon, extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([48.4, 48.6]), lat, extrap_nan=False)
        zeta_jdf = v[j0[0]:j1[1]+1, i0[0]:i1[1]+1]
        #
        # (b) Northern Strait of Georgia
        i0, i1, fr = zfun.get_interpolant(np.array([-125.5, -124.5]), lon, extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([50.15, 50.45]), lat, extrap_nan=False)
        v[j0[0]:j1[1]+1, i0[0]:i1[1]+1] = np.nanmean(zeta_jdf) + 0.1
        # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    vv = extrap_nearest_to_masked(X, Y, v)
    V[vn] = vv
    vn_list.remove('ssh')    
    # extrapolate 3D fields
    for vn in vn_list:
        v = b[vn]
        if vn == 't3d':
            v0 = np.nanmin(v)
        elif vn == 's3d':
            v0 = np.nanmax(v)
        if vn in ['t3d', 's3d']:
            print(' -- extrapolating ' + vn)
            if add_CTD==False:
                for k in range(N):
                    fld = v[k, :, :]
                    fldf = extrap_nearest_to_masked(X, Y, fld, fld0=v0)
                    V[vn][k, :, :] = fldf
            elif add_CTD==True:
                print(vn + ' Adding CTD data before extrapolating')
                Cast_dict, sta_df = Ofun_CTD.get_casts(Ldir)
                for k in range(N):
                    fld = v[k, :, :]
                    zz = z[k]
                    xyorig, fldorig = Ofun_CTD.get_orig(Cast_dict, sta_df,
                        X, Y, fld, lon, lat, zz, vn)
                    fldf = Ofun_CTD.extrap_nearest_to_masked_CTD(X,Y,fld,
                        xyorig=xyorig,fldorig=fldorig,fld0=v0)
                    V[vn][k, :, :] = fldf
        elif vn in ['u3d', 'v3d']:
            print(' -- extrapolating ' + vn)
            vv = v.copy()
            vv = np.ma.masked_where(np.isnan(vv), vv)
            vv[vv.mask] = 0
            V[vn] = vv.data
    # Create ubar and vbar.
    # Note: this is slightly imperfect because the z levels are at the same
    # position as the velocity levels.
    dz = np.nan * np.ones((N, 1, 1))
    dz[1:, 0, 0]= np.diff(z)
    dz[0, 0, 0] = dz[1, 0, 0]
    
    # account for the fact that the new hycom fields do not show up masked
    u3d = np.ma.masked_where(np.isnan(b['u3d']),b['u3d'])
    v3d = np.ma.masked_where(np.isnan(b['v3d']),b['v3d'])
    dz3 = dz * np.ones_like(u3d) # make dz a masked array
    b['ubar'] = np.sum(u3d*dz3, axis=0) / np.sum(dz3, axis=0)
    b['vbar'] = np.sum(v3d*dz3, axis=0) / np.sum(dz3, axis=0)
    
    for vn in ['ubar', 'vbar']:
        v = b[vn]
        vv = v.copy()
        vv = np.ma.masked_where(np.isnan(vv), vv)
        vv[vv.mask] = 0
        V[vn] = vv.data  
    # calculate potential temperature
    press_db = -z.reshape((N,1,1))
    V['theta'] = seawater.ptmp(V['s3d'], V['t3d'], press_db)    
    return V
示例#31
0
def get_tracks(fn_list,
               plon0,
               plat0,
               pcs0,
               dir_tag,
               method,
               surface,
               turb,
               ndiv,
               windage,
               bound='stop',
               dep_range=None):
    '''
    Create tracks of particles starting from the locations at (plon0, plat0, pcs0)
    
    Inputs:
    fn_list - array of dataset file locations
    plon0/plat0/pcs0 - arrays of position (longitude/latitude/proportion of total depth)
    dir_tag - string determining direction of tracking ('forward' or 'reverse')
    method - string determining interpolation level ('rk2' or 'rk4')
    surface - Boolean, True traps particles to the surface
    turb - Boolean, True adds random vertical walk
    ndiv - int determining number of divisions to make between saves for the integration
    windage - float (0 to 1) determining proportion of velocity to add from surface wind
    bound - string determing boundary velocity conditions 
        'stop' (default) prevents particles from moving when a gridcell contains land
        'reflect' causes particles to move away from gridcells that contain land
    dep_range - tuple containing arrays (minimum depth, maximum depth) for all particles
    
    Outputs:
    P - dictionary containing variables in plist_main
        each variable has rows of time and columns of particles
        except the array 'ot', seconds since 1970
    G - dictionary containing grid and bathymetry information
    S - dictionary containing water surface information
    '''

    # Bartos - removed on land particle removal, so set these to plon, not plonA
    plon = plon0.copy()
    plat = plat0.copy()
    pcs = pcs0.copy()

    # get basic info
    G = zrfun.get_basic_info(fn_list[0], only_G=True)
    S = zrfun.get_basic_info(fn_list[0], only_S=True)

    # get time vector of history files
    NT = len(fn_list)
    rot = np.nan * np.ones(NT)
    counter = 0
    for fn in fn_list:
        ds = nc4.Dataset(fn)
        rot[counter] = ds.variables['ocean_time'][:].squeeze()
        counter += 1
        ds.close

    delta_t = rot[1] - rot[0]  # seconds between saves

    # this is how we track backwards in time
    if dir_tag == 'reverse':
        delta_t = -delta_t
        fn_list = fn_list[::-1]

    # make vectors to feed to interpolant maker
    R = dict()
    R['rlonr'] = G['lon_rho'][0, :].squeeze()
    R['rlatr'] = G['lat_rho'][:, 0].squeeze()
    R['rlonu'] = G['lon_u'][0, :].squeeze()
    R['rlatu'] = G['lat_u'][:, 0].squeeze()
    R['rlonv'] = G['lon_v'][0, :].squeeze()
    R['rlatv'] = G['lat_v'][:, 0].squeeze()
    R['rcsr'] = S['Cs_r'][:]
    R['rcsw'] = S['Cs_w'][:]

    # these lists are used internally to get other variables as needed
    vn_list_vel = ['u', 'v', 'w']
    vn_list_zh = ['zeta', 'h']
    vn_list_wind = ['Uwind', 'Vwind']
    vn_list_other = ['salt', 'temp', 'zeta', 'h', 'u', 'v', 'w']

    # Step through times.
    # Bartos - removed on land particle removal
    counter = 0
    nrot = len(rot)
    for pot in rot[:-1]:

        #        if np.mod(counter,24) == 0:
        #            print(' - time %d out of %d' % (counter, nrot))
        #            sys.stdout.flush()

        # get time indices
        it0, it1, frt = zfun.get_interpolant(np.array(pot),
                                             rot,
                                             extrap_nan=False)

        # get the velocity zeta, and h at all points
        ds0 = nc4.Dataset(fn_list[it0[0]])
        ds1 = nc4.Dataset(fn_list[it1[0]])

        if counter == 0:

            # create result arrays
            NP = len(plon)
            P = dict()
            # plist main is what ends up written to output
            plist_main = [
                'lon', 'lat', 'cs', 'ot', 'z', 'zeta', 'zbot', 'salt', 'temp',
                'u', 'v', 'w', 'Uwind', 'Vwind', 'h'
            ]
            for vn in plist_main:
                P[vn] = np.nan * np.ones((NT, NP))

            # write positions to the results arrays
            P['lon'][it0, :] = plon
            P['lat'][it0, :] = plat
            if surface == True:
                pcs[:] = S['Cs_r'][-1]
            P['cs'][it0, :] = pcs

            P = get_properties(vn_list_other, ds0, it0, P, plon, plat, pcs, R,
                               surface)

        delt = delta_t / ndiv

        for nd in range(ndiv):

            fr0 = nd / ndiv
            fr1 = (nd + 1) / ndiv
            frmid = (fr0 + fr1) / 2

            if method == 'rk4':
                # RK4 integration

                V0, ZH0 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon,
                                  plat,
                                  pcs,
                                  R,
                                  fr0,
                                  surface,
                                  bound=bound)

                plon1, plat1, pcs1 = update_position(V0, ZH0, S, delt / 2,
                                                     plon, plat, pcs, surface)
                V1, ZH1 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon1,
                                  plat1,
                                  pcs1,
                                  R,
                                  frmid,
                                  surface,
                                  bound=bound)

                plon2, plat2, pcs2 = update_position(V1, ZH1, S, delt / 2,
                                                     plon, plat, pcs, surface)
                V2, ZH2 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon2,
                                  plat2,
                                  pcs2,
                                  R,
                                  frmid,
                                  surface,
                                  bound=bound)

                plon3, plat3, pcs3 = update_position(V2, ZH2, S, delt, plon,
                                                     plat, pcs, surface)
                V3, ZH3 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon3,
                                  plat3,
                                  pcs3,
                                  R,
                                  fr1,
                                  surface,
                                  bound=bound)

                # add windage, calculated from the middle time
                if (surface == True) and (windage > 0):
                    Vwind = get_wind(vn_list_wind, ds0, ds1, plon, plat, pcs,
                                     R, frmid, surface)
                    Vwind3 = np.concatenate((windage * Vwind, np.zeros(
                        (NP, 1))),
                                            axis=1)
                else:
                    Vwind3 = np.zeros((NP, 3))

                plon, plat, pcs = update_position(
                    (V0 + 2 * V1 + 2 * V2 + V3) / 6 + Vwind3,
                    (ZH0 + 2 * ZH1 + 2 * ZH2 + ZH3) / 6, S, delt, plon, plat,
                    pcs, surface)

                # Bartos - begin turbulence edit

                # add turbulence in two distinct timesteps
                if turb == True:
                    # pull values of VdAKs and add up to 3-dimensions
                    VdAKs = get_dAKs(vn_list_zh, ds0, ds1, plon, plat, pcs, R,
                                     S, frmid, surface)
                    VdAKs3 = np.concatenate((np.zeros(
                        (NP, 2)), VdAKs[:, np.newaxis]),
                                            axis=1)

                    # update position with 1/2 of AKs gradient
                    plon, plat, pcs = update_position(
                        VdAKs3 / 2, (ZH0 + 2 * ZH1 + 2 * ZH2 + ZH3) / 6, S,
                        delt, plon, plat, pcs, surface)

                    # update position with rest of turbulence
                    Vturb = get_turb(ds0, ds1, VdAKs, delta_t, plon, plat, pcs,
                                     R, frmid, surface)
                    Vturb3 = np.concatenate((np.zeros(
                        (NP, 2)), Vturb[:, np.newaxis]),
                                            axis=1)

                    plon, plat, pcs = update_position(
                        Vturb3, (ZH0 + 2 * ZH1 + 2 * ZH2 + ZH3) / 6, S, delt,
                        plon, plat, pcs, surface)

# Bartos - end edit

            elif method == 'rk2':
                # RK2 integration
                V0, ZH0 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon,
                                  plat,
                                  pcs,
                                  R,
                                  fr0,
                                  surface,
                                  bound=bound)

                plon1, plat1, pcs1 = update_position(V0, ZH0, S, delt / 2,
                                                     plon, plat, pcs, surface)
                V1, ZH1 = get_vel(vn_list_vel,
                                  vn_list_zh,
                                  ds0,
                                  ds1,
                                  plon1,
                                  plat1,
                                  pcs1,
                                  R,
                                  frmid,
                                  surface,
                                  bound=bound)

                # add windage, calculated from the middle time
                if (surface == True) and (windage > 0):
                    Vwind = get_wind(vn_list_wind, ds0, ds1, plon, plat, pcs,
                                     R, frmid, surface)
                    Vwind3 = np.concatenate((windage * Vwind, np.zeros(
                        (NP, 1))),
                                            axis=1)
                else:
                    Vwind3 = np.zeros((NP, 3))

                plon, plat, pcs = update_position(V1 + Vwind3, ZH1, S, delt,
                                                  plon, plat, pcs, surface)

                # Bartos - begin turbulence edit

                # add turbulence in two distinct timesteps
                if turb == True:
                    # pull values of VdAKs and add up to 3-dimensions
                    VdAKs = get_dAKs(vn_list_zh, ds0, ds1, plon, plat, pcs, R,
                                     S, frmid, surface)
                    VdAKs3 = np.concatenate((np.zeros(
                        (NP, 2)), VdAKs[:, np.newaxis]),
                                            axis=1)

                    # update position with 1/2 of AKs gradient
                    plon, plat, pcs = update_position(VdAKs3 / 2, ZH1, S, delt,
                                                      plon, plat, pcs, surface)

                    # update position with rest of turbulence
                    Vturb = get_turb(ds0, ds1, VdAKs, delta_t, plon, plat, pcs,
                                     R, frmid, surface)
                    Vturb3 = np.concatenate((np.zeros(
                        (NP, 2)), Vturb[:, np.newaxis]),
                                            axis=1)

                    plon, plat, pcs = update_position(Vturb3, ZH1, S, delt,
                                                      plon, plat, pcs, surface)

        # write positions to the results arrays
        P['lon'][it1, :] = plon
        P['lat'][it1, :] = plat
        if surface == True:
            pcs[:] = S['Cs_r'][-1]
        P['cs'][it1, :] = pcs
        P = get_properties(vn_list_other, ds1, it1, P, plon, plat, pcs, R,
                           surface)

        # Bartos - begin maximum and minimum depth edit

        if dep_range != None:
            dep_max = dep_range[1]
            # mask of depths below dep_max
            dep_mask = P['z'][it1, :] < dep_max
            dep_mask = dep_mask.squeeze()
            # total depth
            dep_tot = P['zeta'][it1, dep_mask] + P['h'][it1, dep_mask]
            # replace masked depths with dep_max
            P['z'][it1, dep_mask] = dep_max[dep_mask]
            P['cs'][it1, dep_mask] = dep_max[dep_mask] / dep_tot
            pcs[dep_mask] = dep_max[dep_mask] / dep_tot

            dep_min = dep_range[0]
            # mask of depths above dep_min
            dep_mask = P['z'][it1, :] > dep_min
            dep_mask = dep_mask.squeeze()
            # total depth
            dep_tot = P['zeta'][it1, dep_mask] + P['h'][it1, dep_mask]
            # replace masked depths with dep_min
            P['z'][it1, dep_mask] = dep_min[dep_mask]
            P['cs'][it1, dep_mask] = dep_min[dep_mask] / dep_tot
            pcs[dep_mask] = dep_max[dep_mask] / dep_tot


# Bartos - end edits

        ds0.close()
        ds1.close()

        counter += 1

    # by doing this the points are going forward in time
    if dir_tag == 'reverse':
        for vn in plist_main:
            P[vn] = P[vn][::-1, :]

    # and save the time vector (seconds in whatever the model reports)
    P['ot'] = rot

    return P, G, S
示例#32
0
lon = dsr['lon'][:]
lat = dsr['lat'][:]
ot_vec = dsr['ot'][:]
days = (ot_vec - ot_vec[0]) / 86400
dt_list = [Lfun.modtime_to_datetime(ot) for ot in ot_vec]

NT, NP = lon.shape

day_list = []
frac_list = []
for tt in range(0, NT, 96):
    x = lon[tt, :]
    y = lat[tt, :]

    #tt1 = time()
    i0, i1, frx = zfun.get_interpolant(x, xvec)
    j0, j1, fry = zfun.get_interpolant(y, yvec)
    ii = i0.data + np.round(frx.data)
    jj = j0.data + np.round(fry.data)
    iii = ii.astype(int)
    jjj = jj.astype(int)
    this_ji_list = list(zip(jjj, iii))
    #print('Get ji list %0.3f seconds' % (time()-tt1))

    #tt3 = time()
    this_ji_cvec = jjj + iii * 1j
    isin_vec = np.isin(this_ji_cvec, ji_cvec)
    incount = isin_vec.sum()
    #print('Search ji list alt %0.3f seconds' % (time()-tt3))

    day_list.append(days[tt])
示例#33
0
                for iz in range(F.shape[0]):
                    # EXTRAPOLATION
                    fld = F[iz, :, :].squeeze()
                    # do the extrapolation using nearest neighbor
                    fldf = fld.copy() # initialize the "filled" field
                    if iz==0:
                        xyorig = np.array((X[~fld.mask],Y[~fld.mask])).T
                        xynew = np.array((X[fld.mask],Y[fld.mask])).T
                        a = cKDTree(xyorig).query(xynew)
                        aa = a[1]
                    fldf[fld.mask] = fld[~fld.mask][aa]
                    fx = fldf.data
                    # INTERPOLATION    
                    if iz==0:
                        # get interpolants
                        xi0, xi1, xf = zfun.get_interpolant(x,X[0,:], extrap_nan=True)
                        yi0, yi1, yf = zfun.get_interpolant(y,Y[:,0], extrap_nan=True)
                    # bi linear interpolation
                    u00 = fx[yi0,xi0]
                    u10 = fx[yi1,xi0]
                    u01 = fx[yi0,xi1]
                    u11 = fx[yi1,xi1]
                    fi = (1-yf)*((1-xf)*u00 + xf*u01) + yf*((1-xf)*u10 + xf*u11)
                    ff = np.reshape(fi, x.shape)
                    fm = np.ma.masked_where(mask==False, ff)
                    ds1[name][tt,iz,:,:] = fm
    print('Hour %d took %0.1f seconds' % (tt, time.time() - tt0))
    tt += 1
    ds0.close()
ds1.close()
  
示例#34
0
        # get coordinates
        indir = indir0 + ocn + '/Data/'
        coord_dict = pickle.load(open(indir + 'coord_dict.p', 'rb'))
        lon = coord_dict['lon']
        lat = coord_dict['lat']

        # get fields
        # note that when we use the "xfh" fields there should be no nans
        xfh = pickle.load(open(indir + '/xfh' + mds + '.p', 'rb'))
        zeta = xfh['ssh']

        # get indices around certain regions, and their data
        #
        # (a) Mouth of Strait of Juan de Fuca
        i0, i1, fr = zfun.get_interpolant(np.array([-124.7, -124.5]),
                                          lon,
                                          extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([48.4, 48.6]),
                                          lat,
                                          extrap_nan=False)
        zeta_jdf = zeta[j0[0]:j1[1] + 1, i0[0]:i1[1] + 1]
        #
        # (b) Northern Strait of Georgia
        i0, i1, fr = zfun.get_interpolant(np.array([-125.5, -124.5]),
                                          lon,
                                          extrap_nan=False)
        j0, j1, fr = zfun.get_interpolant(np.array([50.25, 50.45]),
                                          lat,
                                          extrap_nan=False)
        zeta_sog = zeta[j0[0]:j1[1] + 1, i0[0]:i1[1] + 1]
        #