def mocsy_3d_getOmA(tsal, ttemp, tdic, tta): tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = 1 tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tzero, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup OmegaAR = OmegaA.reshape(40, 898, 398) return OmegaAR
def oned_moxy(tsal, ttemp, tdic, tta, pres_atm, depth_this): size_box = np.shape(tdic) size_0 = size_box[0] size_1= size_box[1] size_2 = size_box[2] tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = pres_atm tdepth = np.ravel(depth_this) tzero = tpressure * 0 tsra_psu = tsra*35/35.16504 ttera_is = gsw.t_from_CT(tsra,ttera,tzero) print('beginning mocsy') response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepth, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb = 'l10', optk1k2='m10', optkf = 'dg', optgas = 'Pinsitu') pH,pco2,fco2,co2,hco3,co3,OmegaA,OmegaC,BetaD,DENis,p,Tis = response_tup print('finished mocsy') pHr = pH.reshape(size_0,size_1,size_2) OmAr = OmegaA.reshape(size_0,size_1,size_2) pco2r = pco2.reshape(size_0,size_1,size_2) return pHr, OmAr, pco2r
def compute_potdens(ds, saltname='SALT', tempname='THETA'): import gsw """ compute the potential density """ # compute the Conservative Temperature from the model's potential temperature temp = ds[tempname].transpose(*('time', 'k', 'face', 'j', 'i')) salt = ds[tempname].transpose(*('time', 'k', 'face', 'j', 'i')) CT = gsw.CT_from_pt(salt, temp) z, lat = xr.broadcast(ds['Z'], ds['YC']) z = z.transpose(*('k', 'face', 'j', 'i')) lat = lat.transpose(*('k', 'face', 'j', 'i')) # compute pressure from depth p = gsw.p_from_z(z, lat) # compute in-situ temperature T = gsw.t_from_CT(salt, CT, p) # compute potential density rho = gsw.pot_rho_t_exact(salt, T, p, 0.) # create new dataarray darho = xr.full_like(temp, 0.) darho = darho.load().chunk({'time': 1, 'face': 1}) darho.name = 'RHO' darho.attrs['long_name'] = 'Potential Density ref at 0m' darho.attrs['standard_name'] = 'RHO' darho.attrs['units'] = 'kg/m3' darho.values = rho # filter special value darho = darho.where(darho > 1000) darho = darho.assign_coords(XC=ds['XC'], YC=ds['YC'], Z=ds['Z']) return darho
def OmA_2D(grid,carp): tsal = grid['vosaline'][0,0,:,:] ttemp = grid['votemper'][0,0,:,:] tdic = carp['dissolved_inorganic_carbon'][0,0,:,:] tta = carp['total_alkalinity'][0,0,:,:] tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] =1 tzero = tpressure * 0 tsra_psu = tsra*35/35.16504 ttera_is = gsw.t_from_CT(tsra,ttera,tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tzero, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb = 'l10', optk1k2='m10', optkf = 'dg', optgas = 'Pinsitu') pH,pco2,fco2,co2,hco3,co3,OmegaA,OmegaC,BetaD,DENis,p,Tis = response_tup pHr = pH.reshape(898,398) OmAr = OmegaA.reshape(898,398) OmCr = OmegaC.reshape(898,398) pco2r = pco2.reshape(898,398) return pHr, OmAr, OmCr, pco2r
def tsappen_ct(p, **kwargs): ''' add potential density contours to the current axis ''' ax = kwargs.get('axis', plt.gca()) pref = kwargs.get('pref', 0) levels = kwargs.get('levels', np.arange(20, 31)) colors = kwargs.get('colors', 'k') keys = ['axis', 'pref', 'levels', 'colors'] for key in keys: if key in kwargs: kwargs.pop(key) xlim = ax.get_xlim() ylim = ax.get_ylim() xax = np.arange(np.min(xlim) - 0.01, np.max(xlim) + 0.01, 0.01) yax = np.arange(np.min(ylim) - 0.01, np.max(ylim) + 0.01, 0.01) sa, ct = np.meshgrid(xax, yax) # pden = sw.pden(x, y, pref, 0)-1000 t = gsw.t_from_CT(sa, ct, p) pden = gsw.pot_rho_t_exact(sa, t, pref, 0) - 1000 c = plt.contour(sa, ct, pden, levels, colors=colors, **kwargs) plt.clabel(c, fmt='%2.1f')
def potential_to_in_situ_temperature(dsPotTemp, dsSalin): z = dsPotTemp.z.values lat = numpy.maximum(dsPotTemp.lat.values, -80.) lon = dsPotTemp.lon.values if len(lat.shape) == 1: lon, lat = numpy.meshgrid(lon, lat) nz = len(z) ny, nx = lat.shape if 'time' in dsPotTemp.dims: nt = dsPotTemp.sizes['time'] T = numpy.nan * numpy.ones((nt, nz, ny, nx)) for zIndex in range(nz): pressure = gsw.p_from_z(z[zIndex], lat) for tIndex in range(nt): pt = dsPotTemp.temperature[tIndex, zIndex, :, :].values salin = dsSalin.salinity[tIndex, zIndex, :, :].values mask = numpy.logical_and(numpy.isfinite(pt), numpy.isfinite(salin)) SA = gsw.SA_from_SP(salin[mask], pressure[mask], lon[mask], lat[mask]) TSlice = T[tIndex, zIndex, :, :] CT = gsw.CT_from_pt(SA, pt[mask]) TSlice[mask] = gsw.t_from_CT(SA, CT, pressure[mask]) T[tIndex, zIndex, :, :] = TSlice else: T = numpy.nan * numpy.ones((nz, ny, nx)) for zIndex in range(nz): pressure = gsw.p_from_z(z[zIndex], lat) pt = dsPotTemp.temperature[zIndex, :, :].values salin = dsSalin.salinity[zIndex, :, :].values mask = numpy.logical_and(numpy.isfinite(pt), numpy.isfinite(salin)) SA = gsw.SA_from_SP(salin[mask], pressure[mask], lon[mask], lat[mask]) TSlice = T[zIndex, :, :] CT = gsw.CT_from_pt(SA, pt[mask]) TSlice[mask] = gsw.t_from_CT(SA, CT, pressure[mask]) T[zIndex, :, :] = TSlice dsTemp = dsPotTemp.drop('temperature') dsTemp['temperature'] = (dsPotTemp.temperature.dims, T) dsTemp['temperature'].attrs = dsPotTemp.temperature.attrs return dsTemp
def potential_density(salt_PSU, temp_C, pres_db, lat, lon, pres_ref=0): """ Calculate density from glider measurements of salinity and temperature. The Basestation calculates density from absolute salinity and potential temperature. This function is a wrapper for this functionality, where potential temperature and absolute salinity are calculated first. Note that a reference pressure of 0 is used by default. Parameters ---------- salt_PSU : array, dtype=float, shape=[n, ] practical salinty temp_C : array, dtype=float, shape=[n, ] temperature in deg C pres_db : array, dtype=float, shape=[n, ] pressure in decibar lat : array, dtype=float, shape=[n, ] latitude in degrees north lon : array, dtype=float, shape=[n, ] longitude in degrees east Returns ------- potential_density : array, dtype=float, shape=[n, ] Note ---- Using seawater.dens does not yield the same results as this function. We get very close results to what the SeaGlider Basestation returns with this function. The difference of this function with the basestation is on average ~ 0.003 kg/m3 """ try: import gsw salt_abs = gsw.SA_from_SP(salt_PSU, pres_db, lon, lat) temp_pot = gsw.t_from_CT(salt_abs, temp_C, pres_db) pot_dens = gsw.pot_rho_t_exact(salt_abs, temp_pot, pres_db, pres_ref) except ImportError: import seawater as sw pot_dens = sw.pden(salt_PSU, temp_C, pres_db, pres_ref) pot_dens = transfer_nc_attrs( getframe(), temp_C, pot_dens, 'potential_density', units='kg/m3', comment='', standard_name='potential_density', ) return pot_dens
def OmA_3D(grid, carp): tsal = grid['model_output']['SAL'][:, :, :] ttemp = grid['model_output']['TEMP'][:, :, :] tdic = carp['model_output']['DIC'][:, :, :] tta = carp['model_output']['TA'][:, :, :] test_LO = nc.Dataset( '/results/forcing/LiveOcean/boundary_conditions/LiveOcean_v201905_y2018m01d01.nc' ) zlevels = (test_LO['deptht'][:]) depths = np.zeros([40, 898, 398]) for j in range(0, 898): for i in range(0, 398): depths[:, j, i] = zlevels tdepths = np.ravel(depths) tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = 1 tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepths, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup pHr = pH.reshape(40, 898, 398) OmAr = OmegaA.reshape(40, 898, 398) OmCr = OmegaC.reshape(40, 898, 398) pco2r = pco2.reshape(40, 898, 398) return pHr, OmAr, OmCr, pco2r
def OmA_3D(grid, carp): tsal = grid['vosaline'][0, :, :, :] ttemp = grid['votemper'][0, :, :, :] tdic = carp['dissolved_inorganic_carbon'][0, :, :, :] tta = carp['total_alkalinity'][0, :, :, :] test_LO = nc.Dataset( '/results/forcing/LiveOcean/boundary_conditions/LiveOcean_v201905_y2018m01d01.nc' ) zlevels = (test_LO['deptht'][:]) depths = np.zeros([40, 898, 398]) for j in range(0, 898): for i in range(0, 398): depths[:, j, i] = zlevels tdepths = np.ravel(depths) tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = 1 tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepths, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup BetaDr = BetaD.reshape(40, 898, 398) return BetaDr
def oned_moxy(tsal, ttemp, tdic, tta, pres_atm, depth_this): import sys sys.path.append('/data/tjarniko/mocsy') import mocsy import numpy as np import gsw size_box = np.shape(tdic) size_0 = size_box[0] size_1 = size_box[1] tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) #tdepth = np.zeros_like(tsra) tpressure[:] = pres_atm tdepth = np.ravel(depth_this) tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepth, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup pHr = pH.reshape(size_0, size_1) OmAr = OmegaA.reshape(size_0, size_1) pco2r = pco2.reshape(size_0, size_1) return pHr, OmAr, pco2r
def surface_maps(carp, grid, stns, ddmmmyy, rdir, humandate, dss_sig): tsal = grid.variables['vosaline'][0, 0, :, :] ttemp = grid.variables['votemper'][0, 0, :, :] tdic = carp.variables['dissolved_inorganic_carbon'][0, 0, :, :] tta = carp.variables['total_alkalinity'][0, 0, :, :] tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = 1 tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tzero, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup pHr = pH.reshape(898, 398) OmA = OmegaA.reshape(898, 398) surf_dat = [tsal, tdic, tta, ttemp, pHr, OmA] vmins = [25, 1800, 1800, 5, 7.5, 0] vmaxs = [32, 2200, 2200, 15, 8.5, 2] msk = [0, 0, 0, 0, 1e20, 1e20] cl = [ 'salinity psu', 'DIC umol/kg', 'TA umol/kg', 'temp deg C', 'pH', 'Omega A' ] t_cmap = [ cm.cm.haline, cm.cm.matter, cm.cm.matter, cm.cm.thermal, cm.cm.speed, cm.cm.curl ] fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = \ plt.subplots(figsize=(20, 27) , nrows=2, ncols=3) viz_tools.set_aspect(ax1) viz_tools.set_aspect(ax2) viz_tools.set_aspect(ax3) viz_tools.set_aspect(ax4) viz_tools.set_aspect(ax5) viz_tools.set_aspect(ax6) i = 0 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax1.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax1) cbar.set_label(cl[i], fontsize=20) i = 1 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax2.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax2) cbar.set_label(cl[i], fontsize=20) i = 2 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax3.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax3) cbar.set_label(cl[i], fontsize=20) i = 3 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax4.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax4) cbar.set_label(cl[i], fontsize=20) i = 4 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax5.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax5) cbar.set_label(cl[i], fontsize=20) i = 5 tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, msk[i]) tcmap = t_cmap[i] mesh = ax6.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax6) cbar.set_label(cl[i], fontsize=20) cols = [] xs = [] ys = [] stn_in = [] for s in stns: col = stns[s]['color'] x = stns[s]['x'] y = stns[s]['y'] stn = stns[s]['code'] cols.append(col) xs.append(x) ys.append(y) stn_in.append(stn) for w in range(0, len(stns)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax1.add_patch(pat) for w in range(0, len(cols)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax2.add_patch(pat) for w in range(0, len(cols)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax3.add_patch(pat) for w in range(0, len(cols)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax4.add_patch(pat) for w in range(0, len(cols)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax5.add_patch(pat) for w in range(0, len(cols)): pat = patches.Rectangle((xs[w], ys[w]), 20, 20, linewidth=2, edgecolor=cols[w], facecolor='none') ax6.add_patch(pat) for i in range(0, len(xs)): ax1.text(xs[i] + 22, ys[i] + 3, stn_in[i], weight='bold', fontsize=20) #tcmap.set_bad('white') st = 'Salish Sea Carbonate Chemistry Map, ' + humandate plt.suptitle(st, fontsize=20) fname = rdir + f'{ddmmmyy}_map_' + dss_sig + '.png' fig.savefig(fname) plt.close()
def surface_buffer_maps(carp, grid, ddmmmyy, rdir, humandate, dss_sig): #retrieve relevant data for mocsy calculation, calculate mocsy tsal = grid.variables['vosaline'][0, 0, :, :] ttemp = grid.variables['votemper'][0, 0, :, :] tdic = carp.variables['dissolved_inorganic_carbon'][0, 0, :, :] tta = carp.variables['total_alkalinity'][0, 0, :, :] tsra = np.ravel(tsal) ttera = np.ravel(ttemp) ttara = np.ravel(tta) * 1e-3 tdra = np.ravel(tdic) * 1e-3 tzero = np.zeros_like(tsra) tpressure = np.zeros_like(tsra) tpressure[:] = 1 tzero = tpressure * 0 tsra_psu = tsra * 35 / 35.16504 ttera_is = gsw.t_from_CT(tsra, ttera, tzero) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tzero, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb='l10', optk1k2='m10', optkf='dg', optgas='Pinsitu') pH, pco2, fco2, co2, hco3, co3, OmegaA, OmegaC, BetaD, DENis, p, Tis = response_tup #calculate borate and ohminus concentration bicarb = hco3 carb = co3 #calculate borate, Uppstrom, 1974, looked up in mocsy scl = tsra / 1.80655 borat = 0.000232 * scl / 10.811 hplus = 10**(-1 * pH) borat2 = .0000119 * tsra ohminus = ttara - bicarb - 2 * carb - borat # - calculates quantities needed for Egleston's factors, and the factors themselves #Khb is the acidity constant for boric acid - is this an appropriate ref? # https://www2.chemistry.msu.edu/courses/cem262/aciddissconst.html Khb = 5.81e-10 S = bicarb + 4 * (carb) + (hplus * borat) / (Khb + hplus) + hplus - ohminus P = 2 * (carb) + bicarb AlkC = bicarb + 2 * (carb) DIC = co2 + bicarb + carb #Alk = bicarb + 2*carb + borat - hplus + ohminus g_dic = DIC - AlkC**2 / S b_dic = (DIC * S - AlkC**2) / AlkC w_dic = DIC - (AlkC * P) / bicarb g_alk = (AlkC**2 - DIC * S) / AlkC b_alk = (AlkC**2 / DIC) - S w_alk = AlkC - (DIC * bicarb) / P #### g_dicR = g_dic.reshape(898, 398) * 1000 b_dicR = b_dic.reshape(898, 398) * 1000 w_dicR = w_dic.reshape(898, 398) * -1000 g_alkR = g_alk.reshape(898, 398) * -1000 b_alkR = b_alk.reshape(898, 398) * -1000 w_alkR = w_alk.reshape(898, 398) * 1000 surf_dat = [g_dicR, b_dicR, w_dicR, g_alkR, b_alkR, w_alkR] #ranges from nov 13,2014 hindcast. vmins = [-0.7, -0.4, -0.1, -0.4, -0.4, -0.1] vmaxs = [0.7, 1, 0.5, 1, 1, 0.4] msk = [1.875e+23, 5e+23, 6e+23, 5e+23, 5e+23, 2e+23] cl = ['$\gamma_{DIC}$', '$\\beta_{DIC}$', '-$\omega_{DIC}$',\ '$\gamma_{TA}$', '$\\beta_{TA}$', '-$\omega_{TA}$'] t_cmap = [cm.cm.oxy, cm.cm.oxy, cm.cm.oxy, cm.cm.oxy, cm.cm.oxy, cm.cm.oxy] fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = \ plt.subplots(figsize=(20, 27) , nrows=2, ncols=3) viz_tools.set_aspect(ax1) viz_tools.set_aspect(ax2) viz_tools.set_aspect(ax3) viz_tools.set_aspect(ax4) viz_tools.set_aspect(ax5) viz_tools.set_aspect(ax6) i = 0 #'g_dicR', tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 1.875e+23) tcmap = t_cmap[i] mesh = ax1.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax1) cbar.set_label(cl[i], fontsize=20) ax1.set_title('$CO_{2}$ with DIC', fontsize=22) i = 1 #'b_dicR', tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 5e+23) tcmap = t_cmap[i] mesh = ax2.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax2) cbar.set_label(cl[i], fontsize=20) ax2.set_title('pH with DIC', fontsize=22) i = 2 #'-w_dicR', tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 6e+23) tcmap = t_cmap[i] mesh = ax3.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax3) cbar.set_label(cl[i], fontsize=20) ax3.set_title('$\Omega$ with DIC', fontsize=22) i = 3 #'-g_alkR', tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 5e+23) tcmap = t_cmap[i] mesh = ax4.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax4) cbar.set_label(cl[i], fontsize=20) ax4.set_title('$CO_{2}$ with TA', fontsize=22) i = 4 #'-b_alkR', tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 5e+23) tcmap = t_cmap[i] mesh = ax5.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax5) cbar.set_label(cl[i], fontsize=20) ax5.set_title('pH with TA', fontsize=22) i = 5 #'w_alkR' tplt0 = surf_dat[i] tplt = np.ma.masked_values(tplt0, 2e+23) tcmap = t_cmap[i] mesh = ax6.pcolormesh(tplt, cmap=tcmap, vmin=vmins[i], vmax=vmaxs[i]) cbar = fig.colorbar(mesh, ax=ax6) cbar.set_label(cl[i], fontsize=20) ax6.set_title('$\Omega$ with TA', fontsize=22) #tcmap.set_bad('white') st = 'Carbonate Chemistry Buffer Factors, ' + humandate plt.suptitle(st, fontsize=20) fname = rdir + f'{ddmmmyy}_buffmap_' + dss_sig + '.png' fig.savefig(fname) plt.close()
def run_task(self): # {{{ """ Plots time-series output of properties in an ocean region. """ # Authors # ------- # Xylar Asay-Davis self.logger.info("\nPlotting TS diagram for {}" "...".format(self.regionName)) register_custom_colormaps() config = self.config sectionName = self.sectionName startYear = self.mpasClimatologyTask.startYear endYear = self.mpasClimatologyTask.endYear regionMaskSuffix = config.getExpression(sectionName, 'regionMaskSuffix') regionMaskFile = get_region_mask(config, '{}.geojson'.format(regionMaskSuffix)) fcAll = read_feature_collection(regionMaskFile) fc = FeatureCollection() for feature in fcAll.features: if feature['properties']['name'] == self.regionName: fc.add_feature(feature) break self.logger.info(' Make plots...') groupLink = 'tsDiag' + self.regionGroup[0].lower() + \ self.regionGroup[1:].replace(' ', '') nSubplots = 1 + len(self.obsDicts) if self.controlConfig is not None: nSubplots += 1 if nSubplots == 4: nCols = 2 nRows = 2 else: nCols = min(nSubplots, 3) nRows = (nSubplots - 1) // 3 + 1 axisIndices = numpy.reshape(numpy.arange(nRows * nCols), (nRows, nCols))[::-1, :].ravel() titleFontSize = config.get('plot', 'titleFontSize') axis_font = {'size': config.get('plot', 'axisFontSize')} title_font = { 'size': titleFontSize, 'color': config.get('plot', 'titleFontColor'), 'weight': config.get('plot', 'titleFontWeight') } width = 3 + 4.5 * nCols height = 2 + 4 * nRows # noinspection PyTypeChecker fig, axarray = plt.subplots(nrows=nRows, ncols=nCols, sharey=True, figsize=(width, height)) if nSubplots == 1: axarray = numpy.array(axarray) if nRows == 1: axarray = axarray.reshape((nRows, nCols)) T, S, zMid, volume, zmin, zmax = self._get_mpas_t_s(self.config) mainRunName = config.get('runs', 'mainRunName') plotFields = [{ 'S': S, 'T': T, 'z': zMid, 'vol': volume, 'title': mainRunName }] if self.controlConfig is not None: T, S, zMid, volume, _, _ = self._get_mpas_t_s(self.controlConfig) controlRunName = self.controlConfig.get('runs', 'mainRunName') plotFields.append({ 'S': S, 'T': T, 'z': zMid, 'vol': volume, 'title': 'Control: {}'.format(controlRunName) }) for obsName in self.obsDicts: obsT, obsS, obsZ, obsVol = self._get_obs_t_s( self.obsDicts[obsName]) plotFields.append({ 'S': obsS, 'T': obsT, 'z': obsZ, 'vol': obsVol, 'title': obsName }) Tbins = config.getExpression(sectionName, 'Tbins', usenumpyfunc=True) Sbins = config.getExpression(sectionName, 'Sbins', usenumpyfunc=True) normType = config.get(sectionName, 'normType') PT, SP = numpy.meshgrid(Tbins, Sbins) SA = gsw.SA_from_SP(SP, p=0., lon=0., lat=-75.) CT = gsw.CT_from_t(SA, PT, p=0.) neutralDensity = sigma0(SA, CT) rhoInterval = config.getfloat(sectionName, 'rhoInterval') contours = numpy.arange(24., 29. + rhoInterval, rhoInterval) diagramType = config.get(sectionName, 'diagramType') if diagramType not in ['volumetric', 'scatter']: raise ValueError('Unexpected diagramType {}'.format(diagramType)) lastPanel = None volMinMpas = None volMaxMpas = None for index in range(len(axisIndices)): panelIndex = axisIndices[index] row = nRows - 1 - index // nCols col = numpy.mod(index, nCols) if panelIndex >= nSubplots: plt.delaxes(axarray[row, col]) continue plt.sca(axarray[row, col]) T = plotFields[index]['T'] S = plotFields[index]['S'] z = plotFields[index]['z'] volume = plotFields[index]['vol'] title = plotFields[index]['title'] CS = plt.contour(SP, PT, neutralDensity, contours, linewidths=1., colors='k', zorder=2) plt.clabel(CS, fontsize=12, inline=1, fmt='%4.2f') if diagramType == 'volumetric': lastPanel, volMin, volMax = \ self._plot_volumetric_panel(T, S, volume) if index == 0: volMinMpas = volMin volMaxMpas = volMax if normType == 'linear': norm = colors.Normalize(vmin=0., vmax=volMaxMpas) elif normType == 'log': if volMinMpas is None or volMaxMpas is None: norm = None else: norm = colors.LogNorm(vmin=volMinMpas, vmax=volMaxMpas) else: raise ValueError( 'Unsupported normType {}'.format(normType)) if norm is not None: lastPanel.set_norm(norm) else: lastPanel = self._plot_scatter_panel(T, S, z, zmin, zmax) CTFreezing = freezing.CT_freezing(Sbins, 0, 1) PTFreezing = gsw.t_from_CT(gsw.SA_from_SP(Sbins, p=0., lon=0., lat=-75.), CTFreezing, p=0.) plt.plot(Sbins, PTFreezing, linestyle='--', linewidth=1., color='k') plt.ylim([Tbins[0], Tbins[-1]]) plt.xlim([Sbins[0], Sbins[-1]]) plt.xlabel('Salinity (PSU)', **axis_font) if col == 0: plt.ylabel(r'Potential temperature ($^\circ$C)', **axis_font) plt.title(title) # do this before the inset because otherwise it moves the inset # and cartopy doesn't play too well with tight_layout anyway plt.tight_layout() fig.subplots_adjust(right=0.91) if nRows == 1: fig.subplots_adjust(top=0.85) else: fig.subplots_adjust(top=0.88) suptitle = 'T-S diagram for {} ({}, {:04d}-{:04d})\n' \ ' {} m < z < {} m'.format(self.regionName, self.season, startYear, endYear, zmin, zmax) fig.text(0.5, 0.9, suptitle, horizontalalignment='center', **title_font) inset = add_inset(fig, fc, width=1.5, height=1.5) # move the color bar down a little ot avoid the inset pos0 = inset.get_position() pos1 = axarray[-1, -1].get_position() pad = 0.04 top = pos0.y0 - pad height = top - pos1.y0 cbar_ax = fig.add_axes([0.92, pos1.y0, 0.02, height]) cbar = fig.colorbar(lastPanel, cax=cbar_ax) if diagramType == 'volumetric': cbar.ax.get_yaxis().labelpad = 15 cbar.ax.set_ylabel(r'volume (m$^3$)', rotation=270) else: cbar.ax.set_ylabel('depth (m)', rotation=270) outFileName = '{}/TS_diagram_{}_{}.png'.format(self.plotsDirectory, self.prefix, self.season) savefig(outFileName, tight=False) caption = 'Regional mean of {}'.format(suptitle) write_image_xml(config=config, filePrefix='TS_diagram_{}_{}'.format( self.prefix, self.season), componentName='Ocean', componentSubdirectory='ocean', galleryGroup='T-S Diagrams', groupLink=groupLink, gallery=self.regionGroup, thumbnailDescription=self.regionName, imageDescription=caption, imageCaption=caption)
def profiles(carp, grid, stns): ''' Take 2 daily datasets, carbon+ and grid, extract depth profiles of sal,temp,DIC,TA,O2,pH,OmA and their standard deviations" ''' w = carp wp = grid sal = wp.variables['vosaline'][0,:,:,:] temp = wp.variables['votemper'][0,:,:,:] DIC = w.variables['dissolved_inorganic_carbon'][0,:,:,:] TA = w.variables['total_alkalinity'][0,:,:,:] O2 = w.variables['dissolved_oxygen'][0,:,:,:] prof_depth = w.variables['deptht'][:] depth_broadcast = np.zeros([40,20,20]) for i in range(0,40): depth_broadcast[i,:,:] = prof_depth[i] nos = len(stns) stn_list = [] sal_prof = np.zeros([nos,40]) temp_prof = np.zeros([nos,40]) DIC_prof = np.zeros([nos,40]) TA_prof = np.zeros([nos,40]) pH_prof = np.zeros([nos,40]) OmA_prof = np.zeros([nos,40]) O2_prof = np.zeros([nos,40]) sal_profSD = np.zeros([nos,40]) temp_profSD = np.zeros([nos,40]) DIC_profSD = np.zeros([nos,40]) TA_profSD = np.zeros([nos,40]) pH_profSD = np.zeros([nos,40]) OmA_profSD = np.zeros([nos,40]) O2_profSD = np.zeros([nos,40]) b = 0 for s in stns: stn_list.append(s) stn = stns[s] #print('Calculating profiles for ' + stns[s]['fullname']) ty = stns[s]['y'] tx = stns[s]['x'] ts = sal[:,ty:ty+20,tx:tx+20] tte = temp[:,ty:ty+20,tx:tx+20] td = DIC[:,ty:ty+20,tx:tx+20] tta = TA[:,ty:ty+20,tx:tx+20] to2 = O2[:,ty:ty+20,tx:tx+20] tsr = ts.reshape(40,400) tter = tte.reshape(40,400) tdr = td.reshape(40,400) ttar = tta.reshape(40,400) tdepth = depth_broadcast.reshape(40,400) to2r = to2.reshape(40,400) tsr[tsr == 0] = np.ma.masked tter[tter == 0] = np.ma.masked tdr[tdr == 0] = np.ma.masked ttar[ttar == 0] = np.ma.masked sal_prof[b,:] = np.ma.MaskedArray.nanmean(tsr, axis = 1) sal_profSD[b,:] = np.ma.MaskedArray.nanstd(tsr, axis = 1) temp_prof[b,:] = np.ma.MaskedArray.nanmean(tter, axis = 1) temp_profSD[b,:] = np.ma.MaskedArray.nanstd(tter, axis = 1) DIC_prof[b,:] = np.ma.MaskedArray.nanmean(tdr, axis = 1) DIC_profSD[b,:] = np.ma.MaskedArray.nanstd(tdr, axis = 1) TA_prof[b,:] = np.ma.MaskedArray.nanmean(ttar, axis = 1) TA_profSD[b,:] = np.ma.MaskedArray.nanstd(ttar, axis = 1) O2_prof[b,:] = np.ma.MaskedArray.nanmean(to2r, axis = 1) O2_profSD[b,:] = np.ma.MaskedArray.nanstd(to2r, axis = 1) tsra = np.ravel(ts) ttera = np.ravel(tte) tdra = np.ravel(td) * 1e-3 ttara = np.ravel(tta) * 1e-3 tdepthra = np.ravel(tdepth) tpressure = tdepthra tpressure[:] =1 tzero = tdepthra * 0 tsra_psu = tsra*35/35.16504 ttera_is = gsw.t_from_CT(tsra,ttera,tdepthra) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepthra, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb = 'l10', optk1k2='m10', optkf = 'dg', optgas = 'Pinsitu') pH,pco2,fco2,co2,hco3,co3,OmegaA,OmegaC,BetaD,DENis,p,Tis = response_tup pHra = pH.reshape(40,400) OmegaAra = OmegaA.reshape(40,400) pHra[pHra == 1.00000000e+20] = np.nan OmegaAra[OmegaAra == 1.00000000e+20] = np.nan pHra = np.ma.masked_invalid(pHra) OmegaAra = np.ma.masked_invalid(OmegaAra) pH_prof[b,:] = np.ma.MaskedArray.nanmean(pHra, axis = 1) pH_profSD[b,:] = np.ma.MaskedArray.nanstd(pHra, axis = 1) OmA_prof[b,:] = np.ma.MaskedArray.nanmean(OmegaAra, axis = 1) OmA_profSD[b,:] = np.ma.MaskedArray.nanstd(OmegaAra, axis = 1) #depth = w.variables['deptht'][:] sal_prof[sal_prof == 0 ] = np.nan temp_prof[temp_prof == 0 ] = np.nan DIC_prof[DIC_prof == 0 ] = np.nan TA_prof[TA_prof == 0 ] = np.nan pH_prof[pH_prof == 0 ] = np.nan OmA_prof[OmA_prof == 0 ] = np.nan b = b+1 pars_profs = {'sal': sal_prof, 'sal_SD': sal_profSD,\ 'temp': temp_prof, 'temp_SD': temp_profSD,\ 'DIC': DIC_prof, 'DIC_SD' : DIC_profSD,\ 'TA': TA_prof, 'TA_SD' : TA_profSD,\ 'OmA': OmA_prof, 'OmA_SD': OmA_profSD,\ 'pH': pH_prof, 'pH_SD': pH_profSD,\ 'O2' : O2_prof, 'O2_SD': O2_profSD} return pars_profs, stn_list, prof_depth
def point_value(carp, grid, stns): ''' ''' w = carp wp = grid sal = wp.variables['vosaline'][0,:,:,:] temp = wp.variables['votemper'][0,:,:,:] DIC = w.variables['dissolved_inorganic_carbon'][0,:,:,:] TA = w.variables['total_alkalinity'][0,:,:,:] O2 = w.variables['dissolved_oxygen'][0,:,:,:] depth = w.variables['deptht'][:] depth_broadcast = np.zeros([40,20,20]) for i in range(0,40): depth_broadcast[i,:,:] = depth[i] depth_inds = [0,21,26] dum = [0.0,0.0,0.0] pt_depths = np.zeros_like(dum) for i in range(0,len(pt_depths)): di = depth_inds pt_depths[i] = depth[depth_inds[i]] nos = len(stns) stn_list = [] sal_pt = np.zeros([nos,len(depth_inds)]) temp_pt = np.zeros([nos,len(depth_inds)]) DIC_pt = np.zeros([nos,len(depth_inds)]) TA_pt = np.zeros([nos,len(depth_inds)]) pH_pt = np.zeros([nos,len(depth_inds)]) OmA_pt = np.zeros([nos,len(depth_inds)]) O2_pt = np.zeros([nos,len(depth_inds)]) sal_ptSD = np.zeros([nos,len(depth_inds)]) temp_ptSD = np.zeros([nos,len(depth_inds)]) DIC_ptSD = np.zeros([nos,len(depth_inds)]) TA_ptSD = np.zeros([nos,len(depth_inds)]) pH_ptSD = np.zeros([nos,len(depth_inds)]) OmA_ptSD = np.zeros([nos,len(depth_inds)]) O2_ptSD = np.zeros([nos,len(depth_inds)]) b = 0 for s in stns: stn_list.append(s) #print('Calculating point values for ' + stns[s]['fullname']) ty = stns[s]['y'] tx = stns[s]['x'] for d in range(0,len(depth_inds)): dp = depth[depth_inds[d]] ts = sal[d,ty:ty+20,tx:tx+20] tte = temp[d,ty:ty+20,tx:tx+20] td = DIC[d,ty:ty+20,tx:tx+20] tta = TA[d,ty:ty+20,tx:tx+20] to2 = O2[d,ty:ty+20,tx:tx+20] tsr = ts.reshape(1,400) tter = tte.reshape(1,400) tdr = td.reshape(1,400) ttar = tta.reshape(1,400) tdepth = np.zeros_like(ttar) tdepth[:] = dp to2r = to2.reshape(1,400) tsr[tsr == 0] = np.ma.masked tter[tter == 0] = np.ma.masked tdr[tdr == 0] = np.ma.masked ttar[ttar == 0] = np.ma.masked sal_pt[b,d] = np.ma.MaskedArray.nanmean(tsr, axis = 1) sal_ptSD[b,d] = np.ma.MaskedArray.nanstd(tsr, axis = 1) temp_pt[b,:] = np.ma.MaskedArray.nanmean(tter, axis = 1) temp_ptSD[b,d] = np.ma.MaskedArray.nanstd(tter, axis = 1) DIC_pt[b,d] = np.ma.MaskedArray.nanmean(tdr, axis = 1) DIC_ptSD[b,d] = np.ma.MaskedArray.nanstd(tdr, axis = 1) TA_pt[b,d] = np.ma.MaskedArray.nanmean(ttar, axis = 1) TA_ptSD[b,d] = np.ma.MaskedArray.nanstd(ttar, axis = 1) O2_pt[b,d] = np.ma.MaskedArray.nanmean(to2r, axis = 1) O2_ptSD[b,d] = np.ma.MaskedArray.nanstd(to2r, axis = 1) tsra = np.ravel(ts) ttera = np.ravel(tte) tdra = np.ravel(td) * 1e-3 ttara = np.ravel(tta) * 1e-3 tdepthra = np.ravel(tdepth) tpressure = np.zeros_like(tdepthra) tpressure[:] =1 tzero = tdepthra * 0 tsra_psu = tsra*35/35.16504 ttera_is = gsw.t_from_CT(tsra,ttera,tdepthra) response_tup = mocsy.mvars(temp=ttera_is, sal=tsra_psu, alk=ttara, dic=tdra, sil=tzero, phos=tzero, patm=tpressure, depth=tdepthra, lat=tzero, optcon='mol/m3', optt='Tinsitu', optp='m', optb = 'l10', optk1k2='m10', optkf = 'dg', optgas = 'Pinsitu') pH,pco2,fco2,co2,hco3,co3,OmegaA,OmegaC,BetaD,DENis,p,Tis = response_tup pHra = pH.reshape(1,400) OmegaAra = OmegaA.reshape(1,400) pHra[pHra == 1.00000000e+20] = np.nan OmegaAra[OmegaAra == 1.00000000e+20] = np.nan pHra = np.ma.masked_invalid(pHra) OmegaAra = np.ma.masked_invalid(OmegaAra) pH_pt[b,d] = np.ma.MaskedArray.nanmean(pHra, axis = 1) pH_pt[b,d] = np.ma.MaskedArray.nanstd(pHra, axis = 1) OmA_pt[b,d] = np.ma.MaskedArray.nanmean(OmegaAra, axis = 1) OmA_pt[b,d] = np.ma.MaskedArray.nanstd(OmegaAra, axis = 1) sal_pt[sal_pt == 0 ] = np.nan temp_pt[temp_pt == 0 ] = np.nan DIC_pt[DIC_pt == 0 ] = np.nan TA_pt[TA_pt == 0 ] = np.nan pH_pt[pH_pt == 0 ] = np.nan OmA_pt[OmA_pt == 0 ] = np.nan wb = b+1 pars_pts = {'sal': sal_pt, 'sal_SD': sal_ptSD,\ 'temp': temp_pt, 'temp_SD': temp_ptSD,\ 'DIC': DIC_pt, 'DIC_SD' : DIC_ptSD,\ 'TA': TA_pt, 'TA_SD' : TA_ptSD,\ 'OmA': OmA_pt, 'OmA_SD': OmA_ptSD,\ 'pH': pH_pt, 'pH_SD': pH_ptSD,\ 'O2' : O2_pt, 'O2_SD': O2_ptSD} return pars_pts, pt_depths, stn_list