def refstate_meandensity(rho_in,grd,area_xyz_in): # refstate_meandensity(rho,zlev,area_xyz) ################################################ # written by : Gabriel Wolf, g.a.wolf@reading.ac.uk # adapted from get_refstate_meandensity.m of Remi Tailleux (10.04.2013) # last modified : 20.09.2018 # Content/Description #################################################################### # Usage : from gw_ocean_refstate import refstate_meandensity # Input : area_xyz, rho, zlev # area_xyz : hor. area for 3d grid [m**2], 3d # rho : density [kg m**-3], 3d # grd : Input grid [python class] # Output : pp_rhor # pp_rhor : interpolant for reference state # ######################################################################################## # Load modules import numpy as np from scipy import interpolate import pickle # To load interpolants of bathymetry data # Allocation rhor = np.zeros([grd.Nz,1]) # compute hor. averaged density field rho_surf = area_xyz_in*rho_in mask = np.isfinite(rho_surf) rhor = sum(sum(mask*rho_surf,1),0)/sum(sum(area_xyz_in*mask,1),0) # define arrays for interpolation of density profiles pp_rhor = interpolate.PchipInterpolator(grd.z, rhor, axis=0) # return interpolant for reference state return pp_rhor def refstate_sorted_stheta(th,s,rho,mask,ztarget,grd,sbin=[0.0,43.0,0.002],\ thbin=[-2.6,30.0,0.005],ref_EOS='jackettetal2004',test=False,case_str=[]): # refstate_sorted_stheta(th,s,rho,mask,ztarget,grd,test) ################################# # written by : Gabriel Wolf, g.a.wolf@reading.ac.uk # adapted from get_refstate_sorted.m of Remi Tailleux (10.04.2013) # last modified : 24.09.2018 # Content/Description #################################################################### # Reference : method based on Tailleux (2013), -> https://doi.org/10.1017/jfm.2013.509 # : summary of this framework in Saenz et al. (2015): # -> https://doi.org/10.1175/JPO-D-14-0105.1 # Usage : from gw_ocean_refstate import refstate_sorted_stheta # Input : grd, mask, ,ref_equofstate, rho, s, sbin, test, thbin, th, ztarget # grd : Input grid [python class] # mask : valid points [boolean], 3d # ref_EOS : defines equ. of state [reference] # : reference def. by publication, e.g. author1year for one author-public., # : author1andauthor2year for 2-author-public. or author1etalyear for more # : than 2 authors # rho : density [kg m**-3], 3d # s : salinity [psu], 3d # sbin : bin range for s to construct s-th-diagram [min,max,delta] # test : further test plotting and value checking [boolean], 1d # th : potential temperature [deg C], 3d # thbin : bin range for th to construct s-th-diagram [min,max,delta] # ztarget : target height level [m], 1d # Output :pp_rhor_botup, pp_rhor_topdn # pp_rhor_botup : interpolant for density reference state (calc. from bottom up) # pp_rhor_topdn : interpolant for density reference state (calc. from bottom up) # Testing : plot_sth_pdf # plot_sth_pdf : plotting of sorted ocena-volumes in the S-TH-diagram # ######################################################################################## # Testing variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% plot_sth_pdf = 1*test if plot_sth_pdf == 1: print ' Create test plot for sorted ocean-volumes in S-Th-diagram' from myplot import myplot_2d # Load modules %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% import numpy as np from scipy import interpolate # for interpolation from mycalc_ocean import calc_rho_from_theta, volume_census_levitus # calc_rho_from_theta : to calculate density from pot. temperature # volume_census_levitus : to create s-th-pdf with vol info from myconstants import rho0, grav # necessary constants # Allocation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% n_target = len(ztarget) s[mask==False] = np.nan th[mask==False] = np.nan rho[mask==False] = np.nan # Compute the pdf of the salinity/theta data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% try: import pickle with open('data_pdf_salth' + case_str + '.pickle', 'rb') as data_pdf: dummy = pickle.load(data_pdf) pdf_vol_lev = dummy[0] vol_tot_ocean = dummy[1] del dummy, data_pdf pdf_vol_lev_norm = pdf_vol_lev/vol_tot_ocean except: pdf_vol_lev, vol_tot_ocean = volume_census_levitus(th, s, grd, thbin, sbin) print ' Total volume ocean: ' + str(vol_tot_ocean) + ' m**3' pdf_vol_lev_norm = pdf_vol_lev/vol_tot_ocean import pickle with open('data_pdf_salth' + case_str + '.pickle', 'wb') as output: pdf_salth = [pdf_vol_lev, vol_tot_ocean] pickle.dump(pdf_salth, output, -1) # Define properties of the binned temperature/salinity data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% print ' *** MISSING: property definition of binned temperature/salinity data ***' n_sbin, n_thbin = pdf_vol_lev.shape s_axis = np.arange(sbin[0]+sbin[2]*0.5,sbin[1],sbin[2]) th_axis = np.arange(thbin[0]+thbin[2]*0.5,thbin[1],thbin[2]) # Testing pdf-output (pdf_vol_lev_norm) if plot_sth_pdf: d_step = 1 xxx = np.arange(sbin[0],sbin[1],sbin[2]*d_step) yyy = yyy=np.arange(thbin[0],thbin[1],thbin[2]*d_step) ddd = pdf_vol_lev_norm[::d_step,::d_step] ddd[ddd==0] = np.nan ddd = np.log10(ddd) print 'np.nanmax(ddd) = ',np.nanmax(ddd) import datetime plotname = 'Testplot_for_oceanvol_in_s_th_diagram_' + \ str(datetime.date.today()) + case_str + '.png' myplot_2d(xxx,yyy,ddd.T,xlabel_c='salinity [psu]',ylabel_c='potential temp. [deg C]',\ plotname=plotname,saveplot=1,FS=14,d_xtick=0.2,title_c='S-TH',\ cbarlabel_c='Volume freq. distribution [log_10]') #import pdb #pdb.set_trace() #iprint 'stop here' del xxx, yyy, ddd # define target pressure from target depths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ptarget = rho0 * grav * ztarget / 1e4 n_target = len(ptarget) print ' *** why using constant density for target pressure and not variable one? ***' # Seek the global min. and max. of density by bringing all parcels to the ocean surface # (to find min.) and to ocean bottom (to find max.) -------------------------------------- # Allocation rho_theta_surf = rho rho_theta_deep = rho p_surf = np.ones([grd.Nlon,grd.Nlat,grd.Nz])*ptarget[0] p_deep = np.ones([grd.Nlon,grd.Nlat,grd.Nz])*ptarget[-1] # Compute potential density reference to target pressure at surface rho_theta_surf[mask] = calc_rho_from_theta(s[mask],th[mask],p_surf[mask],reference=ref_EOS) # Compute potential density referenced to last target pressure rho_theta_deep[mask] = calc_rho_from_theta(s[mask],th[mask],p_deep[mask],reference=ref_EOS) # Compute global density minimum and maximum rho_min = np.min(rho_theta_surf[mask]) rho_max = np.max(rho_theta_deep[mask]) # Compute upper and lower salinity curves in theta/salt space %%%%%%%%%%%%%%%%%%%%%%%%%%%% # Allocation s_lower = np.zeros(n_thbin) s_upper = np.zeros(n_thbin) # Computation s_lower = calc_sal_from_rho(rho_min,th_axis,ptarget[0],reference=ref_EOS) s_upper = calc_sal_from_rho(rho_max,th_axis,ptarget[-1],reference=ref_EOS) # Compute the topography statistics %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% print ' Load topographic data for z-dependent ocean area and volume' # Load or calculate z-dep. ocean area/volume fn_topo = 'interp_of_topo' + '.pickle' try: with open(fn_topo, 'rb') as data_interp: dummy = pickle.load(data_interp) pp_area = dummy[0] pp_volume = dummy[1] del dummy, data_interp except: print ' -> Data could not be loaded. Therefore it will be calculated.' pp_area, pp_volume = volume_etopo(fn_topo) del fn_topo # define z-dep. volume and its fraction vol_target = pp_volume(ztarget) frac_vol_target = vol_target/vol_target[-1] # New attempt to compute the top-down profile %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% print ' Computing top-down profile for reference density' # Allocation/Initialization rhor_topdn = np.zeros(n_target) rhor_topdn[0] = rho_min rhor_topdn[-1] = rho_max s_curves_td = np.zeros([n_target,n_thbin]) s_curves_td[0,:] = s_lower s_curves_td[-1,:] = s_upper scurv = np.copy(s_lower) rho_l = np.copy(rho_min) # Use optimization method to converge to correct salinity curve print ' *** this loop is not necessary ***' for i_iter in range(0,n_target-1): rho_u = calc_rho_from_theta(sbin[1],thbin[0],ptarget[i_iter+1]) func = lambda rho_i : volume_from_sth(rho_i, pdf_vol_lev_norm,\ th_axis, ptarget[i_iter+1], scurv, sbin) - \ (frac_vol_target[i_iter+1]-frac_vol_target[i_iter]) rhor_topdn[i_iter+1] = fsolve(func, np.array([rho_l,rho_u])) s_curves_td[i_iter+1,:] = calc_sal_from_rho(rhor_topdn[i_iter+1]*np.ones(n_thbin),\ th_axis,ptarget[i_iter+1]*np.ones(n_thbin)) s_curv = s_curves_td[i_iter+1,:] rho_l = rhor_topdn[i_iter+1] print ' -> [iter(target) rhor_topdn(iter) rho_l rho_u]',\ [i_iter,rhor_topdn[i_iter+1],rho_l, rho_u] # New attempt at computing bottom-up profile %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% print ' *** MISSING: rhor bottom-up profile ***' print ' Computing bottom-up profile for reference density' # Allocation/Initialization rhor_botup = np.zeros(n_target) rhor_botup[0] = rho_min rhor_botup[-1] = rho_max s_curves_bu = np.zeros([n_target,n_thbin]) s_curves_bu[0,:] = s_lower s_curves_bu[-1,:] = s_upper scurv = np.copy(s_upper) rho_u = np.copy(rho_max) # Use optimization method to converge to correct salinity curve print ' *** this loop is not necessary ***' for i_iter in range(n_target-1,1,-1): rho_l = calc_rho_from_theta(sbin[0],thbin[1],ptarget[i_iter-1]) func = lambda rho_i : vol_from_sth(rho_i, pdf_vol_lev_norm,\ th_axis, ptarget[i_iter-1],scurv, sbin) - \ (frac_vol_target[i_iter]-frac_vol_target[i_iter-1]) rhor_botup[i_iter+1] = fsolve(func, np.array([rho_l,rho_u])) s_curves_bu[i_iter-1,:] = calc_sal_from_rho(rhor_botup[i_iter-1]*np.ones(n_thbin),\ th_axis,ptarget[i_iter-1]*np.ones(n_thbin)) s_curv = s_curves_bu[i_iter-1,:] rho_u = rhor_botup[i_iter-1] print ' -> [iter(target) rhor_botup(iter) rho_l rho_u]',\ [i_iter,rhor_botup[i_iter+1],rho_l, rho_u] # Assign interpolants for the two possible reference states %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pp_rhor_botup = interpolate.PchipInterpolator(ztarget, rhor_botup, axis=0) pp_rhor_topdn = interpolate.PchipInterpolator(ztarget, rhor_topdn, axis=0) # return interpolant for the two reference states %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% return pp_rhor_botup, pp_rhor_topdn