def test_dyn_height_shallower_pref(): """ Check that we can handle a p_ref that is shallower than the top of the cast. To make the results from bin 1 on down independent of whether bin 0 has been deleted, we need to use linear interpolation. """ p = cv.p_chck_cast CT = cv.CT_chck_cast SA = cv.SA_chck_cast strf0 = gsw.geo_strf_dyn_height(SA, CT, p, p_ref=0, interp_method='linear') strf1 = gsw.geo_strf_dyn_height(SA[1:], CT[1:], p[1:], p_ref=0, interp_method='linear') found = strf1 - strf1[0] expected = strf0[1:] - strf0[1] assert_almost_equal(found, expected)
def test_geostrophy(): lon = cv.long_chck_cast lat = cv.lat_chck_cast p = cv.p_chck_cast CT = cv.CT_chck_cast SA = cv.SA_chck_cast strf = gsw.geo_strf_dyn_height(SA, CT, p) geovel, midlon, midlat = gsw.geostrophic_velocity(strf, lon, lat) assert_almost_equal(geovel, cv.geo_strf_velocity) assert_almost_equal(midlon, cv.geo_strf_velocity_mid_long[0]) assert_almost_equal(midlat, cv.geo_strf_velocity_mid_lat[0])
def test_strf_no_good(): # revised geo_strf_dyn_height requires 2 valid points shape = (5,) SA = np.ma.masked_all(shape, dtype=float) CT = np.ma.masked_all(shape, dtype=float) p = np.array([0.0, 10.0, 20.0, 30.0, 40.0]) # No valid points. strf = gsw.geo_strf_dyn_height(SA, CT, p, p_ref=0, axis=0) expected = np.zeros(shape, float) + np.nan assert_array_equal(strf.filled(np.nan), expected) # 1 valid point: not enough. SA[:1] = 35 CT[:1] = 5 strf = gsw.geo_strf_dyn_height(SA, CT, p, p_ref=0, axis=0) expected = np.zeros(shape, float) + np.nan assert_array_equal(strf.filled(np.nan), expected) # 2 valid points: enough for the calculation to proceed. SA[:2] = 35 CT[:2] = [5, 4] strf = gsw.geo_strf_dyn_height(SA, CT, p, p_ref=0, axis=0) assert strf.count() == 2
def geo_strf_isopycnal(SA, CT, p, p_ref, Neutral_Density, p_Neutral_Density, A="s2"): p = np.abs(np.asarray(p)) try: dyn_height = gsw.geo_strf_dyn_height(SA, CT, p, p_ref) except: print("something wrong") print(SA, CT, p, p_ref) return np.nan p_Neutral_Density, idxs = np.unique(p_Neutral_Density, return_index=True) Neutral_Density = Neutral_Density[idxs] filt = np.where(np.isin(p, p_Neutral_Density)) nsdyn_height = dyn_height[filt] nstemps = CT[filt] nssals = SA[filt] db2Pa = 1e4 sa_iref_cast, ct_iref_cast, p_iref_cast = interp_ref_cast( Neutral_Density, A) cp0 = 3991.86795711963 part1 = 0.5 * db2Pa * (p_Neutral_Density - p_iref_cast) * ( gsw.specvol(nssals, nstemps, p_Neutral_Density) - gsw.specvol(sa_iref_cast, ct_iref_cast, p_Neutral_Density)) part2 = 0 part3 = (-0.225e-15) * (db2Pa * db2Pa) * (nstemps - ct_iref_cast) * ( p_Neutral_Density - p_iref_cast) * (p_Neutral_Density - p_iref_cast) part4 = nsdyn_height - enthalpy_SSO_0(p_Neutral_Density) part5 = gsw.enthalpy(sa_iref_cast, ct_iref_cast, p_Neutral_Density) - cp0 * ct_iref_cast return part1 + part2 + part3 + part4 + part5
def calc_geostrophic_velocity(var_w_sa_ct_p_lon_lat): import numpy as np import xarray as xr import gsw # need geostrophic stream function first temp = var_w_sa_ct_p_lon_lat.sortby('z', ascending=False) temp['geo_height'] = xr.full_like( temp.SA, fill_value=np.nan) # make empty dataarray temp.geo_height.values = gsw.geo_strf_dyn_height(temp.SA, temp.CT, temp.Pressure, p_ref=10.1325, axis=1) temp['geo_velocity'] = xr.full_like( temp.geo_height, fill_value=np.nan) # make empty dataarray temp.geo_velocity[0:-1, :] = np.transpose( gsw.geostrophic_velocity(temp.geo_height.T.values, temp.lon, temp.lat)[0]) var_w_sa_ct_p_lon_lat = temp.sortby('z', ascending=True) return var_w_sa_ct_p_lon_lat
# DYNAMIC HEIGHT and depth nanarray = np.empty((ctd['P'].shape[0], len(transects[nts]))) nanarray[:] = np.nan SA, CT, g, depth, pt, nprof = nanarray.copy(), nanarray.copy(), nanarray.copy(), nanarray.copy(), nanarray.copy(), nanarray.copy() for i, profile in enumerate(transects[nts]): nprof[:, i] = profile SA[:, i] = SA_from_SP(ctd['S'][:, profile], P, ctd['lon'][0, profile], ctd['lat'][0, profile]) CT[:, i] = CT_from_t(SA[:, i], ctd['T'][:, profile], P) g[:, i] = grav(ctd['lat'][0, profile], P) depth[:, i] = abs(z_from_p(P, ctd['lat'][0, profile])) pt[:, i] = pt_from_t(SA[:, i], ctd['T'][:, profile], P, p_ref) sig0 = sigma0(SA, CT) # for i deltaD = geo_strf_dyn_height(SA, CT, P, p_ref=p_ref) / g deltaD500 = np.tile(deltaD[i500], (deltaD.shape[0],1)) # g_p = grav(ctd['lat'][0, profile], P) # SA = SA_from_SP(ctd['S'][:, profile], P, ctd['lon'][0, profile], ctd['lat'][0, profile]) # CT = CT_from_t(SA, ctd['T'][:, profile], P) # pt = pt_from_t(SA, ctd['T'][:, profile], P, 0) # depth = abs(z_from_p(P, ctd['lat'][0, profile])) # deltaD = geo_strf_dyn_height(SA, CT, P) # fig, ax = plt.subplots(1, 2, sharex='col', sharey='row', figsize=(20, 8)) # ct0 = ax[0].contourf(deltaD500, depth, CT, cmap=cmocean.cm.thermal) # fig.colorbar(ct0, ax=ax[0]) # ax[0].set_title('Conservative Temperature') # ax[0].set_ylabel('Depth in m') # ax[0].invert_yaxis()
# change one dimension variables to two dimensions p, lon, lat = nc['p'][:], nc['lon'][:, 0][:, np.newaxis], nc[ 'lat'][:, 0][:, np.newaxis] # convert in-situ variables to gsw variables p_ref = 1494 # shallowest profile (4) except (34) which goes until 1004 SA = SA_from_SP(nc['SP'][:], p, lon, lat) CT = CT_from_t(SA, nc['t'][:], p) pt = pt_from_t(SA, nc['t'][:], p, p_ref) deltaD = np.ma.masked_invalid( geo_strf_dyn_height(SA.data, CT.data, p, p_ref=p_ref, axis=1)) # transect stations transects = { 1: list(reversed(range(2, 10))), 2: list(range(10, 18)), 3: list(reversed(range(18, 27))), 4: list(range(26, 34)), 5: list(reversed(range(36, 46))), 6: list(range(46, 57)), 7: list(reversed(range(56, 65))), 8: list(reversed(range(68, 76))), 9: list(range(76, 84)), 10: list(reversed(range(84, 91))),
lat_array = np.zeros(pres.shape) lat_array[:] = np.NaN lon_array = np.zeros(pres.shape) lon_array[:] = np.NaN for l in np.arange(lat_array.shape[0]): lat_array[l, :] = lat[l] lon_array[l, :] = lon[l] SA = gsw.SA_from_SP(sal, pres, lon_array, lat_array) CT = gsw.CT_from_t(SA, temp, pres) oxy_eq = gsw.O2sol(SA, CT, pres, lon_array, lat_array) # calculate depth geo_strf = gsw.geo_strf_dyn_height(SA=SA.T, CT=CT.T, p=pres.T) geo_strf = geo_strf.T z = gsw.z_from_p(p=pres, lat=lat_array, geo_strf_dyn_height=geo_strf) z = -1 * z oxy_sat = doxy / oxy_eq * 100 # Calculate density density = np.zeros(temp.shape) # Calculate MLD mld = np.zeros(sal.shape[0]) mld[:] = np.NaN
dict_stations['P']) dict_stations[station]['g'] = grav( dict_stations[station]['lat'], dict_stations['P']) dict_stations[station]['depth'] = abs( z_from_p(dict_stations['P'], dict_stations[station]['lat'])) dict_stations[station]['pt'] = pt_from_t( dict_stations[station]['SA'], dict_stations[station]['T'], dict_stations['P'], p_ref) dict_stations[station]['sigma0'] = sigma0( dict_stations[station]['SA'], dict_stations[station]['CT']) dict_stations[station]['spiciness0'] = spiciness0( dict_stations[station]['SA'], dict_stations[station]['CT']) dict_stations[station]['deltaD'] = geo_strf_dyn_height( dict_stations[station]['SA'], dict_stations[station]['CT'], dict_stations['P'], p_ref=p_ref) # save dictionary to file write_dict(dict_stations, path, filename, protocol=2) # protocol 2 allows python2 print('data stored in file') # 2) CALCULATE NEUTRAL DENSITY IN PYTHON2 if sys.version_info[0] == 2: # python2 from pygamman import gamman as nds if os.path.exists(os.path.join(path, filename + '.pkl')): dict_stations = read_dict(path, filename + '.pkl')
Matlab functions. Therefore we have to make our own test values, using the current test cast inputs. This is a minimal script for that purpose, to be run in the tests directory in which it lives. It should be run only if we change to a different calculation algorithm, or we update the cast input and general check value file. """ import numpy as np import gsw from gsw._utilities import Bunch cv = Bunch(np.load('gsw_cv_v3_0.npz')) dyn_height = gsw.geo_strf_dyn_height(cv.SA_chck_cast, cv.CT_chck_cast, cv.p_chck_cast, cv.pr) np.save('geo_strf_dyn_height.npy', dyn_height) lon = cv.long_chck_cast lat = cv.lat_chck_cast p = cv.p_chck_cast CT = cv.CT_chck_cast SA = cv.SA_chck_cast strf = gsw.geo_strf_dyn_height(SA, CT, p) geovel, midlon, midlat = gsw.geostrophic_velocity(strf, lon, lat) np.save('geo_strf_velocity.npy', geovel) # midlon, midlat are OK