def get_ij_good(lon, lat, xvec, yvec, i0, j0, mask): # find the nearest unmasked point # # starting point lon0 = lon[j0,i0] lat0 = lat[j0,i0] pad = 5 # how far to look (points) # indices of box to search over imax = len(xvec)-1 jmax = len(yvec)-1 I = np.arange(i0-pad, i0+pad) J = np.arange(j0-pad,j0+pad) # account for out-of-range points if I[0] < 0: I = I - I[0] if I[-1] > imax: I = I - (I[-1] - imax) if J[0] < 0: J = J - J[0] if J[-1] > jmax: J = J - (J[-1] - jmax) ii, jj = np.meshgrid(I, J) # sub arrays llon = lon[jj,ii] llat = lat[jj,ii] xxx, yyy = zfun.ll2xy(llon, llat, lon0, lat0) ddd = np.sqrt(xxx**2 + yyy**2) # distance from original point mmask = mask[jj,ii] mm = mmask==1 # Boolean array of good points dddm = ddd[mm] # vector of good distances # indices of best point igood = ii[mm][dddm==dddm.min()][0] jgood = jj[mm][dddm==dddm.min()][0] # return igood, jgood
def get_ij_good(lon, lat, xvec, yvec, i0, j0, mask): # find the nearest unmasked point # # starting point lon0 = lon[j0, i0] lat0 = lat[j0, i0] pad = 5 # how far to look (points) # indices of box to search over imax = len(xvec) - 1 jmax = len(yvec) - 1 I = np.arange(i0 - pad, i0 + pad) J = np.arange(j0 - pad, j0 + pad) # account for out-of-range points if I[0] < 0: I = I - I[0] if I[-1] > imax: I = I - (I[-1] - imax) if J[0] < 0: J = J - J[0] if J[-1] > jmax: J = J - (J[-1] - jmax) ii, jj = np.meshgrid(I, J) # sub arrays llon = lon[jj, ii] llat = lat[jj, ii] xxx, yyy = zfun.ll2xy(llon, llat, lon0, lat0) ddd = np.sqrt(xxx**2 + yyy**2) # distance from original point mmask = mask[jj, ii] mm = mmask == 1 # Boolean array of good points dddm = ddd[mm] # vector of good distances # indices of best point igood = ii[mm][dddm == dddm.min()][0] jgood = jj[mm][dddm == dddm.min()][0] # return igood, jgood
def make_dist(x, y): NS = len(x) xs = np.zeros(NS) ys = np.zeros(NS) xs, ys = zfun.ll2xy(x, y, x[0], y[0]) dx = np.diff(xs) dy = np.diff(ys) dd = (dx**2 + dy**2)**.5 # not clear why np.sqrt throws an error dist = np.zeros(NS) dist[1:] = np.cumsum(dd / 1000) # convert m to km return dist
def get_coords(in_dir): # get coordinate fields and sizes coord_dict = pickle.load(open(in_dir + 'coord_dict.p', 'rb')) lon = coord_dict['lon'] lat = coord_dict['lat'] z = coord_dict['z'] L = len(lon) M = len(lat) N = len(z) # Create arrays of distance from the center (m) so that the # nearest neighbor extrapolation is based on physical distance Lon, Lat = np.meshgrid(lon,lat) X, Y = zfun.ll2xy(Lon, Lat, lon.mean(), lat.mean()) return (lon, lat, z, L, M, N, X, Y)
def get_coords(in_dir): # get coordinate fields and sizes coord_dict = pickle.load(open(in_dir + 'coord_dict.p', 'rb')) lon = coord_dict['lon'] lat = coord_dict['lat'] z = coord_dict['z'] L = len(lon) M = len(lat) N = len(z) # Create arrays of distance from the center (m) so that the # nearest neighbor extrapolation is based on physical distance Lon, Lat = np.meshgrid(lon, lat) X, Y = zfun.ll2xy(Lon, Lat, lon.mean(), lat.mean()) return (lon, lat, z, L, M, N, X, Y)
plist_len = len(particlelist) N = 80 for particlechoice in particlelist: print('Particle %i' % particlechoice) tlon = tlon1[:, particlechoice] tlat = tlat1[:, particlechoice] tz = tz1[:, particlechoice] tu = tu1[:, particlechoice] tv = tv1[:, particlechoice] if particlechoice == particlelist[0]: pdict = dict() dist_from_mouth = np.zeros(NT) for tt in range(NT): x, y = zfun.ll2xy(tlon[tt], tlat[tt], reflon, reflat) dist_from_mouth[tt] = np.sqrt(x**2 + y**2) dist_from_mouth[tt] = np.sign(tlon[tt]) * np.abs(dist_from_mouth[tt]) #initialize dicts Du = dict() Dv = dict() #to build a list of momentum terms by position, go through each time step... print('reading in momentum budgets along track...') for i in range(NT): #open the relevant model output... ds_dia = nc.Dataset(dia_list[i]) ds_avg = nc.Dataset(avg_list[i]) zeta = ds_avg['zeta'][:]
#calcualte direction based on coriolis indx_u = zfun.find_nearest_ind(lonu[0, :], p['tlon'][tt]) indy_u = zfun.find_nearest_ind(latu[:, 0], p['tlat'][tt]) indz_u = zfun.find_nearest_ind( zr[:, indy_u, indx_u + 1], p['tz'][tt]) #indx+1 because zr is on rho grid indx_v = zfun.find_nearest_ind(lonv[0, :], p['tlon'][tt]) indy_v = zfun.find_nearest_ind(latv[:, 0], p['tlat'][tt]) indz_v = zfun.find_nearest_ind( zr[:, indy_v + 1, indx_v], p['tz'][tt]) #indy+1 because zr is on rho grid #build dist_from_mouth x, y = zfun.ll2xy(p['tlon'][tt], p['tlat'][tt], reflon, reflat) p['dist_from_mouth'][tt] = np.sqrt(x**2 + y**2) p['dist_from_mouth'][tt] = np.sign(p['tlon'][tt]) * np.abs( p['dist_from_mouth'][tt]) #build hab indx_r = zfun.find_nearest_ind(lonr[0, :], p['tlon'][tt]) indy_r = zfun.find_nearest_ind(latr[:, 0], p['tlat'][tt]) p['hab'][tt] = h[indy_r, indx_r] + p['tz'][ tt] #h is (+), tz is (-), and |h|>|tz| so adding them should produce a (+) difference #calculate du/dt h0_u = ds_h0['u'][0, indz_u, indy_u, indx_u] h1_u = ds_h1['u'][0, indz_u, indy_u, indx_u] dudt = (h1_u - h0_u) / dt
def get_orig(Cast_dict, sta_df, X, Y, fld, lon, lat, zz, vn): verbose = False # make vectors or 1- or 2-column arrays (*) of the good points to feed to cKDTree xyorig = np.array((X[~fld.mask],Y[~fld.mask])).T fldorig = fld[~fld.mask] #======================================================================== # +++ append good points from CTD data to our arrays (*) +++ goodcount = 0 for station in Cast_dict.keys(): Cast = Cast_dict[station] cz = Cast.index.values izc = zfun.find_nearest_ind(cz, zz) # only take data from this cast if its bottom depth is at or above # the chosen hycom level czbot = -sta_df.loc[station,'Max_Depth'] if czbot <= zz: # becasue we used find_nearest above we should always # get data in the steps below if vn == 't3d': this_fld = Cast.iloc[izc]['Temperature'] elif vn == 's3d': this_fld = Cast.iloc[izc]['Salinity'] # and store in sta_df (to align with lat, lon) sta_df.loc[station,'fld'] = this_fld goodcount += 1 else: pass if goodcount >= 1: # drop stations that don't have T and s values at this depth sta_df = sta_df.dropna() # and for later convenience make a new list of stations sta_list = list(sta_df.index) # if we got any good points then append them if verbose: print(' - Ofun_CTD.get_orig: goodcount = %d, len(sta_df) = %d' % (goodcount, len(sta_df))) # append CTD values to the good points from HYCOM x_sta = sta_df['Longitude'].values y_sta = sta_df['Latitude'].values xx_sta, yy_sta = zfun.ll2xy(x_sta, y_sta, lon.mean(), lat.mean()) xy_sta = np.stack((xx_sta,yy_sta), axis=1) xyorig = np.concatenate((xyorig, xy_sta)) fld_arr = sta_df['fld'].values fldorig = np.concatenate((fldorig, np.array(fld_arr,ndmin=1))) else: if verbose: print(' - Ofun_CTD.get_orig: No points added') return xyorig, fldorig
qsin_abs = np.nan * np.ones(NS) qsout_abs = np.nan * np.ones(NS) sin = np.nan * np.ones(NS) sout = np.nan * np.ones(NS) xs = np.nan * np.ones(NS) ys = np.nan * np.ones(NS) counter = 0 for sect_name in sect_list: print('** ' + sect_name + ' **') x0, x1, y0, y1, landward = sect_df.loc[sect_name,:] lon = (x0+x1)/2 lat = (y0+y1)/2 if counter == 0: lon0 = lon lat0 = lat xs[counter], ys[counter] = zfun.ll2xy(lon, lat, lon0, lat0) fn = indir + sect_name + '.p' Qi, Si, Fi, qnet_lp, fnet_lp, td = tef_fun.tef_integrals(fn) qin[counter] = np.nanmean(Qi[:,0]/1e3) qout[counter] = np.nanmean(Qi[:,1]/1e3) qsin[counter] = np.nanmean(Fi[:,0]/1e3) qsout[counter] = np.nanmean(Fi[:,1]/1e3) qin_abs[counter] = np.nanmean(np.abs(Qi[:,0])) qout_abs[counter] = np.nanmean(np.abs(Qi[:,1])) qsin_abs[counter] = np.nanmean(np.abs(Fi[:,0])) qsout_abs[counter] = np.nanmean(np.abs(Fi[:,1])) sin[counter] = qsin_abs[counter]/qin_abs[counter] sout[counter] = qsout_abs[counter]/qout_abs[counter] counter += 1 # create a distance vector dx = np.diff(xs)
elif which_vol == 'Strait of Georgia': sea_sect = 'sji1'; land_sect = 'sog1' sea_seg = 'G1'; land_seg = 'G2' sill_name = 'San Juan Islands' df1 = flux_fun.get_fluxes(indir0, sea_sect) df3 = flux_fun.get_fluxes(indir0, land_sect) # get DX for dSbar_dx sea_lon = (sect_df.loc[sea_sect,'x0'] + sect_df.loc[sea_sect,'x1'])/2 sea_lat = (sect_df.loc[sea_sect,'y0'] + sect_df.loc[sea_sect,'y1'])/2 land_lon = (sect_df.loc[land_sect,'x0'] + sect_df.loc[land_sect,'x1'])/2 land_lat = (sect_df.loc[land_sect,'y0'] + sect_df.loc[land_sect,'y1'])/2 mean_lon = (sea_lon + land_lon)/2 mean_lat = (sea_lat + land_lat)/2 sea_x, sea_y = zfun.ll2xy(sea_lon, sea_lat, mean_lon, mean_lat) land_x, land_y = zfun.ll2xy(land_lon, land_lat, mean_lon, mean_lat) DX = np.sqrt((sea_x-land_x)**2 + (sea_y-land_y)**2) # various things for the dynamical scalings dSbar_dx = ((df1['Sin']+df1['Sout'])/2-(df3['Sin']+df3['Sout'])/2)/DX DF = df1['Ftide']-df3['Ftide'] # Net loss of tidal energy flux in region A0 = v_df.loc[sea_seg,'area m2'] + v_df.loc[land_seg,'area m2'] V0 = v_df.loc[sea_seg,'volume m3'] + v_df.loc[land_seg,'volume m3'] H0 = V0/A0 # average depth of surrounding segments B0 = V0/(H0*DX) # dynamical scalings a = 2.5 * 0.028 # the 2.5 is a fudge factor to get Qe to match Qe_pred Cd = 2.6e-3 h = H0/2 # m