def __calc_pressure(depth, latitude): pressure = [] try: pressure = [seawater.pres(d, latitude) for d in depth] except TypeError: pressure = seawater.pres(depth, latitude) return np.array(pressure)
def load_data(self): super(SoundSpeedPlotter, self).load_data() self.pressure = [ seawater.pres(self.temperature_depths[idx], ll[0]) for idx, ll in enumerate(self.points) ] ureg = pint.UnitRegistry() try: u = ureg.parse_units(self.variable_units[0].lower()) except: u = ureg.dimensionless if u == ureg.boltzmann_constant: u = ureg.kelvin if u == ureg.kelvin: unit = "Celsius" temperature_c = ureg.Quantity(self.temperature, u).to(ureg.celsius).magnitude else: temperature_c = self.temperature self.sspeed = seawater.svel(self.salinity, temperature_c, self.pressure)
def pressure(filename, yS, yN): avg_lat = (yS + yN) / 2.0 depths = depth_list(filename) pressure = sw.pres(depths, avg_lat) return pressure
def plot_fun(i): print(i) f=plt.figure(figsize=(25/2.539,15/2.536)) ax=plt.axes([.13,.11,.8825,.8125]) if coastflag: plotcoast(ax,filename='mid_nwatl6c_sjh_lr.nc', filepath=coastpath, color='k', fill=True) pres=sw.pres(data['h'],data['lat']) dens=sw.dens(data['salinity'][i,layer,:],data['temp'][i,layer,:],pres) triax=ax.tripcolor(data['trigrid'],dens,vmin=cmin,vmax=cmax) if vectorflag: Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],data['u'][i,layer,vidx],data['v'][i,layer,vidx],angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.001) qaxk=ax.quiverkey(Q1,.9,.88,2, r'2 ms$^{-1}$') if uniformvectorflag: norm=np.sqrt(data['u'][i,layer,vidx]**2+data['v'][i,layer,vidx]**2) Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],np.divide(data['u'][i,layer,vidx],norm),np.divide(data['v'][i,layer,vidx],norm),angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.002,color='k') cb=plt.colorbar(triax) cb.set_label(r'Density (kg m$^{3}$)',fontsize=10) ax.set_xlabel(r'Longitude ($^{\circ}$)') ax.set_ylabel(r'Latitude ($^{\circ}$)') ax.axis(region['region']) ax.annotate('{} {}'.format(data['Time'][i][:10],data['Time'][i][11:19]),xy=(.425,.93),xycoords='axes fraction') for label in ax.get_xticklabels()[::2]: label.set_visible(False) f.savefig(savepath + grid + '_' + region['regionname'] +'_density_' + ("%04d" %(i)) + '.png',dpi=300) plt.close(f)
def processor(input_list): print('Compute ', lout, ' from ', lin) # Select variables votemper = input_list['votemper'] vosaline = input_list['vosaline'] DepthLayers = votemper.DepthLayers LatCells = votemper.LatCells # Replicate geometry 3D (to be updated with complete model geometry variables) if np.ndim(votemper.LatCells) == 1 and np.ndim(votemper.LonCells) == 1 and np.ndim(votemper.DepthLayers) == 1: DepthLayers = np.transpose(np.tile(votemper.DepthLayers, (votemper.LatCells.shape[0], votemper.LonCells.shape[0], 1)), (2, 0, 1)) LatCells = np.transpose(np.tile(votemper.LatCells, (votemper.LonCells.shape[0], 1)), (1, 0)) # Concatenate latitude, longitude and depth cells at the centers of the grid # (COMIC TYPE CHARACTERISTIC reserved procedure) depths = 1 / 4 * (DepthLayers[1:, 1:, 1:] + DepthLayers[: - 1, : - 1, 1:] + DepthLayers[: - 1, 1:, : - 1] + DepthLayers[: - 1, : - 1, : - 1]) lats = 1 / 4 * (LatCells[1:, 1:] + LatCells[: - 1, 1:] + LatCells[1:, : - 1] + LatCells[: - 1, : - 1]) # Cut time dimension temp = votemper.COSM[0, ...] salt = vosaline.COSM[0, ...] # Compute Pressure 3D pressure = sw.pres(depths, lats) # Compute Potential Density field 3D density = ma.array(np.empty(shape=votemper.COSM.shape), mask=False, fill_value=1.e20, dtype=float) density[0, ...] = sw.dens(salt, temp, pressure) # Attributes of Characteristic class are (StandardName, # VariableName, DepthLayers, LonCells, LatCells, TimeCells, ConcatenatioOfSpatialMaps, MaskedAs=None) potential_d = sp_type.Characteristic(StandardName='sea_water_density', VariableName='vodnsity', DepthLayers=votemper.DepthLayers, LonCells=votemper.LonCells, LatCells=votemper.LatCells, TimeCells=votemper.TimeCells, ConcatenatioOfSpatialMaps=density) return potential_d
def get_full(fn): # gets v_dict for the full extent of one history file ds = nc.Dataset(fn) G, S, T = zrfun.get_basic_info(fn) # extract needed info from history file v_dict = dict() if print_info: print('\nINPUT Variable Info:') for vn in ['alkalinity', 'TIC', 'salt', 'temp','rho']: v = ds[vn][:] v = fillit(v) v_dict[vn] = v # create depth, pressure, and in situ temperature h = ds['h'][:] h = fillit(h) lat = G['lat_rho'][:] z_rho = zrfun.get_z(h, 0*h, S, only_rho=True) depth = -z_rho pres = sw.pres(depth, lat) v_dict['pres'] = pres temp = sw.ptmp(v_dict['salt'], v_dict['temp'], 0, v_dict['pres']) v_dict['temp'] = temp # convert from umol/L to umol/kg using in situ dentity v_dict['alkalinity'] = 1000 * v_dict['alkalinity'] / (v_dict['rho'] + 1000) v_dict['TIC'] = 1000 * v_dict['TIC'] / (v_dict['rho'] + 1000) # clean up v_dict.pop('rho') # no longer needed, so don't pass to worker ds.close() return v_dict
def sspeed(depth, latitude, temperature, salinity): """ Calculates the speed of sound. Parameters: depth: The depth(s) in meters latitude: The latitude(s) in degrees North temperature: The temperatures(s) in Celsius salinity: The salinity (unitless) """ try: press = [seawater.pres(d, latitude) for d in depth] except TypeError: press = seawater.pres(depth, latitude) speed = seawater.svel(salinity, temperature, press) return np.array(speed)
def buoy_calc(Z, EOS, T=None, S=None, alpha=None, sbeta=None, g=None, lat=None, Tref=None, Sref=None): """Calculate the buoyancy given the temperature T, salinity S,depth, specified equation of state, thermal expansion coefficient (if necessary) haline coefficient (if necessary) and latitude (if necessary)""" if g is None: g = 9.81 if EOS == 'lin': """Set default parameters if not otherwise specified""" if g is None: g = 9.81 if alpha is None: alpha = 2e-4 if sbeta is None: sbeta = 7.4e-4 if Tref is None: Tref = 0 if Sref is None: Sref = 0 #Calculate the buoyancy contributions where relevant if S is None and T is not None: """Thermal contribution only""" buoy = g * alpha * (T - Tref) if T is None and S is not None: """Haline contribution only""" buoy = -g * sbeta * (S - Sref) if T is not None and S is not None: buoy = g * alpha * (T - Tref) - g * sbeta * (S - Sref) if EOS == 'jmd': import jmd95 import seawater if T is None: T = np.zeros(np.shape(S)) if S is None: S = np.zeros(np.shape(T)) rhoConst = 1000 #Pressure needed in decibars press = seawater.pres(-Z, 45) #Loop this routine along t and y to avoid running out of memory sp = np.shape(S) buoy = np.empty(np.shape(S)) for ti in np.arange(0, sp[-1]): for rw in np.arange(0, sp[0]): buoy_fac = g / rhoConst b = -buoy_fac * (jmd95.densjmd95(np.squeeze( S[rw, :, :, ti]), np.squeeze(T[rw, :, :, ti]), press) - 1030) buoy[rw, :, :, ti] = b return buoy
def load_data(self): super(SoundSpeedPlotter, self).load_data() self.pressure = [seawater.pres(self.temperature_depths[idx], ll[0]) for idx, ll in enumerate(self.points)] self.sspeed = seawater.svel( self.salinity, self.temperature, self.pressure )
def load_data(self): super(SoundSpeedPlotter, self).load_data() self.pressure = [ seawater.pres(self.temperature_depths[idx], ll[0]) for idx, ll in enumerate(self.points) ] self.sspeed = seawater.svel(self.salinity, self.temperature, self.pressure)
def select_field(data, field, i, layer='da'): """ Helper function to select the correct field and name for the field """ fn = {'temp' : r'Temperature ($^{\circ}$)', 'salinity' : r'Salinity (PSU)', 'speed' : r'Speed (m/s)', 'u' : r'U-Velocity (m/s)', 'v' : r'V-Velocity (m/s)', 'vorticity' : r'Vorticity', 'density' : r'Density (kg m$^{3}$)', 'zeta' : 'Elevation (m)'} if 'speed' in field: if layer=='da': fieldout = np.sqrt(data['ua'][i,:]**2 + data['va'][i,:]**2) else: fieldout = np.sqrt(data['u'][i,layer,:]**2 + data['v'][i,layer,:]**2) elif 'vorticity' in field: if layer=='da': dudy = data['a2u'][0,:]*data['ua'][i,:]+data['a2u'][1,:]*data['ua'][i,data['nbe'][:,0]] +\ data['a2u'][2,:]*data['ua'][i,data['nbe'][:,1]]+data['a2u'][3,:]*data['ua'][i,data['nbe'][:,2]] dvdx = data['a1u'][0,:]*data['va'][i,:]+data['a1u'][1,:]*data['va'][i,data['nbe'][:,0]] +\ data['a1u'][2,:]*data['va'][i,data['nbe'][:,1]]+data['a1u'][3,:]*data['va'][i,data['nbe'][:,2]] else: dudy = data['a2u'][0,:]*data['u'][i,layer,:]+data['a2u'][1,:]*data['u'][i,layer,data['nbe'][:,0]] +\ data['a2u'][2,:]*data['u'][i,layer,data['nbe'][:,1]]+data['a2u'][3,:]*data['u'][i,layer,data['nbe'][:,2]] dvdx = data['a1u'][0,:]*data['v'][i,layer,:]+data['a1u'][1,:]*data['v'][i,layer,data['nbe'][:,0]] +\ data['a1u'][2,:]*data['v'][i,layer,data['nbe'][:,1]]+data['a1u'][3,:]*data['v'][i,layer,data['nbe'][:,2]] fieldout = dvdx - dudy elif 'density' in field: if layer==None: print("Can't get density for layer None. Using layer=0.") layer = 0 pres = sw.pres(data['h']+data['zeta'][i,:],data['lat']) fieldout = sw.dens(data['salinity'][i,layer,:],data['temp'][i,layer,:],pres) else: if layer=='da': fieldout = data[field][i,:] else: fieldout = data[field][i,layer,:] try: fieldname = fn[field] except KeyError: fieldname = field return fieldout, fieldname
def plot_fun(i): print(i) f = plt.figure(figsize=(25 / 2.539, 15 / 2.536)) ax = plt.axes([.13, .11, .8825, .8125]) if coastflag: plotcoast(ax, filename='mid_nwatl6c_sjh_lr.nc', filepath=coastpath, color='k', fill=True) pres = sw.pres(data['h'], data['lat']) dens = sw.dens(data['salinity'][i, layer, :], data['temp'][i, layer, :], pres) triax = ax.tripcolor(data['trigrid'], dens, vmin=cmin, vmax=cmax) if vectorflag: Q1 = ax.quiver(data['uvnodell'][vidx, 0], data['uvnodell'][vidx, 1], data['u'][i, layer, vidx], data['v'][i, layer, vidx], angles='xy', scale_units='xy', scale=vector_scale, zorder=100, width=.001) qaxk = ax.quiverkey(Q1, .9, .88, 2, r'2 ms$^{-1}$') if uniformvectorflag: norm = np.sqrt(data['u'][i, layer, vidx]**2 + data['v'][i, layer, vidx]**2) Q1 = ax.quiver(data['uvnodell'][vidx, 0], data['uvnodell'][vidx, 1], np.divide(data['u'][i, layer, vidx], norm), np.divide(data['v'][i, layer, vidx], norm), angles='xy', scale_units='xy', scale=vector_scale, zorder=100, width=.002, color='k') cb = plt.colorbar(triax) cb.set_label(r'Density (kg m$^{3}$)', fontsize=10) ax.set_xlabel(r'Longitude ($^{\circ}$)') ax.set_ylabel(r'Latitude ($^{\circ}$)') ax.axis(region['region']) ax.annotate('{} {}'.format(data['Time'][i][:10], data['Time'][i][11:19]), xy=(.425, .93), xycoords='axes fraction') for label in ax.get_xticklabels()[::2]: label.set_visible(False) f.savefig(savepath + grid + '_' + region['regionname'] + '_density_' + ("%04d" % (i)) + '.png', dpi=300) plt.close(f)
def buoy_dgl(dgl, eos, alpha=None, sbeta=None, g=None, lat=None, Tref=None, Sref=None): """Calculate the buoyancy field for a structured array dgl""" import mit b_exists = mit.check_field(dgl, 'b') if not b_exists: dgl = mit.add_field(dgl, 'b') S_exists = mit.check_field(dgl, 's') T_exists = mit.check_field(dgl, 't') if eos == 'lin': alpha, sbeta, g, Tref, Sref = lin_eos_params(alpha, sbeta, g, lat, Tref, Sref) for rw in np.arange(0, len(dgl[0]['y'])): if T_exists and not S_exists: """Thermal contribution only""" dgl[0]['b'][rw, :, :, :] = g * alpha * ( dgl[0]['t'][rw, :, :, :] - Tref) if S_exists and not T_exists: """Haline contribution only""" dgl[0]['b'][rw, :, :, :] = -g * sbeta * ( dgl[0]['s'][rw, :, :, :] - Sref) if T_exists and S_exists: dgl[0]['b'][rw, :, :, :] = g * alpha * ( dgl[0]['t'][rw, :, :, :] - Tref) -g * sbeta * (dgl[0]['s'][rw, :, :, :] - Sref) elif eos == 'jmd': g = 9.81 import jmd95 import seawater import mit if not T_exists: T = np.zeros(np.shape(dgl[0]['s'])) if not S_exists: S = np.zeros(np.shape(dgl[0]['t'])) rhoConst = 1000 ylen, xlen, zlen, tlen = mit.dgl_dims(dgl) #Pressure needed in decibars press = seawater.pres(-dgl[0]['z'], lat=45) buoy_fac = g / rhoConst #Loop this routine along t and y to avoid running out of memory for ti in np.arange(0, tlen): for rw in np.arange(0, ylen): dgl[0]['b'][rw, :, :, ti] = -buoy_fac * (jmd95.densjmd95( np.squeeze(dgl[0]['s'][rw, :, :, ti]), np.squeeze(dgl[0]['t'][rw, :, :, ti]), press) - 1030) return dgl
def get_SG(file, get_data=True, get_dives=None, remove_seawater=False, wavelength=700): with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) warnings.simplefilter("ignore", category=RuntimeWarning) nc = Dataset(file, 'r') inds = np.arange(len( nc.variables['time'])) if get_dives is None else get_dives rd = dt.datetime(1970, 1, 1) sd = dt.datetime(2018, 1, 1) t = np.nanmedian(nc.variables['time'][inds], axis=1) t = [rd + dt.timedelta(seconds=tt) - sd for tt in t] t = np.array([tt.days + tt.seconds / 86400 for tt in t]) lat = np.nanmedian(nc.variables['lat'][inds], axis=1) lon = np.nanmedian(nc.variables['lon'][inds], axis=1) if get_data: T = np.ma.getdata(nc.variables['T'][inds]) S = np.ma.getdata(nc.variables['S'][inds]) z = np.repeat(np.atleast_2d(np.ma.getdata(nc.variables['z'][:])), T.shape[0], axis=0) if remove_seawater: VSF_sw = betasw_wetlabs(700, 20, 124, 41, T, S, sw.pres(z, lat=50.5)) else: VSF_sw = 0 VSF = np.ma.getdata( nc.variables['baseline_%03dnm' % wavelength][inds]) - VSF_sw bad_inds = (t > END_DATE) # beyond time of the main EXPORTS experiment t = t[~bad_inds] lat = lat[~bad_inds] lon = lon[~bad_inds] inds = inds[~bad_inds] if get_data: T = T[~bad_inds] S = S[~bad_inds] VSF = VSF[~bad_inds] z = z[~bad_inds] if get_data: return t, lat, lon, inds, T, S, z, VSF else: return t, lat, lon, inds
def buoy_calc(Z, EOS, T = None, S = None, alpha = None, sbeta = None, g = None, lat = None, Tref = None, Sref = None): """Calculate the buoyancy given the temperature T, salinity S,depth, specified equation of state, thermal expansion coefficient (if necessary) haline coefficient (if necessary) and latitude (if necessary)""" if g is None: g = 9.81 if EOS == 'lin': """Set default parameters if not otherwise specified""" if g is None: g = 9.81 if alpha is None: alpha = 2e-4 if sbeta is None: sbeta = 7.4e-4 if Tref is None: Tref = 0 if Sref is None: Sref = 0 #Calculate the buoyancy contributions where relevant if S is None and T is not None: """Thermal contribution only""" buoy = g*alpha*(T - Tref) if T is None and S is not None: """Haline contribution only""" buoy = -g*sbeta*(S - Sref) if T is not None and S is not None: buoy = g*alpha*(T - Tref) -g*sbeta*(S - Sref) if EOS == 'jmd': import jmd95 import seawater if T is None: T = np.zeros(np.shape(S)) if S is None: S = np.zeros(np.shape(T)) rhoConst = 1000 #Pressure needed in decibars press = seawater.pres(-Z,45) #Loop this routine along t and y to avoid running out of memory sp = np.shape(S) buoy = np.empty(np.shape(S)) for ti in np.arange(0,sp[-1]): for rw in np.arange(0,sp[0]): buoy_fac = g/rhoConst b =-buoy_fac*(jmd95.densjmd95(np.squeeze(S[rw,:,:,ti]), np.squeeze(T[rw,:,:,ti]),press) - 1030) buoy[rw,:,:,ti] = b return buoy
def get_WW(files, get_data=True, get_dives=None, remove_seawater=False, VSF_dark=0): SB_files = np.sort(glob.glob(files)) if get_dives is not None: SB_files = SB_files[get_dives.astype('int32')] lat = () lon = () t = () sta = () if get_data: T = () S = () z = () VSF = () for i in range(len(SB_files)): SB = readSB(SB_files[i], no_warn=True) lat += (get_startlat(SB), ) lon += (get_startlon(SB), ) t += (get_starttime(SB), ) sta += (i, ) if get_data: T += (np.array(SB.data['wt']), ) S += (np.array(SB.data['sal']), ) z += (np.array(SB.data['depth']), ) if remove_seawater: VSF_sw = betasw_wetlabs(700, 20, 124, 41, T[-1], S[-1], sw.pres(z[-1], lat=50.5)) else: VSF_sw = 0 VSF += (np.array(SB.data['bbp700']) / (np.pi * 2 * 1.1) - VSF_sw - VSF_dark, ) # convert using chi factor for 124deg angle used here output = (np.array(t, dtype='object'), np.array(lat, dtype='object'), np.array(lon, dtype='object'), np.array(sta, dtype='object')) if get_data: output += ( np.array(T, dtype='object'), np.array(S, dtype='object'), np.array(z, dtype='object'), np.array(VSF, dtype='object'), ) return output
def calc_atm_equil_methane_depth(temp, sal, fg, depth): ''' Calculate atmospheric equilibrium methane concentration Bunsen - the volume of gas (corrected to st.temp and pressure) absorbed in a unit volume of water at the measured temp when the part.pressure of the gas is 760 mm. Coefficients and bunsen equation are taken from the paper 'Solubility of Methane in Distilled Water and Seawater' 1972 Sachio Yamamoto,' James B. Alcauskas, and Thomas E. Crozier ''' abs_temp = temp + 273.15 # Absoulte Temp Kelvins a1 = -67.1962 a2 = 99.1624 a3 = 27.9015 b1 = -0.072909 b2 = 0.041674 b3 = -0.0064603 #print (temp,sal,depth) ln_bunsen = a1 + a2 * (100. / abs_temp) + a3 * math.log( abs_temp / 100.) + (sal * (b1 + b2 * (abs_temp / 100.) + b3 * ((abs_temp / 100.)**2))) bunsen = math.e**ln_bunsen # p_tot - the total pressure (atm) try: import seawater as sw st_lat = 76.47 p_dbar = sw.pres(depth, st_lat) # dbars p_tot = 0.987 * p_dbar / 10. # convert dbars to atm except ModuleNotFoundError: p_tot = 1 + depth / 10.3 # in atm # fg - the mole fraction of gas (fG) in the dry atmosphere h = 100 # h is the relative humidity (percent) # p_vapor is vapor pressure of the solution (atm). p_vapor = calculate_vapor(temp, sal) # Equation (4) from Weisenburg 1979 c = (bunsen * (p_tot - ((h / 100.) * p_vapor)) * fg * 44.6 * 10**6 ) #(nanomoles) return c #,bunsen
def buoy_dgl(dgl,eos,alpha = None,sbeta = None, g = None, lat = None, Tref = None, Sref = None): """Calculate the buoyancy field for a structured array dgl""" import mit b_exists = mit.check_field(dgl,'b') if not b_exists: dgl = mit.add_field(dgl,'b') S_exists = mit.check_field(dgl,'s') T_exists = mit.check_field(dgl,'t') if eos == 'lin': alpha, sbeta, g, Tref, Sref = lin_eos_params(alpha,sbeta,g,lat,Tref,Sref) for rw in np.arange(0,len(dgl[0]['y'])): if T_exists and not S_exists: """Thermal contribution only""" dgl[0]['b'][rw,:,:,:] = g*alpha*(dgl[0]['t'][rw,:,:,:] - Tref) if S_exists and not T_exists: """Haline contribution only""" dgl[0]['b'][rw,:,:,:] = -g*sbeta*(dgl[0]['s'][rw,:,:,:] - Sref) if T_exists and S_exists: dgl[0]['b'][rw,:,:,:] = g*alpha*(dgl[0]['t'][rw,:,:,:] - Tref) -g*sbeta*(dgl[0]['s'][rw,:,:,:] - Sref) elif eos == 'jmd': g = 9.81 import jmd95 import seawater import mit if not T_exists: T = np.zeros(np.shape(dgl[0]['s'])) if not S_exists: S = np.zeros(np.shape(dgl[0]['t'])) rhoConst = 1000 ylen, xlen, zlen, tlen = mit.dgl_dims(dgl) #Pressure needed in decibars press = seawater.pres(-dgl[0]['z'],lat = 45) buoy_fac = g/rhoConst #Loop this routine along t and y to avoid running out of memory for ti in np.arange(0,tlen): for rw in np.arange(0,ylen): dgl[0]['b'][rw,:,:,ti] =-buoy_fac*(jmd95.densjmd95( np.squeeze(dgl[0]['s'][rw,:,:,ti]), np.squeeze(dgl[0]['t'][rw,:,:,ti]),press) - 1030) return dgl
def conv_v02(): ''' conv_v02 Takes a v01 DB and converts it to a v02 DB. v02: - contains sigmaT data, as calculated by seawater package ''' global CTD_DAT, STANDARD_KEYS print( '> Converting to v02') print('> Appending calculated sigmaT values') for cast in CTD_DAT: P = SW.pres(cast['Depth'],cast['Latitude']) cast['sigmaT'] = SW.dens(cast['Salinity'],cast['Temperature'],P)-1000 inds = ~np.isnan(cast['sigmaT']) cast['sigmaT'] = np.interp(np.arange(0,len(cast['sigmaT'])),np.arange(0,len(cast['sigmaT']))[inds],cast['sigmaT'][inds]) print('> Complete')
def makeTSPlot(float_data, units, cmax=500, close_all=False): if close_all: plt.close('all') # ymin = np.floor(min(float_data['Temperature'])) # ymax = np.ceil(max(float_data['Temperature'])) ymin = -2 ymax = 15 xmin = 33.5 xmax = 35.5 # pmin = np.floor(min(float_data['Density'])) # pmax = np.ceil(max(float_data['Density'])) pmin = 25 pmax = 28.5 #plot sample data plt.figure() pres = sw.pres(float_data['Depth'], float_data['Lat']) ptemp = sw.ptmp(float_data['Salinity'], float_data['Temperature'], pres, 0) plt.scatter(float_data['Salinity'], ptemp, c=float_data['Depth'], lw=0, cmap=plt.cm.rainbow, vmin=0, vmax=cmax) plt.ylabel('Pot. Temperature (%s)' %units['Temperature']) plt.xlabel('Salinity (PSS)') plt.title("T vs. S for SOCCOM float '%s'" %float_data['Cruise'][0]) plt.clim(cmax, 0) plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) cbar = plt.colorbar(extend='max') cbar.ax.set_ylabel('Depth (%s)' %units['Depth']) #add density lines temps = np.arange(ymin, ymax,0.1) sals = np.arange(xmin, xmax, 0.1) sal_grid, temp_grid = np.meshgrid(np.ma.masked_invalid(sals), np.ma.masked_invalid(temps)) pdens_grid= sw.dens(sal_grid, temp_grid, 0)-1000 plvls = np.arange(pmin, pmax, 0.2) cs = plt.contour(sal_grid, temp_grid, pdens_grid, plvls, colors='0.5',linewidth=0.5) plt.clabel(cs, inline=1, fontsize=10,fmt='%1.1f',inline_spacing=10) plt.show()
## Get data from dives data1 = func1(files1,get_dives=data1_loc[3][inds1]) data2 = func2(files2,get_dives=data2_loc[3][inds2]) ## filter all data with median filters good_inds_1 = [np.isfinite(np.array(T.astype('float32'))) & np.isfinite(np.array(S.astype('float32'))) & np.isfinite(np.array(b.astype('float32'))) for T,S,b in zip(data1[4],data1[5],data1[7])] if inst1 == 'BB2FLSG': # Seaglider VSF data is already filtered filtered_dep1 = [var[i] for var,i in zip(data1[6],good_inds_1)] filtered_VSF1 = [var[i] for var,i in zip(data1[7],good_inds_1)] else: filtered_dep1 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data1[6],good_inds_1)] filtered_VSF1 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data1[7],good_inds_1)] filtered_T1 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep1,data1[6],data1[4],good_inds_1)] filtered_S1 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep1,data1[6],data1[5],good_inds_1)] filtered_dens1 = [sw.pden(S,T,sw.pres(z,lat=CENTRAL_LAT)) for T,S,z in zip(filtered_T1,filtered_S1,filtered_dep1)] good_inds_2 = [np.isfinite(T.astype('float32')) & np.isfinite(S.astype('float32')) & np.isfinite(b.astype('float32')) for T,S,b in zip(data2[4],data2[5],data2[7])] if inst2 == 'BB2FLSG': # Seaglider VSF data is already filtered filtered_dep2 = [var[i] for var,i in zip(data2[6],good_inds_2)] filtered_VSF2 = [var[i] for var,i in zip(data2[7],good_inds_2)] else: filtered_dep2 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data2[6],good_inds_2)] filtered_VSF2 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data2[7],good_inds_2)] filtered_T2 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep2,data2[6],data2[4],good_inds_2)] filtered_S2 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep2,data2[6],data2[5],good_inds_2)] filtered_dens2 = [sw.pden(S,T,sw.pres(z,lat=CENTRAL_LAT)) for T,S,z in zip(filtered_T2,filtered_S2,filtered_dep2)]
def makeHeatContent(salt,temp,destMask,thetao,pressure): """ The makeHeatContent() function takes 3D (not temporal) arguments and creates heat content which is then mapped to a destination grid and written to a specified variable Author: Paul J. Durack : [email protected] : @durack1. Created on Tue Nov 24 15:34:30 2015. Inputs: ------ - salt(lev,lat,lon) - 3D array. - temp(lev,lat,lon) - 3D array either in-situ or potential temperature. - destGridArray(str) - 2D array with valid grid and mask. - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided. - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m). Usage: ------ >>> from oceanLib import makeHeatContent >>> makeHeatContent(salt,temp,destGridArray,thetao=True,pressure=False) Notes: ----- - PJD 24 Nov 2015 - Migrated into new oceanLib from heatContentLib - TODO: Better deal with insitu vs thetao variables - TODO: """ # Remap variables to short names #print salt.getAxisIds() s = salt(squeeze=1) ; # Trim off singleton time dimension #print s.getAxisIds() t = temp(squeeze=1) mask = destMask #print mask.getAxisIds() del(salt,temp,destMask) ; gc.collect() depthInd = 0 ; # Set depth coordinate index #print 's: ',s.min(),s.max() #print 't: ',t.min(),t.max() # Fix out of bounds values t = mv.where(t<-2.6,-2.6,t) ; # Fix for NaN values # Calculate pressure - inputs depth & lat # Create z-coordinate from salinity input if not pressure: zCoord = s.getAxis(depthInd) ; # Assume time,depth,latitude,longitude grid yCoord = s.getAxis(depthInd+1) yCoord = tile(yCoord,(s.shape[depthInd+2],1)).transpose() depthLevels = tile(zCoord.getValue(),(s.shape[depthInd+2],s.shape[depthInd+1],1)).transpose() pressureLevels = sw.pres(np.array(depthLevels),np.array(yCoord)) del(zCoord,yCoord,depthLevels) ; gc.collect() else: pressureLevels = s.getAxis(depthInd) #print pressureLevels.getValue() pressureLevels = transpose(tile(pressureLevels,(s.shape[depthInd+2],s.shape[depthInd+1],1))) pressureLevels = cdm.createVariable(pressureLevels,id='pressureLevels') pressureLevels.setAxis(0,s.getAxis(depthInd)) pressureLevels.setAxis(1,s.getAxis(depthInd+1)) pressureLevels.setAxis(2,s.getAxis(depthInd+2)) pressureLevels.units_long = 'decibar (pressure)' pressureLevels.positive = 'down' pressureLevels.long_name = 'sea_water_pressure' pressureLevels.standard_name = 'sea_water_pressure' pressureLevels.units = 'decibar' pressureLevels.axis = 'Z' #print 'pres: ',pressureLevels.min(),pressureLevels.max() #print pressureLevels.shape #print s.shape #print t.shape #print mask.shape # Calculate temp,rho,cp - inputs temp,salt,pressure if thetao: # Process potential temperature to in-situ temp = sw.temp(np.array(s),np.array(t),np.array(pressureLevels)); # units degrees C rho = sw.dens(np.array(s),np.array(temp),np.array(pressureLevels)) ; # units kg m-3 cp = sw.cp(np.array(s),np.array(temp),np.array(pressureLevels)) ; # units J kg-1 C-1 # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp = scrubNaNAndMask(temp,s) rho = scrubNaNAndMask(rho,s) cp = scrubNaNAndMask(cp,s) #print 'temp: ',temp.min(),temp.max() #print 'rho: ',rho.min(),rho.max() #print 'cp: ',cp.min(),cp.max() # Calculate heatContent - inputs temp,rho,cp heatContent = np.array(temp)*np.array(rho)*np.array(cp) ; # units J # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset heatContent = scrubNaNAndMask(heatContent,s) #print 'hc: ',heatContent.min(),heatContent.max() # Interpolate to standard levels - inputs heatContent,levels newDepth = np.array([5,10,20,30,40,50,75,100,125,150,200,300,500,700,1000,1500,1800,2000]).astype('f'); newDepth_bounds = np.array([[0,5],[5,10],[10,20],[20,30],[30,40],[40,50],[50,75],[75,100],[100,125],[125,150], [150,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f') # Interpolate to standard levels #print heatContent.shape #print heatContent.getAxisIds() #print pressureLevels.shape #print pressureLevels.getAxisIds() # Reset variable axes heatContent.setAxis(0,s.getAxis(0)) #heatContent.setAxis(1,s.getAxis(1)) #heatContent.setAxis(2,s.getAxis(2)) pdb.set_trace() heatContent.setGrid(s.getGrid()) #print heatContent.shape #print heatContent.getAxisIds() #print pressureLevels.shape #print pressureLevels.getAxisIds() heatContent_depthInterp = cdu.linearInterpolation(heatContent,pressureLevels,levels=newDepth) # Fix bounds newDepth = heatContent_depthInterp.getAxis(0) newDepth.setBounds(newDepth_bounds) del(newDepth_bounds) newDepth.id = 'depth2' newDepth.units_long = 'decibar (pressure)' newDepth.positive = 'down' newDepth.long_name = 'sea_water_pressure' newDepth.standard_name = 'sea_water_pressure' newDepth.units = 'decibar' newDepth.axis = 'Z' #print 'hc_interp:',heatContent_depthInterp.min(),heatContent_depthInterp.max() # Integrate to 700 dbar - inputs heatContent heatContent_depthInteg = cdu.averager(heatContent_depthInterp[0:14,...],axis=0,weights='weighted',action='sum')(squeeze=1) # Calculate depth-weighted-integrated thetao # Assign all axis info #print heatContent_depthInteg.shape pdb.set_trace() # Interpolate in x,y - inputs heatContent #tmp1 = heatContent_depthInteg.regrid(mask.getGrid(),regridTool='esmf',regridMethod='linear') ; # Use defaults - ,coordSys='deg',diag = {},periodicity=1) tmp1 = heatContent_depthInteg.regrid(mask,regridTool='esmf',regridMethod='linear') ; # Use defaults - ,coordSys='deg',diag = {},periodicity=1) #print tmp1.shape tmp1 = mv.where(tmp1<0,0,tmp1) ; # Fix for negative values # Infill - inputs heatContent # Create inputs for interpolation points = np.zeros([(mask.shape[0]*mask.shape[1]),2]) ; # Create 25380 vectors of lon/lat latcounter = 0 ; loncounter = 0 for count,data in enumerate(points): if not np.mod(count,180) and not count == 0: latcounter = latcounter + 1 loncounter = 0 points[count,0] = mask.getLatitude().getValue()[latcounter] points[count,1] = mask.getLongitude().getValue()[loncounter] loncounter = loncounter + 1 del(count,data,latcounter,loncounter); gc.collect() valid = np.logical_not(tmp1.mask) ; # Get inverted-logic boolean mask from variable if valid.size == 1: print '** No valid mask found, skipping **' return valid = valid.flatten() ; # Flatten 2D to 1D #maskFilled = mask(tmp,points,valid) interpolant = interpolate.LinearNDInterpolator(points[valid,:],np.array(tmp1.flatten())[valid]) ; # Create interpolant maskFill = interpolant(points[:,0].squeeze(),points[:,1].squeeze()) ; # Use interpolant to create filled matrix maskFill = np.reshape(maskFill,mask.shape) ; # Resize to original dimensions # Fix issues with interpolant tmp2 = mv.where(np.isnan(maskFill),1e+20,maskFill) ; # Fix for NaN values tmp2 = mv.where(tmp2>tmp1.max(),0,tmp2) ; # Fix for max values tmp2 = mv.where(tmp2<tmp1.min(),0,tmp2) ; # Fix for min values tmp = mv.masked_where(mask.mask,tmp2) #print tmp.shape # Redress variable heatContent = cdm.createVariable([tmp],id='heatContent') depthInt = cdm.createAxis([350],id='depth') depthInt.setBounds(np.array([0,700])) depthInt.units_long = 'decibar (pressure)' depthInt.positive = 'down' depthInt.long_name = 'sea_water_pressure' depthInt.standard_name = 'sea_water_pressure' depthInt.units = 'decibar' depthInt.axis = 'Z' heatContent.setAxis(0,depthInt) heatContent.setAxis(1,mask.getAxis(0)) heatContent.setAxis(2,mask.getAxis(1)) heatContent.units_long = 'Joules' heatContent.long_name = 'sea_water_heat_content' heatContent.standard_name = 'sea_water_heat_content' heatContent.units = 'J' return heatContent ; #,tmp1 ; # 0-700 dbar standard masked variable
def makeSteric(salinity,salinityChg,temp,tempChg,outFileName,thetao,pressure): """ The makeSteric() function takes 3D (not temporal) arguments and creates heat content and steric fields which are written to a specified outfile Author: Paul J. Durack : [email protected] : @durack1. Created on Thu Jul 18 13:03:37 2013. Inputs: ------ - salinity(lev,lat,lon) - 3D array for the climatological period. - salinityChg(lev,lat,lon) - 3D array for the temporal change period. - temp(lev,lat,lon) - 3D array for the climatological period either in-situ or potential temperature. - tempChg(lev,lat,lon) - 3D array for the temporal change period as with temp, either in-situ or potential temperature. - outFileName(str) - output filename with full path specified. - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided. - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m). Usage: ------ >>> from makeStericLib import makeSteric >>> makeSteric(salinity,salinityChg,thetao,thetaoChg,'outfile.nc',True,False) Notes: ----- - PJD 18 Jul 2013 - Validated Ishii v6.13 data against WOA94 - checks out ok. Units: dyn decimeter compared to http://www.nodc.noaa.gov/OC5/WOA94/dyn.html uses cm (not decimeter; x 10) - PJD 18 Jul 2013 - Added attribute scrub to incoming variables (so,so_chg,temp,temp_chg) to maintain output consistency - PJD 22 Jul 2013 - Added name attributes to so and temp variables, added units to so_chg - PJD 22 Jul 2013 - removed duplicated code by converting repetition to function scrubNaNAndMask - PJD 23 Jul 2013 - Further cleaned up so,so_chg,temp,temp_chg outputs specifying id/name attributes - PJD 5 Aug 2013 - Updated python-seawater library to version 3.3.1 from github repo, git clone http://github.com/ocefpaf/python-seawater, python setup.py install --user - PJD 7 Aug 2013 - FIXED: thetao rather than in-situ temperature propagating throughout calculations - PJD 7 Aug 2013 - Replaced looping with 3D gpan - PJD 7 Aug 2013 - Further code duplication cleanup - PJD 8 Aug 2013 - FIXED: scrubNanAndMask function type/mask/grid issue - encase sw arguments in np.array() (attempt to strip cdms fluff) - PJD 8 Aug 2013 - FIXED: removed depth variable unit edits - not all inputs are depth (m) - PJD 15 Aug 2013 - Increased interpolated field resolution [200,300,500,700,1000,1500,1800,2000] - [5,10,20,30,40,50,75,100,125,150,200, ...] - PJD 18 Aug 2013 - AR5 hard coded rho=1020,cp=4187 == 4.3e6 vs Ishii 1970 rho.mean=1024,cp.mean=3922 == 4.1e6 ~5% too high - PJD 13 Jan 2014 - Corrected steric_height_anom and steric_height_thermo_anom to true anomaly fields, needed to remove climatology - PJD 3 May 2014 - Turned off thetao conversion, although convert to numpy array rather than cdms2 transient variable - PJD 13 Oct 2014 - Added seawater_library_version as a global attribute - PJD 13 Oct 2014 - FIXED: bug with calculation of rho_halo variable was calculating gpan - PJD 13 Oct 2014 - Added alternate calculation of halosteric anomaly (direct salinity anomaly calculation, rather than total-thermosteric) - PJD 13 Oct 2014 - Added makeSteric_version as a global attribute - TODO: Better deal with insitu vs thetao variables - TODO: Query Charles on why *.name attributes are propagating - TODO: validate outputs and compare to matlab versions - 10e-7 errors. """ # Remap all variables to short names so = salinity so_chg = salinityChg temp = temp temp_chg = tempChg del(salinity,salinityChg,tempChg) ; gc.collect() # Strip attributes to maintain consistency between datasets for count,x in enumerate(so.attributes.keys()): delattr(so,x) #print so.listattributes() ; # Print remaining attributes for count,x in enumerate(so_chg.attributes.keys()): delattr(so_chg,x) for count,x in enumerate(temp.attributes.keys()): delattr(temp,x) for count,x in enumerate(temp_chg.attributes.keys()): delattr(temp_chg,x) del(count,x) # Create z-coordinate from salinity input if not pressure: z_coord = so.getAxis(0) y_coord = so.getAxis(1) y_coord = tile(y_coord,(so.shape[2],1)).transpose() depth_levels = tile(z_coord.getValue(),(so.shape[2],so.shape[1],1)).transpose() pressure_levels = sw.pres(np.array(depth_levels),np.array(y_coord)) del(z_coord,y_coord,depth_levels) ; gc.collect() else: pressure_levels = so.getAxis(0) pressure_levels = transpose(tile(pressure_levels,(so.shape[2],so.shape[1],1))) pressure_levels = cdm.createVariable(pressure_levels,id='pressure_levels') pressure_levels.setAxis(0,so.getAxis(0)) pressure_levels.setAxis(1,so.getAxis(1)) pressure_levels.setAxis(2,so.getAxis(2)) pressure_levels.id = 'pressure_levels' pressure_levels.units_long = 'decibar (pressure)' pressure_levels.positive = 'down' pressure_levels.long_name = 'sea_water_pressure' pressure_levels.standard_name = 'sea_water_pressure' pressure_levels.units = 'decibar' pressure_levels.axis = 'Z' # Cleanup depth axis attributes depth = so.getAxis(0) depth.id = 'depth' depth.name = 'depth' depth.long_name = 'depth' depth.standard_name = 'depth' depth.axis = 'Z' so.setAxis(0,depth) so_chg.setAxis(0,depth) temp.setAxis(0,depth) temp_chg.setAxis(0,depth) del(depth) # Convert using python-seawater library (v3.3.1 - 130807) if thetao: # Process potential temperature to in-situ - default conversion sets reference pressure to 0 (surface) #temp_chg = sw.temp(np.array(so),np.array(temp_chg),np.array(pressure_levels)); # units degrees C #temp = sw.temp(np.array(so),np.array(temp),np.array(pressure_levels)); # units degrees C #temp_chg = sw.ptmp(np.array(so),np.array(temp_chg),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C #temp = sw.ptmp(np.array(so),np.array(temp),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C temp_chg = np.array(temp_chg); # units degrees C temp = np.array(temp); # units degrees C # Climatologies - rho,cp,steric_height rho = sw.dens(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units kg m-3 cp = sw.cp(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units J kg-1 C-1 steric_height = sw.gpan(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Halosteric - rho,cp ss = map(array,(so+so_chg)) rho_halo = sw.dens(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units kg m-3 cp_halo = sw.cp(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units J kg-1 C-1 tmp = sw.gpan(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_halo_anom2 = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Full steric - steric_height tt = map(array,(temp+temp_chg)) tmp = sw.gpan(np.array(ss),np.array(tt),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_anom = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) del(ss,tmp) ; gc.collect() # Thermosteric - rho,cp,steric_height rho_thermo = sw.dens(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units kg m-3 cp_thermo = sw.cp(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units J kg-1 C-1 tmp = sw.gpan(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_thermo_anom = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) del(tt,tmp) ; gc.collect() # Halosteric - steric_height steric_height_halo_anom = steric_height_anom-steric_height_thermo_anom ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Create heat content heat_content = np.array(temp)*np.array(rho)*np.array(cp) ; # units J heat_content_sanom = np.array(temp)*np.array(rho_halo)*np.array(cp_halo) ; # units J heat_content_tanom = np.array(temp_chg)*np.array(rho)*np.array(cp) ; # units J #heat_content_tanom = np.array(temp_chg)*np.array(1020)*np.array(4187) ; # units J - try hard-coded - AR5 numbers heat_content_tsanom = np.array(temp_chg)*np.array(rho_halo)*np.array(cp_halo) ; # units J # Correct all instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp = scrubNaNAndMask(temp,so) temp_chg = scrubNaNAndMask(temp_chg,so) rho = scrubNaNAndMask(rho,so) cp = scrubNaNAndMask(cp,so) rho_halo = scrubNaNAndMask(rho_halo,so) cp_halo = scrubNaNAndMask(cp_halo,so) rho_thermo = scrubNaNAndMask(rho_thermo,so) cp_thermo = scrubNaNAndMask(cp_thermo,so) steric_height = scrubNaNAndMask(steric_height,so) steric_height_anom = scrubNaNAndMask(steric_height_anom,so) steric_height_thermo_anom = scrubNaNAndMask(steric_height_thermo_anom,so) steric_height_halo_anom = scrubNaNAndMask(steric_height_halo_anom,so) steric_height_halo_anom2 = scrubNaNAndMask(steric_height_halo_anom2,so) heat_content = scrubNaNAndMask(heat_content,so) heat_content_sanom = scrubNaNAndMask(heat_content_sanom,so) heat_content_tanom = scrubNaNAndMask(heat_content_tanom,so) heat_content_tsanom = scrubNaNAndMask(heat_content_tsanom,so) # Recreate and redress variables so.id = 'so_mean' so.units = '1e-3' so_chg.id = 'so_chg' so_chg.units = '1e-3' temp = cdm.createVariable(temp,id='temp_mean') temp.setAxis(0,so.getAxis(0)) temp.setAxis(1,so.getAxis(1)) temp.setAxis(2,so.getAxis(2)) temp.units = 'degrees_C' temp_chg = cdm.createVariable(temp_chg,id='temp_chg') temp_chg.setAxis(0,so.getAxis(0)) temp_chg.setAxis(1,so.getAxis(1)) temp_chg.setAxis(2,so.getAxis(2)) temp_chg.units = 'degrees_C' rho = cdm.createVariable(rho,id='rho') rho.setAxis(0,so.getAxis(0)) rho.setAxis(1,so.getAxis(1)) rho.setAxis(2,so.getAxis(2)) rho.name = 'density_mean' rho.units = 'kg m^-3' cp = cdm.createVariable(cp,id='cp') cp.setAxis(0,so.getAxis(0)) cp.setAxis(1,so.getAxis(1)) cp.setAxis(2,so.getAxis(2)) cp.name = 'heat_capacity_mean' cp.units = 'J kg^-1 C^-1' rho_halo = cdm.createVariable(rho_halo,id='rho_halo') rho_halo.setAxis(0,so.getAxis(0)) rho_halo.setAxis(1,so.getAxis(1)) rho_halo.setAxis(2,so.getAxis(2)) rho_halo.name = 'density_mean_halo' rho_halo.units = 'kg m^-3' cp_halo = cdm.createVariable(cp_halo,id='cp_halo') cp_halo.setAxis(0,so.getAxis(0)) cp_halo.setAxis(1,so.getAxis(1)) cp_halo.setAxis(2,so.getAxis(2)) cp_halo.name = 'heat_capacity_mean_halo' cp_halo.units = 'J kg^-1 C^-1' rho_thermo = cdm.createVariable(rho_thermo,id='rho_thermo') rho_thermo.setAxis(0,so.getAxis(0)) rho_thermo.setAxis(1,so.getAxis(1)) rho_thermo.setAxis(2,so.getAxis(2)) rho_thermo.name = 'density_mean_thermo' rho_thermo.units = 'kg m^-3' cp_thermo = cdm.createVariable(cp_thermo,id='cp_thermo') cp_thermo.setAxis(0,so.getAxis(0)) cp_thermo.setAxis(1,so.getAxis(1)) cp_thermo.setAxis(2,so.getAxis(2)) cp_thermo.name = 'heat_capacity_mean_thermo' cp_thermo.units = 'J kg^-1 C^-1' steric_height = cdm.createVariable(steric_height,id='steric_height') steric_height.setAxis(0,so.getAxis(0)) steric_height.setAxis(1,so.getAxis(1)) steric_height.setAxis(2,so.getAxis(2)) steric_height.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_anom = cdm.createVariable(steric_height_anom,id='steric_height_anom') steric_height_anom.setAxis(0,so.getAxis(0)) steric_height_anom.setAxis(1,so.getAxis(1)) steric_height_anom.setAxis(2,so.getAxis(2)) steric_height_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_thermo_anom = cdm.createVariable(steric_height_thermo_anom,id='steric_height_thermo_anom') steric_height_thermo_anom.setAxis(0,so.getAxis(0)) steric_height_thermo_anom.setAxis(1,so.getAxis(1)) steric_height_thermo_anom.setAxis(2,so.getAxis(2)) steric_height_thermo_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom = cdm.createVariable(steric_height_halo_anom,id='steric_height_halo_anom') steric_height_halo_anom.setAxis(0,so.getAxis(0)) steric_height_halo_anom.setAxis(1,so.getAxis(1)) steric_height_halo_anom.setAxis(2,so.getAxis(2)) steric_height_halo_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom2 = cdm.createVariable(steric_height_halo_anom2,id='steric_height_halo_anom2') steric_height_halo_anom2.setAxis(0,so.getAxis(0)) steric_height_halo_anom2.setAxis(1,so.getAxis(1)) steric_height_halo_anom2.setAxis(2,so.getAxis(2)) steric_height_halo_anom2.units = 'm^3 kg^-1 Pa (dynamic decimeter)' heat_content = cdm.createVariable(heat_content,id='heat_content') heat_content.setAxis(0,so.getAxis(0)) heat_content.setAxis(1,so.getAxis(1)) heat_content.setAxis(2,so.getAxis(2)) heat_content.units = 'J' heat_content_sanom = cdm.createVariable(heat_content_sanom,id='heat_content_sanom') heat_content_sanom.setAxis(0,so.getAxis(0)) heat_content_sanom.setAxis(1,so.getAxis(1)) heat_content_sanom.setAxis(2,so.getAxis(2)) heat_content_sanom.units = 'J' heat_content_tanom = cdm.createVariable(heat_content_tanom,id='heat_content_tanom') heat_content_tanom.setAxis(0,so.getAxis(0)) heat_content_tanom.setAxis(1,so.getAxis(1)) heat_content_tanom.setAxis(2,so.getAxis(2)) heat_content_tanom.units = 'J' heat_content_tsanom = cdm.createVariable(heat_content_tsanom,id='heat_content_tsanom') heat_content_tsanom.setAxis(0,so.getAxis(0)) heat_content_tsanom.setAxis(1,so.getAxis(1)) heat_content_tsanom.setAxis(2,so.getAxis(2)) heat_content_tsanom.units = 'J' # Create model-based depth index for subset target levels newdepth = np.array([5,10,20,30,40,50,75,100,125,150,200,300,500,700,1000,1500,1800,2000]).astype('f'); newdepth_bounds = np.array([[0,5],[5,10],[10,20],[20,30],[30,40],[40,50],[50,75],[75,100],[100,125],[125,150], [150,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f') #newdepth = np.array([200,300,500,700,1000,1500,1800,2000]).astype('f'); #newdepth_bounds = np.array([[0,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f') # Interpolate to depths so_depthInterp = cdu.linearInterpolation(so,pressure_levels,levels=newdepth) temp_depthInterp = cdu.linearInterpolation(temp,pressure_levels,levels=newdepth) steric_height_depthInterp = cdu.linearInterpolation(steric_height,pressure_levels,levels=newdepth) steric_height_anom_depthInterp = cdu.linearInterpolation(steric_height_anom,pressure_levels,levels=newdepth) steric_height_thermo_anom_depthInterp = cdu.linearInterpolation(steric_height_thermo_anom,pressure_levels,levels=newdepth) steric_height_halo_anom_depthInterp = cdu.linearInterpolation(steric_height_halo_anom,pressure_levels,levels=newdepth) steric_height_halo_anom2_depthInterp = cdu.linearInterpolation(steric_height_halo_anom2,pressure_levels,levels=newdepth) heat_content_sanom_depthInterp = cdu.linearInterpolation(heat_content_sanom,pressure_levels,levels=newdepth) heat_content_tanom_depthInterp = cdu.linearInterpolation(heat_content_tanom,pressure_levels,levels=newdepth) heat_content_tsanom_depthInterp = cdu.linearInterpolation(heat_content_tanom,pressure_levels,levels=newdepth) # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp_depthInterp = scrubNaNAndMask(temp_depthInterp,so_depthInterp) steric_height_depthInterp = scrubNaNAndMask(steric_height_depthInterp,so_depthInterp) steric_height_anom_depthInterp = scrubNaNAndMask(steric_height_anom_depthInterp,so_depthInterp) steric_height_thermo_anom_depthInterp = scrubNaNAndMask(steric_height_thermo_anom_depthInterp,so_depthInterp) steric_height_halo_anom_depthInterp = scrubNaNAndMask(steric_height_halo_anom_depthInterp,so_depthInterp) steric_height_halo_anom2_depthInterp = scrubNaNAndMask(steric_height_halo_anom2_depthInterp,so_depthInterp) heat_content_sanom_depthInterp = scrubNaNAndMask(heat_content_sanom_depthInterp,so_depthInterp) heat_content_tanom_depthInterp = scrubNaNAndMask(heat_content_tanom_depthInterp,so_depthInterp) heat_content_tsanom_depthInterp = scrubNaNAndMask(heat_content_tsanom_depthInterp,so_depthInterp) # Fix bounds newdepth = so_depthInterp.getAxis(0) newdepth.setBounds(newdepth_bounds) del(newdepth_bounds) newdepth.id = 'depth2' newdepth.units_long = 'decibar (pressure)' newdepth.positive = 'down' newdepth.long_name = 'sea_water_pressure' newdepth.standard_name = 'sea_water_pressure' newdepth.units = 'decibar' newdepth.axis = 'Z' # Assign corrected bounds so_depthInterp.setAxis(0,newdepth) temp_depthInterp.setAxis(0,newdepth) steric_height_depthInterp.setAxis(0,newdepth) steric_height_anom_depthInterp.setAxis(0,newdepth) steric_height_thermo_anom_depthInterp.setAxis(0,newdepth) steric_height_halo_anom_depthInterp.setAxis(0,newdepth) steric_height_halo_anom2_depthInterp.setAxis(0,newdepth) heat_content_sanom_depthInterp.setAxis(0,newdepth) heat_content_tanom_depthInterp.setAxis(0,newdepth) heat_content_tsanom_depthInterp.setAxis(0,newdepth) # Average/integrate to surface - configure bounds # Preallocate arrays so_depthAve = np.ma.zeros([len(newdepth),shape(so)[1],shape(so)[2]]) temp_depthAve = so_depthAve.copy() heat_content_sanom_depthInteg = so_depthAve.copy() heat_content_tanom_depthInteg = so_depthAve.copy() heat_content_tsanom_depthInteg = so_depthAve.copy() for count,depth in enumerate(newdepth): tmp = cdu.averager(so_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='average') so_depthAve[count,] = tmp; tmp = cdu.averager(temp_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='average') temp_depthAve[count,] = tmp; tmp = cdu.averager(heat_content_sanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum') heat_content_sanom_depthInteg[count,] = tmp tmp = cdu.averager(heat_content_tanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum') heat_content_tanom_depthInteg[count,] = tmp tmp = cdu.averager(heat_content_tsanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum') heat_content_tsanom_depthInteg[count,] = tmp del(heat_content_tanom_depthInterp,heat_content_tsanom_depthInterp); gc.collect() # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset so_depthAve = scrubNaNAndMask(so_depthAve,so_depthInterp) temp_depthAve = scrubNaNAndMask(temp_depthAve,so_depthInterp) heat_content_sanom_depthInteg = scrubNaNAndMask(heat_content_sanom_depthInteg,so_depthInterp) heat_content_tanom_depthInteg = scrubNaNAndMask(heat_content_tanom_depthInteg,so_depthInterp) heat_content_tsanom_depthInteg = scrubNaNAndMask(heat_content_tsanom_depthInteg,so_depthInterp) del(so_depthInterp) # Convert numpy arrays to cdms objects heat_content_sanom_depthInteg = cdm.createVariable(heat_content_sanom_depthInteg,id='heat_content_sanom_depthInteg') heat_content_sanom_depthInteg.id = 'heat_content_sanom_depthInteg' heat_content_sanom_depthInteg.setAxis(0,newdepth) heat_content_sanom_depthInteg.setAxis(1,so.getAxis(1)) heat_content_sanom_depthInteg.setAxis(2,so.getAxis(2)) heat_content_sanom_depthInteg.units = 'J' heat_content_tanom_depthInteg = cdm.createVariable(heat_content_tanom_depthInteg,id='heat_content_tanom_depthInteg') heat_content_tanom_depthInteg.id = 'heat_content_tanom_depthInteg' heat_content_tanom_depthInteg.setAxis(0,newdepth) heat_content_tanom_depthInteg.setAxis(1,so.getAxis(1)) heat_content_tanom_depthInteg.setAxis(2,so.getAxis(2)) heat_content_tanom_depthInteg.units = 'J' heat_content_tsanom_depthInteg = cdm.createVariable(heat_content_tsanom_depthInteg,id='heat_content_tsanom_depthInteg') heat_content_tsanom_depthInteg.id = 'heat_content_tsanom_depthInteg' heat_content_tsanom_depthInteg.setAxis(0,newdepth) heat_content_tsanom_depthInteg.setAxis(1,so.getAxis(1)) heat_content_tsanom_depthInteg.setAxis(2,so.getAxis(2)) heat_content_tsanom_depthInteg.units = 'J' so_depthAve = cdm.createVariable(so_depthAve,id='so_depthAve') so_depthAve.id = 'so_depthAve' so_depthAve.setAxis(0,newdepth) so_depthAve.setAxis(1,so.getAxis(1)) so_depthAve.setAxis(2,so.getAxis(2)) so_depthAve.units = '1e-3' temp_depthAve = cdm.createVariable(temp_depthAve,id='temp_depthAve') temp_depthAve.id = 'temp_depthAve' temp_depthAve.setAxis(0,newdepth) temp_depthAve.setAxis(1,so.getAxis(1)) temp_depthAve.setAxis(2,so.getAxis(2)) temp_depthAve.units = 'degrees_C' steric_height_depthInterp = cdm.createVariable(steric_height_depthInterp,id='steric_height_depthInterp') steric_height_depthInterp.setAxis(0,newdepth) steric_height_depthInterp.setAxis(1,so.getAxis(1)) steric_height_depthInterp.setAxis(2,so.getAxis(2)) steric_height_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_anom_depthInterp = cdm.createVariable(steric_height_anom_depthInterp,id='steric_height_anom_depthInterp') steric_height_anom_depthInterp.setAxis(0,newdepth) steric_height_anom_depthInterp.setAxis(1,so.getAxis(1)) steric_height_anom_depthInterp.setAxis(2,rho.getAxis(2)) steric_height_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_thermo_anom_depthInterp = cdm.createVariable(steric_height_thermo_anom_depthInterp,id='steric_height_thermo_anom_depthInterp') steric_height_thermo_anom_depthInterp.setAxis(0,newdepth) steric_height_thermo_anom_depthInterp.setAxis(1,so.getAxis(1)) steric_height_thermo_anom_depthInterp.setAxis(2,so.getAxis(2)) steric_height_thermo_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom_depthInterp = cdm.createVariable(steric_height_halo_anom_depthInterp,id='steric_height_halo_anom_depthInterp') steric_height_halo_anom_depthInterp.setAxis(0,newdepth) steric_height_halo_anom_depthInterp.setAxis(1,so.getAxis(1)) steric_height_halo_anom_depthInterp.setAxis(2,so.getAxis(2)) steric_height_halo_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom2_depthInterp = cdm.createVariable(steric_height_halo_anom2_depthInterp,id='steric_height_halo_anom2_depthInterp') steric_height_halo_anom2_depthInterp.setAxis(0,newdepth) steric_height_halo_anom2_depthInterp.setAxis(1,so.getAxis(1)) steric_height_halo_anom2_depthInterp.setAxis(2,so.getAxis(2)) steric_height_halo_anom2_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' # Cleanup workspace del(newdepth) ; gc.collect() # Write variables to file if os.path.isfile(outFileName): os.remove(outFileName) filehandle = cdm.open(outFileName,'w') # Global attributes globalAttWrite(filehandle,options=None) ; # Use function to write standard global atts # Write seawater version filehandle.seawater_library_version = sw.__version__ # Write makeSteric version makeStericPath = str(makeSteric.__code__).split(' ')[6] makeStericPath = replace(replace(makeStericPath,'"',''),',','') ; # Clean scraped path filehandle.makeSteric_version = ' '.join(getGitInfo(makeStericPath)[0:3]) # Master variables filehandle.write(so.astype('float32')) filehandle.write(so_chg.astype('float32')) filehandle.write(so_depthAve.astype('float32')) filehandle.write(temp.astype('float32')) filehandle.write(temp_chg.astype('float32')) filehandle.write(temp_depthAve.astype('float32')) # Derived variables filehandle.write(cp.astype('float32')) filehandle.write(cp_halo.astype('float32')) filehandle.write(cp_thermo.astype('float32')) filehandle.write(rho.astype('float32')) filehandle.write(rho_halo.astype('float32')) filehandle.write(rho_thermo.astype('float32')) filehandle.write(heat_content.astype('float32')) filehandle.write(heat_content_sanom.astype('float32')) filehandle.write(heat_content_sanom_depthInteg.astype('float32')) filehandle.write(heat_content_tanom.astype('float32')) filehandle.write(heat_content_tanom_depthInteg.astype('float32')) filehandle.write(heat_content_tsanom.astype('float32')) filehandle.write(heat_content_tsanom_depthInteg.astype('float32')) filehandle.write(steric_height.astype('float32')) filehandle.write(steric_height_depthInterp.astype('float32')) filehandle.write(steric_height_anom.astype('float32')) filehandle.write(steric_height_anom_depthInterp.astype('float32')) filehandle.write(steric_height_halo_anom.astype('float32')) filehandle.write(steric_height_halo_anom2.astype('float32')) filehandle.write(steric_height_halo_anom_depthInterp.astype('float32')) filehandle.write(steric_height_halo_anom2_depthInterp.astype('float32')) filehandle.write(steric_height_thermo_anom.astype('float32')) filehandle.write(steric_height_thermo_anom_depthInterp.astype('float32')) filehandle.close() # Cleanup workspace del(outFileName) ; gc.collect()
def makeHeatContent(salt, temp, destMask, thetao, pressure): """ The makeHeatContent() function takes 3D (not temporal) arguments and creates heat content which is then mapped to a destination grid and written to a specified variable Author: Paul J. Durack : [email protected] : @durack1. Created on Tue Nov 24 15:34:30 2015. Inputs: ------ - salt(lev,lat,lon) - 3D array. - temp(lev,lat,lon) - 3D array either in-situ or potential temperature. - destGridArray(str) - 2D array with valid grid and mask. - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided. - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m). Usage: ------ >>> from oceanLib import makeHeatContent >>> makeHeatContent(salt,temp,destGridArray,thetao=True,pressure=False) Notes: ----- - PJD 24 Nov 2015 - Migrated into new oceanLib from heatContentLib - TODO: Better deal with insitu vs thetao variables - TODO: """ # Remap variables to short names #print salt.getAxisIds() s = salt(squeeze=1) # Trim off singleton time dimension #print s.getAxisIds() t = temp(squeeze=1) mask = destMask #print mask.getAxisIds() del (salt, temp, destMask) gc.collect() depthInd = 0 # Set depth coordinate index #print 's: ',s.min(),s.max() #print 't: ',t.min(),t.max() # Fix out of bounds values t = mv.where(t < -2.6, -2.6, t) # Fix for NaN values # Calculate pressure - inputs depth & lat # Create z-coordinate from salinity input if not pressure: zCoord = s.getAxis(depthInd) # Assume time,depth,latitude,longitude grid yCoord = s.getAxis(depthInd + 1) yCoord = tile(yCoord, (s.shape[depthInd + 2], 1)).transpose() depthLevels = tile( zCoord.getValue(), (s.shape[depthInd + 2], s.shape[depthInd + 1], 1)).transpose() pressureLevels = sw.pres(np.array(depthLevels), np.array(yCoord)) del (zCoord, yCoord, depthLevels) gc.collect() else: pressureLevels = s.getAxis(depthInd) #print pressureLevels.getValue() pressureLevels = transpose( tile(pressureLevels, (s.shape[depthInd + 2], s.shape[depthInd + 1], 1))) pressureLevels = cdm.createVariable(pressureLevels, id='pressureLevels') pressureLevels.setAxis(0, s.getAxis(depthInd)) pressureLevels.setAxis(1, s.getAxis(depthInd + 1)) pressureLevels.setAxis(2, s.getAxis(depthInd + 2)) pressureLevels.units_long = 'decibar (pressure)' pressureLevels.positive = 'down' pressureLevels.long_name = 'sea_water_pressure' pressureLevels.standard_name = 'sea_water_pressure' pressureLevels.units = 'decibar' pressureLevels.axis = 'Z' #print 'pres: ',pressureLevels.min(),pressureLevels.max() #print pressureLevels.shape #print s.shape #print t.shape #print mask.shape # Calculate temp,rho,cp - inputs temp,salt,pressure if thetao: # Process potential temperature to in-situ temp = sw.temp(np.array(s), np.array(t), np.array(pressureLevels)) # units degrees C rho = sw.dens(np.array(s), np.array(temp), np.array(pressureLevels)) # units kg m-3 cp = sw.cp(np.array(s), np.array(temp), np.array(pressureLevels)) # units J kg-1 C-1 # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp = scrubNaNAndMask(temp, s) rho = scrubNaNAndMask(rho, s) cp = scrubNaNAndMask(cp, s) #print 'temp: ',temp.min(),temp.max() #print 'rho: ',rho.min(),rho.max() #print 'cp: ',cp.min(),cp.max() # Calculate heatContent - inputs temp,rho,cp heatContent = np.array(temp) * np.array(rho) * np.array(cp) # units J # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset heatContent = scrubNaNAndMask(heatContent, s) #print 'hc: ',heatContent.min(),heatContent.max() # Interpolate to standard levels - inputs heatContent,levels newDepth = np.array([ 5, 10, 20, 30, 40, 50, 75, 100, 125, 150, 200, 300, 500, 700, 1000, 1500, 1800, 2000 ]).astype('f') newDepth_bounds = np.array([[0, 5], [5, 10], [10, 20], [20, 30], [30, 40], [40, 50], [50, 75], [75, 100], [100, 125], [125, 150], [150, 200], [200, 300], [300, 500], [500, 700], [700, 1000], [1000, 1500], [1500, 1800], [1800, 2000]]).astype('f') # Interpolate to standard levels #print heatContent.shape #print heatContent.getAxisIds() #print pressureLevels.shape #print pressureLevels.getAxisIds() # Reset variable axes heatContent.setAxis(0, s.getAxis(0)) #heatContent.setAxis(1,s.getAxis(1)) #heatContent.setAxis(2,s.getAxis(2)) pdb.set_trace() heatContent.setGrid(s.getGrid()) #print heatContent.shape #print heatContent.getAxisIds() #print pressureLevels.shape #print pressureLevels.getAxisIds() heatContent_depthInterp = cdu.linearInterpolation(heatContent, pressureLevels, levels=newDepth) # Fix bounds newDepth = heatContent_depthInterp.getAxis(0) newDepth.setBounds(newDepth_bounds) del (newDepth_bounds) newDepth.id = 'depth2' newDepth.units_long = 'decibar (pressure)' newDepth.positive = 'down' newDepth.long_name = 'sea_water_pressure' newDepth.standard_name = 'sea_water_pressure' newDepth.units = 'decibar' newDepth.axis = 'Z' #print 'hc_interp:',heatContent_depthInterp.min(),heatContent_depthInterp.max() # Integrate to 700 dbar - inputs heatContent heatContent_depthInteg = cdu.averager( heatContent_depthInterp[0:14, ...], axis=0, weights='weighted', action='sum')(squeeze=1) # Calculate depth-weighted-integrated thetao # Assign all axis info #print heatContent_depthInteg.shape pdb.set_trace() # Interpolate in x,y - inputs heatContent #tmp1 = heatContent_depthInteg.regrid(mask.getGrid(),regridTool='esmf',regridMethod='linear') ; # Use defaults - ,coordSys='deg',diag = {},periodicity=1) tmp1 = heatContent_depthInteg.regrid(mask, regridTool='esmf', regridMethod='linear') # Use defaults - ,coordSys='deg',diag = {},periodicity=1) #print tmp1.shape tmp1 = mv.where(tmp1 < 0, 0, tmp1) # Fix for negative values # Infill - inputs heatContent # Create inputs for interpolation points = np.zeros([(mask.shape[0] * mask.shape[1]), 2]) # Create 25380 vectors of lon/lat latcounter = 0 loncounter = 0 for count, data in enumerate(points): if not np.mod(count, 180) and not count == 0: latcounter = latcounter + 1 loncounter = 0 points[count, 0] = mask.getLatitude().getValue()[latcounter] points[count, 1] = mask.getLongitude().getValue()[loncounter] loncounter = loncounter + 1 del (count, data, latcounter, loncounter) gc.collect() valid = np.logical_not(tmp1.mask) # Get inverted-logic boolean mask from variable if valid.size == 1: print '** No valid mask found, skipping **' return valid = valid.flatten() # Flatten 2D to 1D #maskFilled = mask(tmp,points,valid) interpolant = interpolate.LinearNDInterpolator( points[valid, :], np.array(tmp1.flatten())[valid]) # Create interpolant maskFill = interpolant(points[:, 0].squeeze(), points[:, 1].squeeze()) # Use interpolant to create filled matrix maskFill = np.reshape(maskFill, mask.shape) # Resize to original dimensions # Fix issues with interpolant tmp2 = mv.where(np.isnan(maskFill), 1e+20, maskFill) # Fix for NaN values tmp2 = mv.where(tmp2 > tmp1.max(), 0, tmp2) # Fix for max values tmp2 = mv.where(tmp2 < tmp1.min(), 0, tmp2) # Fix for min values tmp = mv.masked_where(mask.mask, tmp2) #print tmp.shape # Redress variable heatContent = cdm.createVariable([tmp], id='heatContent') depthInt = cdm.createAxis([350], id='depth') depthInt.setBounds(np.array([0, 700])) depthInt.units_long = 'decibar (pressure)' depthInt.positive = 'down' depthInt.long_name = 'sea_water_pressure' depthInt.standard_name = 'sea_water_pressure' depthInt.units = 'decibar' depthInt.axis = 'Z' heatContent.setAxis(0, depthInt) heatContent.setAxis(1, mask.getAxis(0)) heatContent.setAxis(2, mask.getAxis(1)) heatContent.units_long = 'Joules' heatContent.long_name = 'sea_water_heat_content' heatContent.standard_name = 'sea_water_heat_content' heatContent.units = 'J' return heatContent
def do_load_dataloop(mesh, data, fname_list, var_list, sel_timeidx, sel_levidx, \ nti, nsi, ndi, do_tmean, do_output,): if ndi!=0: #_______________________________________________________________________ # initialize data.value array if do_tmean: data.value = np.zeros((nsi,len(sel_levidx)),dtype='float32') if len(fname_list[1]): data.value2 = np.zeros((nsi,len(sel_levidx)),dtype='float32') if len(fname_list[1]): data.value3 = np.zeros((nsi,len(sel_levidx)),dtype='float32') else: data.value = np.zeros((nti,nsi,len(sel_levidx))) if len(fname_list[1]): data.value2 = np.zeros((nti*len(fname_list),nsi,len(sel_levidx)),dtype='float32') if len(fname_list[1]): data.value3 = np.zeros((nti*len(fname_list),nsi,len(sel_levidx)),dtype='float32') #_______________________________________________________________________ # select time+depth range + compute time mean for it in range(0,len(fname_list[0])): if do_tmean: data.value = data.value + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx].mean(axis=0) if len(fname_list[1]): data.value2 = data.value2 + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx].mean(axis=0) if len(fname_list[2]): data.value3 = data.value3 + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx].mean(axis=0) else: t_idx = sel_timeidx+nti*it data.value[t_idx,:,:] = data.value[t_idx,:,:] + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx] if len(fname_list[1]): data.value2[t_idx,:,:] = data.value2[t_idx,:,:] + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx] if len(fname_list[2]): data.value3[t_idx,:,:] = data.value3[t_idx,:,:] + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx] # divide by loaded file number --> to final time mean if do_tmean: data.value = data.value/len(fname_list[0]) if len(fname_list[1]): data.value2 = data.value2/len(fname_list[1]) if len(fname_list[2]): data.value3 = data.value2/len(fname_list[2]) #_______________________________________________________________________ # compute potential density & temperatur if selected if any(x in data.var for x in ['pdens','ptemp','sigma']): dep = np.matlib.repmat(mesh.zmid[sel_levidx],nsi,1) lat = np.matlib.repmat(mesh.nodes_2d_yg[0:mesh.n2dn],nsi,1).transpose() press = sw.pres(dep,lat) press_ref= 0 if '0' in data.var : press_ref=0 elif '1' in data.var : press_ref=1000 elif '2' in data.var : press_ref=2000 elif '3' in data.var : press_ref=3000 elif '4' in data.var : press_ref=4000 elif '5' in data.var : press_ref=5000 if press_ref!=0: data.lname = '$\sigma_{'+str(int(press_ref/1000))+'}$ '+data.lname del dep,lat if do_tmean: if 'ptemp' in data.var: data.value = sw.ptmp(data.value2,data.value,press,press_ref) if any(x in data.var for x in ['pdens','sigma']): data.value = sw.pden(data.value2,data.value,press,press_ref)-1000.025 else: for it in range(0,data.value.shape[0]): if 'ptemp' in data.var: data.value[it,:,:] = sw.ptmp(data.value2[it,:,:],data.value[it,:,:],press,press_ref) if any(x in data.var for x in ['pdens','sigma']): data.value[it,:,:] = sw.pden(data.value2[it,:,:],data.value[it,:,:],press,press_ref)-1000.025 fname_list[1]=[] #_______________________________________________________________________ # compute depth mean + linear interpolation to selected depth levels data.value = do_zinterp(mesh, data.value, data.depth, ndi, nsi, sel_levidx,do_output) if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, nsi, sel_levidx,do_output) if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, nsi, sel_levidx,do_output) # 2D data: else: #_______________________________________________________________________ # initialize data.value array if do_tmean: data.value = np.zeros((nsi,)) if len(fname_list[1]): data.value2 = np.zeros((nsi,)) if len(fname_list[1]): data.value3 = np.zeros((nsi,)) else: data.value = np.zeros((nti,nsi)) if len(fname_list[1]): data.value2 = np.zeros((nti*len(fname_list),nsi)) if len(fname_list[1]): data.value3 = np.zeros((nti*len(fname_list),nsi)) #_______________________________________________________________________ # select time+depth range + compute time mean for it in range(0,len(fname_list[0])): if do_tmean: data.value = data.value + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:].mean(axis=0) if len(fname_list[1]): data.value2 = data.value2 + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:].mean(axis=0) if len(fname_list[2]): data.value3 = data.value3 + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:].mean(axis=0) else: t_idx = sel_timeidx+nti*it data.value[t_idx,:] = data.value[t_idx,:] + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:] if len(fname_list[1]): data.value2[t_idx,:] = data.value2[t_idx,:] + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:] if len(fname_list[2]): data.value3[t_idx,:] = data.value3[t_idx,:] + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:] # divide by loaded file number --> to final time mean if do_tmean: data.value = data.value/len(fname_list[0]) if len(fname_list[1]): data.value2 = data.value2/len(fname_list[1]) if len(fname_list[2]): data.value3 = data.value2/len(fname_list[2]) return(data)
for var, i in zip(data1[7], good_inds_1) ] filtered_T1 = [ np.interp(fd, d.astype('float32')[i], var.astype('float32')[i]) for fd, d, var, i in zip(filtered_dep1, data1[6], data1[4], good_inds_1) ] filtered_S1 = [ np.interp(fd, d.astype('float32')[i], var.astype('float32')[i]) for fd, d, var, i in zip(filtered_dep1, data1[6], data1[5], good_inds_1) ] filtered_dens1 = [ sw.pden(S, T, sw.pres(z, lat=CENTRAL_LAT)) for T, S, z in zip(filtered_T1, filtered_S1, filtered_dep1) ] good_inds_2 = [ np.isfinite(T.astype('float32')) & np.isfinite(S.astype('float32')) & np.isfinite(b.astype('float32')) for T, S, b in zip(data2[4], data2[5], data2[7]) ] if inst2 == 'BB2FLSG': # Seaglider VSF data is already filtered filtered_dep2 = [var[i] for var, i in zip(data2[6], good_inds_2)] filtered_VSF2 = [var[i] for var, i in zip(data2[7], good_inds_2)] else: filtered_dep2 = [ get_data.median_filter(var.astype('float32')[i]) for var, i in zip(data2[6], good_inds_2)
fn = fn_list[tt] ds1 = nc.Dataset(fn) if np.mod(tt, 10) == 0: # print update to console every 10th file print('tt = ' + str(tt) + '/' + str(NT) + ' ' + str(datetime.now())) sys.stdout.flush() if model_type == 'Kurapov': # Kurapov variable structure: [time,layer,lon,lat] import seawater zeta = ds1['zeta'][0, :, :].squeeze() if tt == 0: bp_arr = (0 * zeta) * np.ones((NT, 1, 1)) salt = ds1['salt'][0, :, :, :].squeeze() ptemp = ds1['temp'][0, :, :, :].squeeze() # potential temperature z_r = zrfun.get_z(G['h'][:, :], 0 * zeta, S, only_rho=True) z_w = zrfun.get_z(G['h'][:, :], zeta, S, only_w=True) p = seawater.pres(-z_r, G['lat_rho'][0, 0]) temp = seawater.temp(salt, ptemp, p) # in situ temperature # for some reason seawater.dens throws errors if we don't do this sd = salt.data td = temp.data prd = p.data sd[salt.mask] = np.nan td[salt.mask] = np.nan prd[salt.mask] = np.nan prho = seawater.pden(sd, td, prd) # potential density prho = np.ma.masked_where(salt.mask, prho) rho = seawater.dens( sd, td, prd) # in-situ density from salinity, temperature, and pressure rho = np.ma.masked_where(salt.mask, rho) DZ = np.diff(z_w, axis=0)
def get_layer(fn, NZ=-1, aa=[], print_info=False): # function to extract and process fields from a history file # returning a dict of arrays that can be passed to CO2SYS.m # default is to get full surface field ds = nc.Dataset(fn) G, S, T = zrfun.get_basic_info(fn) if len(aa) == 4: # find indices that encompass region aa i0 = zfun.find_nearest_ind(G['lon_rho'][0,:], aa[0]) - 1 i1 = zfun.find_nearest_ind(G['lon_rho'][0,:], aa[1]) + 2 j0 = zfun.find_nearest_ind(G['lat_rho'][:,0], aa[2]) - 1 j1 = zfun.find_nearest_ind(G['lat_rho'][:,0], aa[3]) + 2 else: # full region i0 = 0; j0 = 0 j1, i1 = G['lon_rho'].shape i1 += 1; j1 += 1 plon = G['lon_psi'][j0:j1-1, i0:i1-1] plat = G['lat_psi'][j0:j1-1, i0:i1-1] # extract needed info from history file v_dict = dict() if print_info: print('\nINPUT Variable Info:') for vn in ['alkalinity', 'TIC', 'salt', 'temp','rho']: v = ds[vn][0,NZ, j0:j1, i0:i1] v = fillit(v) v_dict[vn] = v if print_info: name = ds[vn].long_name try: units = ds[vn].units except AttributeError: units = '' vmax = np.nanmax(v) vmin = np.nanmin(v) v_dict[vn] = v print('%25s (%25s) max = %6.1f min = %6.1f' % (name, units, vmax, vmin)) # create depth, pressure, and in situ temperature h = ds['h'][j0:j1, i0:i1] h = fillit(h) lat = G['lat_rho'][j0:j1, i0:i1] z_rho = zrfun.get_z(h, 0*h, S, only_rho=True) depth = -z_rho[NZ, :, :].squeeze() pres = sw.pres(depth, lat) v_dict['pres'] = pres # assume potential temperature is close enough # temp = sw.ptmp(v_dict['salt'], v_dict['temp'], 0, v_dict['pres']) # v_dict['temp'] = temp # convert from umol/L to umol/kg using in situ dentity v_dict['alkalinity'] = 1000 * v_dict['alkalinity'] / (v_dict['rho'] + 1000) v_dict['TIC'] = 1000 * v_dict['TIC'] / (v_dict['rho'] + 1000) # clean up v_dict.pop('rho') # no longer needed, so don't pass to worker ds.close() return v_dict, plon, plat
def do_load_mfdata(mesh, data, fname_list, var_list, sel_timeidx, sel_levidx, \ nsi, ndi, do_tmean, do_output,): if ndi!=0: #_______________________________________________________________________ # select time+depth range + compute time mean if do_tmean: data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx].mean(axis=0) if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx].mean(axis=0) if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx].mean(axis=0) else: data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx] if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx] if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx] #_______________________________________________________________________ # compute potential density & temperatur if selected if any(x in data.var for x in ['pdens','ptemp','sigma']): dep = np.matlib.repmat(mesh.zmid[sel_levidx],nsi,1) lat = np.matlib.repmat(mesh.nodes_2d_yg[0:mesh.n2dn],len(sel_levidx),1).transpose() press = sw.pres(dep,lat) press_ref = 0 if '0' in data.var : press_ref=0 elif '1' in data.var : press_ref=1000 elif '2' in data.var : press_ref=2000 elif '3' in data.var : press_ref=3000 elif '4' in data.var : press_ref=4000 elif '5' in data.var : press_ref=5000 if 'sigma' in data.var: data.lname = '$\sigma_{'+str(int(press_ref/1000))+'}$ '+data.lname del dep,lat if do_tmean: if 'ptemp' in data.var: data.value = sw.ptmp(data.value2,data.value,press,press_ref) if any(x in data.var for x in ['pdens','sigma']): data.value = sw.pden(data.value2,data.value,press,press_ref)-1000.025 else: for it in range(0,data.value.shape[0]): if 'ptemp' in data.var: data.value[it,:,:] = sw.ptmp(data.value2[it,:,:],data.value[it,:,:],press,press_ref) if any(x in data.var for x in ['pdens','sigma']): data.value[it,:,:] = sw.pden(data.value2[it,:,:],data.value[it,:,:],press,press_ref)-1000.025 fname_list[1]=[] #_______________________________________________________________________ # compute depth mean + linear interpolation to selected depth levels if do_tmean: data.value = do_zinterp(mesh, data.value, data.depth, ndi, data.value.shape[0], sel_levidx,do_output) if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, data.value2.shape[0], sel_levidx,do_output) if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, data.value3.shape[0], sel_levidx,do_output) else: data.value = do_zinterp(mesh, data.value, data.depth, ndi, data.value.shape[1], sel_levidx,do_output) if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, data.value2.shape[1], sel_levidx,do_output) if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, data.value3.shape[1], sel_levidx,do_output) # 2D data: else: if do_tmean: data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:].mean(axis=0) if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:].mean(axis=0) if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:].mean(axis=0) else: data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:] if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:] if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:] # kickout single array dimension data.value = data.value.squeeze() if len(fname_list[1]): data.value2 = data.value2.squeeze() if len(fname_list[2]): data.value3 = data.value3.squeeze() return(data)
def get_FLBB_SR(files, get_data=True, get_dives=None, remove_seawater=True, VSF_dark=0): SB_files = np.sort(glob.glob(files)) if get_dives is not None: # first get all stations all_stations = np.empty(len(SB_files)) for i in range(len(SB_files)): SB = readSB(SB_files[i], no_warn=True) # 'calibration_file' is more accurate than 'station' var all_stations[i] = int(SB.headers['calibration_files'][7:10]) # now re-make SB_files list to be one for each station # (need to do it this way in case stations are duplicated) SB_files = np.array([ SB_files[np.where(all_stations == station)[0][0]] for station in get_dives ]) lat = () lon = () t = () sta = () if get_data: T = () S = () z = () VSF = () for i in range(len(SB_files)): SB = readSB(SB_files[i], no_warn=True) # 'calibration_file' is more accurate than 'station' var station = int(SB.headers['calibration_files'][7:10]) lat += (get_startlat(SB), ) lon += (get_startlon(SB), ) t += (get_starttime(SB), ) sta += (station, ) if get_data: T += (np.array(SB.data['wt']), ) S += (np.array(SB.data['sal']), ) z += (np.array(SB.data['depth']), ) if remove_seawater: #VSF_sw = betasw_HZP2019(700,142,T[-1],S[-1],sw.pres(z[-1],lat=50.5))[0].squeeze() VSF_sw = betasw_wetlabs(700, 20, 142, 42, T[-1], S[-1], sw.pres(z[-1], lat=50.5)) else: VSF_sw = 0 VSF += ((np.array(SB.data['bbp']) / (2 * np.pi * 1.17) - VSF_dark - VSF_sw), ) # convert using chi factor for 142deg angle used here (1.17) # (note this is different than that found in Zhang et al., 2021) t = np.array(t, dtype='object') lat = np.array(lat, dtype='object') lon = np.array(lon, dtype='object') sta = np.array(sta, dtype='object') if get_data: T = np.array(T, dtype='object') S = np.array(S, dtype='object') z = np.array(z, dtype='object') VSF = np.array(VSF, dtype='object') output = (t, lat, lon, sta) if get_data: output += (T, S, z, VSF) return output
z0 =(hc*s_r[k]+Cs_r[k]*h[i,j])/(hc+h[i,j]); z[k]=zeta+(zeta+h[i,j])*z0; z0 =(hc*s_w[k]+Cs_w[k]*h[i,j])/(hc+h[i,j]); zw[k]=zeta+(zeta+h[i,j])*z0; # Add last depth for zw z0 =(hc*s_w[N]+Cs_w[N]*h[i,j])/(hc+h[i,j]); zw[N]=zeta+(zeta+h[i,j])*z0; Hz = abs(zw[1:N+1]-zw[0:N]) #------------------------------------------------------------------------ # Calculate various seawater properties #------------------------------------------------------------------------ pres=sw.pres(z*-1,lat[i,j]) #----------------------------------------------------------------- # Calculate depth of the pycnocline #---------------------------------------------------------------- dens=sw.dens(salt,temp,pres)-1000. drdZ = abs(dens[1:N]-dens[0:N-1])/abs(z[1:N]-z[0:N-1]) drdZ_ind=np.argmax(drdZ) #----------------------------------------------------------------- # Average residence time above the pycnocline #---------------------------------------------------------------- rtime02[tdim,i,j]=sum( Hz[drdZ_ind::]*rtime[drdZ_ind::])/\ abs(z[drdZ_ind]) else: rtime02[tdim,i,j]=np.nan
def makeSteric(salinity, salinityChg, temp, tempChg, outFileName, thetao, pressure): """ The makeSteric() function takes 3D (not temporal) arguments and creates heat content and steric fields which are written to a specified outfile Author: Paul J. Durack : [email protected] : @durack1. Created on Thu Jul 18 13:03:37 2013. Inputs: ------ - salinity(lev,lat,lon) - 3D array for the climatological period. - salinityChg(lev,lat,lon) - 3D array for the temporal change period. - temp(lev,lat,lon) - 3D array for the climatological period either in-situ or potential temperature. - tempChg(lev,lat,lon) - 3D array for the temporal change period as with temp, either in-situ or potential temperature. - outFileName(str) - output filename with full path specified. - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided. - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m). Usage: ------ >>> from makeStericLib import makeSteric >>> makeSteric(salinity,salinityChg,thetao,thetaoChg,'outfile.nc',True,False) Notes: ----- - PJD 18 Jul 2013 - Validated Ishii v6.13 data against WOA94 - checks out ok. Units: dyn decimeter compared to http://www.nodc.noaa.gov/OC5/WOA94/dyn.html uses cm (not decimeter; x 10) - PJD 18 Jul 2013 - Added attribute scrub to incoming variables (so,so_chg,temp,temp_chg) to maintain output consistency - PJD 22 Jul 2013 - Added name attributes to so and temp variables, added units to so_chg - PJD 22 Jul 2013 - removed duplicated code by converting repetition to function scrubNaNAndMask - PJD 23 Jul 2013 - Further cleaned up so,so_chg,temp,temp_chg outputs specifying id/name attributes - PJD 5 Aug 2013 - Updated python-seawater library to version 3.3.1 from github repo, git clone http://github.com/ocefpaf/python-seawater, python setup.py install --user - PJD 7 Aug 2013 - FIXED: thetao rather than in-situ temperature propagating throughout calculations - PJD 7 Aug 2013 - Replaced looping with 3D gpan - PJD 7 Aug 2013 - Further code duplication cleanup - PJD 8 Aug 2013 - FIXED: scrubNanAndMask function type/mask/grid issue - encase sw arguments in np.array() (attempt to strip cdms fluff) - PJD 8 Aug 2013 - FIXED: removed depth variable unit edits - not all inputs are depth (m) - PJD 15 Aug 2013 - Increased interpolated field resolution [200,300,500,700,1000,1500,1800,2000] - [5,10,20,30,40,50,75,100,125,150,200, ...] - PJD 18 Aug 2013 - AR5 hard coded rho=1020,cp=4187 == 4.3e6 vs Ishii 1970 rho.mean=1024,cp.mean=3922 == 4.1e6 ~5% too high - PJD 13 Jan 2014 - Corrected steric_height_anom and steric_height_thermo_anom to true anomaly fields, needed to remove climatology - PJD 3 May 2014 - Turned off thetao conversion, although convert to numpy array rather than cdms2 transient variable - PJD 13 Oct 2014 - Added seawater_library_version as a global attribute - PJD 13 Oct 2014 - FIXED: bug with calculation of rho_halo variable was calculating gpan - PJD 13 Oct 2014 - Added alternate calculation of halosteric anomaly (direct salinity anomaly calculation, rather than total-thermosteric) - PJD 13 Oct 2014 - Added makeSteric_version as a global attribute - TODO: Better deal with insitu vs thetao variables - TODO: Query Charles on why *.name attributes are propagating - TODO: validate outputs and compare to matlab versions - 10e-7 errors. """ # Remap all variables to short names so = salinity so_chg = salinityChg temp = temp temp_chg = tempChg del (salinity, salinityChg, tempChg) gc.collect() # Strip attributes to maintain consistency between datasets for count, x in enumerate(so.attributes.keys()): delattr(so, x) #print so.listattributes() ; # Print remaining attributes for count, x in enumerate(so_chg.attributes.keys()): delattr(so_chg, x) for count, x in enumerate(temp.attributes.keys()): delattr(temp, x) for count, x in enumerate(temp_chg.attributes.keys()): delattr(temp_chg, x) del (count, x) # Create z-coordinate from salinity input if not pressure: z_coord = so.getAxis(0) y_coord = so.getAxis(1) y_coord = tile(y_coord, (so.shape[2], 1)).transpose() depth_levels = tile(z_coord.getValue(), (so.shape[2], so.shape[1], 1)).transpose() pressure_levels = sw.pres(np.array(depth_levels), np.array(y_coord)) del (z_coord, y_coord, depth_levels) gc.collect() else: pressure_levels = so.getAxis(0) pressure_levels = transpose( tile(pressure_levels, (so.shape[2], so.shape[1], 1))) pressure_levels = cdm.createVariable(pressure_levels, id='pressure_levels') pressure_levels.setAxis(0, so.getAxis(0)) pressure_levels.setAxis(1, so.getAxis(1)) pressure_levels.setAxis(2, so.getAxis(2)) pressure_levels.id = 'pressure_levels' pressure_levels.units_long = 'decibar (pressure)' pressure_levels.positive = 'down' pressure_levels.long_name = 'sea_water_pressure' pressure_levels.standard_name = 'sea_water_pressure' pressure_levels.units = 'decibar' pressure_levels.axis = 'Z' # Cleanup depth axis attributes depth = so.getAxis(0) depth.id = 'depth' depth.name = 'depth' depth.long_name = 'depth' depth.standard_name = 'depth' depth.axis = 'Z' so.setAxis(0, depth) so_chg.setAxis(0, depth) temp.setAxis(0, depth) temp_chg.setAxis(0, depth) del (depth) # Convert using python-seawater library (v3.3.1 - 130807) if thetao: # Process potential temperature to in-situ - default conversion sets reference pressure to 0 (surface) #temp_chg = sw.temp(np.array(so),np.array(temp_chg),np.array(pressure_levels)); # units degrees C #temp = sw.temp(np.array(so),np.array(temp),np.array(pressure_levels)); # units degrees C #temp_chg = sw.ptmp(np.array(so),np.array(temp_chg),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C #temp = sw.ptmp(np.array(so),np.array(temp),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C temp_chg = np.array(temp_chg) # units degrees C temp = np.array(temp) # units degrees C # Climatologies - rho,cp,steric_height rho = sw.dens(np.array(so), np.array(temp), np.array(pressure_levels)) # units kg m-3 cp = sw.cp(np.array(so), np.array(temp), np.array(pressure_levels)) # units J kg-1 C-1 steric_height = sw.gpan(np.array(so), np.array(temp), np.array(pressure_levels)) # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Halosteric - rho,cp ss = map(array, (so + so_chg)) rho_halo = sw.dens(np.array(ss), np.array(temp), np.array(pressure_levels)) # units kg m-3 cp_halo = sw.cp(np.array(ss), np.array(temp), np.array(pressure_levels)) # units J kg-1 C-1 tmp = sw.gpan(np.array(ss), np.array(temp), np.array(pressure_levels)) # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_halo_anom2 = tmp - steric_height # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Full steric - steric_height tt = map(array, (temp + temp_chg)) tmp = sw.gpan(np.array(ss), np.array(tt), np.array(pressure_levels)) # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_anom = tmp - steric_height # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) del (ss, tmp) gc.collect() # Thermosteric - rho,cp,steric_height rho_thermo = sw.dens(np.array(so), np.array(tt), np.array(pressure_levels)) # units kg m-3 cp_thermo = sw.cp(np.array(so), np.array(tt), np.array(pressure_levels)) # units J kg-1 C-1 tmp = sw.gpan(np.array(so), np.array(tt), np.array(pressure_levels)) # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) steric_height_thermo_anom = tmp - steric_height # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) del (tt, tmp) gc.collect() # Halosteric - steric_height steric_height_halo_anom = steric_height_anom - steric_height_thermo_anom # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter) # Create heat content heat_content = np.array(temp) * np.array(rho) * np.array(cp) # units J heat_content_sanom = np.array(temp) * np.array(rho_halo) * np.array( cp_halo) # units J heat_content_tanom = np.array(temp_chg) * np.array(rho) * np.array(cp) # units J #heat_content_tanom = np.array(temp_chg)*np.array(1020)*np.array(4187) ; # units J - try hard-coded - AR5 numbers heat_content_tsanom = np.array(temp_chg) * np.array(rho_halo) * np.array( cp_halo) # units J # Correct all instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp = scrubNaNAndMask(temp, so) temp_chg = scrubNaNAndMask(temp_chg, so) rho = scrubNaNAndMask(rho, so) cp = scrubNaNAndMask(cp, so) rho_halo = scrubNaNAndMask(rho_halo, so) cp_halo = scrubNaNAndMask(cp_halo, so) rho_thermo = scrubNaNAndMask(rho_thermo, so) cp_thermo = scrubNaNAndMask(cp_thermo, so) steric_height = scrubNaNAndMask(steric_height, so) steric_height_anom = scrubNaNAndMask(steric_height_anom, so) steric_height_thermo_anom = scrubNaNAndMask(steric_height_thermo_anom, so) steric_height_halo_anom = scrubNaNAndMask(steric_height_halo_anom, so) steric_height_halo_anom2 = scrubNaNAndMask(steric_height_halo_anom2, so) heat_content = scrubNaNAndMask(heat_content, so) heat_content_sanom = scrubNaNAndMask(heat_content_sanom, so) heat_content_tanom = scrubNaNAndMask(heat_content_tanom, so) heat_content_tsanom = scrubNaNAndMask(heat_content_tsanom, so) # Recreate and redress variables so.id = 'so_mean' so.units = '1e-3' so_chg.id = 'so_chg' so_chg.units = '1e-3' temp = cdm.createVariable(temp, id='temp_mean') temp.setAxis(0, so.getAxis(0)) temp.setAxis(1, so.getAxis(1)) temp.setAxis(2, so.getAxis(2)) temp.units = 'degrees_C' temp_chg = cdm.createVariable(temp_chg, id='temp_chg') temp_chg.setAxis(0, so.getAxis(0)) temp_chg.setAxis(1, so.getAxis(1)) temp_chg.setAxis(2, so.getAxis(2)) temp_chg.units = 'degrees_C' rho = cdm.createVariable(rho, id='rho') rho.setAxis(0, so.getAxis(0)) rho.setAxis(1, so.getAxis(1)) rho.setAxis(2, so.getAxis(2)) rho.name = 'density_mean' rho.units = 'kg m^-3' cp = cdm.createVariable(cp, id='cp') cp.setAxis(0, so.getAxis(0)) cp.setAxis(1, so.getAxis(1)) cp.setAxis(2, so.getAxis(2)) cp.name = 'heat_capacity_mean' cp.units = 'J kg^-1 C^-1' rho_halo = cdm.createVariable(rho_halo, id='rho_halo') rho_halo.setAxis(0, so.getAxis(0)) rho_halo.setAxis(1, so.getAxis(1)) rho_halo.setAxis(2, so.getAxis(2)) rho_halo.name = 'density_mean_halo' rho_halo.units = 'kg m^-3' cp_halo = cdm.createVariable(cp_halo, id='cp_halo') cp_halo.setAxis(0, so.getAxis(0)) cp_halo.setAxis(1, so.getAxis(1)) cp_halo.setAxis(2, so.getAxis(2)) cp_halo.name = 'heat_capacity_mean_halo' cp_halo.units = 'J kg^-1 C^-1' rho_thermo = cdm.createVariable(rho_thermo, id='rho_thermo') rho_thermo.setAxis(0, so.getAxis(0)) rho_thermo.setAxis(1, so.getAxis(1)) rho_thermo.setAxis(2, so.getAxis(2)) rho_thermo.name = 'density_mean_thermo' rho_thermo.units = 'kg m^-3' cp_thermo = cdm.createVariable(cp_thermo, id='cp_thermo') cp_thermo.setAxis(0, so.getAxis(0)) cp_thermo.setAxis(1, so.getAxis(1)) cp_thermo.setAxis(2, so.getAxis(2)) cp_thermo.name = 'heat_capacity_mean_thermo' cp_thermo.units = 'J kg^-1 C^-1' steric_height = cdm.createVariable(steric_height, id='steric_height') steric_height.setAxis(0, so.getAxis(0)) steric_height.setAxis(1, so.getAxis(1)) steric_height.setAxis(2, so.getAxis(2)) steric_height.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_anom = cdm.createVariable(steric_height_anom, id='steric_height_anom') steric_height_anom.setAxis(0, so.getAxis(0)) steric_height_anom.setAxis(1, so.getAxis(1)) steric_height_anom.setAxis(2, so.getAxis(2)) steric_height_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_thermo_anom = cdm.createVariable( steric_height_thermo_anom, id='steric_height_thermo_anom') steric_height_thermo_anom.setAxis(0, so.getAxis(0)) steric_height_thermo_anom.setAxis(1, so.getAxis(1)) steric_height_thermo_anom.setAxis(2, so.getAxis(2)) steric_height_thermo_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom = cdm.createVariable(steric_height_halo_anom, id='steric_height_halo_anom') steric_height_halo_anom.setAxis(0, so.getAxis(0)) steric_height_halo_anom.setAxis(1, so.getAxis(1)) steric_height_halo_anom.setAxis(2, so.getAxis(2)) steric_height_halo_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom2 = cdm.createVariable( steric_height_halo_anom2, id='steric_height_halo_anom2') steric_height_halo_anom2.setAxis(0, so.getAxis(0)) steric_height_halo_anom2.setAxis(1, so.getAxis(1)) steric_height_halo_anom2.setAxis(2, so.getAxis(2)) steric_height_halo_anom2.units = 'm^3 kg^-1 Pa (dynamic decimeter)' heat_content = cdm.createVariable(heat_content, id='heat_content') heat_content.setAxis(0, so.getAxis(0)) heat_content.setAxis(1, so.getAxis(1)) heat_content.setAxis(2, so.getAxis(2)) heat_content.units = 'J' heat_content_sanom = cdm.createVariable(heat_content_sanom, id='heat_content_sanom') heat_content_sanom.setAxis(0, so.getAxis(0)) heat_content_sanom.setAxis(1, so.getAxis(1)) heat_content_sanom.setAxis(2, so.getAxis(2)) heat_content_sanom.units = 'J' heat_content_tanom = cdm.createVariable(heat_content_tanom, id='heat_content_tanom') heat_content_tanom.setAxis(0, so.getAxis(0)) heat_content_tanom.setAxis(1, so.getAxis(1)) heat_content_tanom.setAxis(2, so.getAxis(2)) heat_content_tanom.units = 'J' heat_content_tsanom = cdm.createVariable(heat_content_tsanom, id='heat_content_tsanom') heat_content_tsanom.setAxis(0, so.getAxis(0)) heat_content_tsanom.setAxis(1, so.getAxis(1)) heat_content_tsanom.setAxis(2, so.getAxis(2)) heat_content_tsanom.units = 'J' # Create model-based depth index for subset target levels newdepth = np.array([ 5, 10, 20, 30, 40, 50, 75, 100, 125, 150, 200, 300, 500, 700, 1000, 1500, 1800, 2000 ]).astype('f') newdepth_bounds = np.array([[0, 5], [5, 10], [10, 20], [20, 30], [30, 40], [40, 50], [50, 75], [75, 100], [100, 125], [125, 150], [150, 200], [200, 300], [300, 500], [500, 700], [700, 1000], [1000, 1500], [1500, 1800], [1800, 2000]]).astype('f') #newdepth = np.array([200,300,500,700,1000,1500,1800,2000]).astype('f'); #newdepth_bounds = np.array([[0,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f') # Interpolate to depths so_depthInterp = cdu.linearInterpolation(so, pressure_levels, levels=newdepth) temp_depthInterp = cdu.linearInterpolation(temp, pressure_levels, levels=newdepth) steric_height_depthInterp = cdu.linearInterpolation(steric_height, pressure_levels, levels=newdepth) steric_height_anom_depthInterp = cdu.linearInterpolation( steric_height_anom, pressure_levels, levels=newdepth) steric_height_thermo_anom_depthInterp = cdu.linearInterpolation( steric_height_thermo_anom, pressure_levels, levels=newdepth) steric_height_halo_anom_depthInterp = cdu.linearInterpolation( steric_height_halo_anom, pressure_levels, levels=newdepth) steric_height_halo_anom2_depthInterp = cdu.linearInterpolation( steric_height_halo_anom2, pressure_levels, levels=newdepth) heat_content_sanom_depthInterp = cdu.linearInterpolation( heat_content_sanom, pressure_levels, levels=newdepth) heat_content_tanom_depthInterp = cdu.linearInterpolation( heat_content_tanom, pressure_levels, levels=newdepth) heat_content_tsanom_depthInterp = cdu.linearInterpolation( heat_content_tanom, pressure_levels, levels=newdepth) # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset temp_depthInterp = scrubNaNAndMask(temp_depthInterp, so_depthInterp) steric_height_depthInterp = scrubNaNAndMask(steric_height_depthInterp, so_depthInterp) steric_height_anom_depthInterp = scrubNaNAndMask( steric_height_anom_depthInterp, so_depthInterp) steric_height_thermo_anom_depthInterp = scrubNaNAndMask( steric_height_thermo_anom_depthInterp, so_depthInterp) steric_height_halo_anom_depthInterp = scrubNaNAndMask( steric_height_halo_anom_depthInterp, so_depthInterp) steric_height_halo_anom2_depthInterp = scrubNaNAndMask( steric_height_halo_anom2_depthInterp, so_depthInterp) heat_content_sanom_depthInterp = scrubNaNAndMask( heat_content_sanom_depthInterp, so_depthInterp) heat_content_tanom_depthInterp = scrubNaNAndMask( heat_content_tanom_depthInterp, so_depthInterp) heat_content_tsanom_depthInterp = scrubNaNAndMask( heat_content_tsanom_depthInterp, so_depthInterp) # Fix bounds newdepth = so_depthInterp.getAxis(0) newdepth.setBounds(newdepth_bounds) del (newdepth_bounds) newdepth.id = 'depth2' newdepth.units_long = 'decibar (pressure)' newdepth.positive = 'down' newdepth.long_name = 'sea_water_pressure' newdepth.standard_name = 'sea_water_pressure' newdepth.units = 'decibar' newdepth.axis = 'Z' # Assign corrected bounds so_depthInterp.setAxis(0, newdepth) temp_depthInterp.setAxis(0, newdepth) steric_height_depthInterp.setAxis(0, newdepth) steric_height_anom_depthInterp.setAxis(0, newdepth) steric_height_thermo_anom_depthInterp.setAxis(0, newdepth) steric_height_halo_anom_depthInterp.setAxis(0, newdepth) steric_height_halo_anom2_depthInterp.setAxis(0, newdepth) heat_content_sanom_depthInterp.setAxis(0, newdepth) heat_content_tanom_depthInterp.setAxis(0, newdepth) heat_content_tsanom_depthInterp.setAxis(0, newdepth) # Average/integrate to surface - configure bounds # Preallocate arrays so_depthAve = np.ma.zeros([len(newdepth), shape(so)[1], shape(so)[2]]) temp_depthAve = so_depthAve.copy() heat_content_sanom_depthInteg = so_depthAve.copy() heat_content_tanom_depthInteg = so_depthAve.copy() heat_content_tsanom_depthInteg = so_depthAve.copy() for count, depth in enumerate(newdepth): tmp = cdu.averager(so_depthInterp[0:(count + 1), ...], axis=0, weights='weighted', action='average') so_depthAve[count, ] = tmp tmp = cdu.averager(temp_depthInterp[0:(count + 1), ...], axis=0, weights='weighted', action='average') temp_depthAve[count, ] = tmp tmp = cdu.averager(heat_content_sanom_depthInterp[0:(count + 1), ...], axis=0, weights='weighted', action='sum') heat_content_sanom_depthInteg[count, ] = tmp tmp = cdu.averager(heat_content_tanom_depthInterp[0:(count + 1), ...], axis=0, weights='weighted', action='sum') heat_content_tanom_depthInteg[count, ] = tmp tmp = cdu.averager(heat_content_tsanom_depthInterp[0:(count + 1), ...], axis=0, weights='weighted', action='sum') heat_content_tsanom_depthInteg[count, ] = tmp del (heat_content_tanom_depthInterp, heat_content_tsanom_depthInterp) gc.collect() # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset so_depthAve = scrubNaNAndMask(so_depthAve, so_depthInterp) temp_depthAve = scrubNaNAndMask(temp_depthAve, so_depthInterp) heat_content_sanom_depthInteg = scrubNaNAndMask( heat_content_sanom_depthInteg, so_depthInterp) heat_content_tanom_depthInteg = scrubNaNAndMask( heat_content_tanom_depthInteg, so_depthInterp) heat_content_tsanom_depthInteg = scrubNaNAndMask( heat_content_tsanom_depthInteg, so_depthInterp) del (so_depthInterp) # Convert numpy arrays to cdms objects heat_content_sanom_depthInteg = cdm.createVariable( heat_content_sanom_depthInteg, id='heat_content_sanom_depthInteg') heat_content_sanom_depthInteg.id = 'heat_content_sanom_depthInteg' heat_content_sanom_depthInteg.setAxis(0, newdepth) heat_content_sanom_depthInteg.setAxis(1, so.getAxis(1)) heat_content_sanom_depthInteg.setAxis(2, so.getAxis(2)) heat_content_sanom_depthInteg.units = 'J' heat_content_tanom_depthInteg = cdm.createVariable( heat_content_tanom_depthInteg, id='heat_content_tanom_depthInteg') heat_content_tanom_depthInteg.id = 'heat_content_tanom_depthInteg' heat_content_tanom_depthInteg.setAxis(0, newdepth) heat_content_tanom_depthInteg.setAxis(1, so.getAxis(1)) heat_content_tanom_depthInteg.setAxis(2, so.getAxis(2)) heat_content_tanom_depthInteg.units = 'J' heat_content_tsanom_depthInteg = cdm.createVariable( heat_content_tsanom_depthInteg, id='heat_content_tsanom_depthInteg') heat_content_tsanom_depthInteg.id = 'heat_content_tsanom_depthInteg' heat_content_tsanom_depthInteg.setAxis(0, newdepth) heat_content_tsanom_depthInteg.setAxis(1, so.getAxis(1)) heat_content_tsanom_depthInteg.setAxis(2, so.getAxis(2)) heat_content_tsanom_depthInteg.units = 'J' so_depthAve = cdm.createVariable(so_depthAve, id='so_depthAve') so_depthAve.id = 'so_depthAve' so_depthAve.setAxis(0, newdepth) so_depthAve.setAxis(1, so.getAxis(1)) so_depthAve.setAxis(2, so.getAxis(2)) so_depthAve.units = '1e-3' temp_depthAve = cdm.createVariable(temp_depthAve, id='temp_depthAve') temp_depthAve.id = 'temp_depthAve' temp_depthAve.setAxis(0, newdepth) temp_depthAve.setAxis(1, so.getAxis(1)) temp_depthAve.setAxis(2, so.getAxis(2)) temp_depthAve.units = 'degrees_C' steric_height_depthInterp = cdm.createVariable( steric_height_depthInterp, id='steric_height_depthInterp') steric_height_depthInterp.setAxis(0, newdepth) steric_height_depthInterp.setAxis(1, so.getAxis(1)) steric_height_depthInterp.setAxis(2, so.getAxis(2)) steric_height_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_anom_depthInterp = cdm.createVariable( steric_height_anom_depthInterp, id='steric_height_anom_depthInterp') steric_height_anom_depthInterp.setAxis(0, newdepth) steric_height_anom_depthInterp.setAxis(1, so.getAxis(1)) steric_height_anom_depthInterp.setAxis(2, rho.getAxis(2)) steric_height_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_thermo_anom_depthInterp = cdm.createVariable( steric_height_thermo_anom_depthInterp, id='steric_height_thermo_anom_depthInterp') steric_height_thermo_anom_depthInterp.setAxis(0, newdepth) steric_height_thermo_anom_depthInterp.setAxis(1, so.getAxis(1)) steric_height_thermo_anom_depthInterp.setAxis(2, so.getAxis(2)) steric_height_thermo_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom_depthInterp = cdm.createVariable( steric_height_halo_anom_depthInterp, id='steric_height_halo_anom_depthInterp') steric_height_halo_anom_depthInterp.setAxis(0, newdepth) steric_height_halo_anom_depthInterp.setAxis(1, so.getAxis(1)) steric_height_halo_anom_depthInterp.setAxis(2, so.getAxis(2)) steric_height_halo_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' steric_height_halo_anom2_depthInterp = cdm.createVariable( steric_height_halo_anom2_depthInterp, id='steric_height_halo_anom2_depthInterp') steric_height_halo_anom2_depthInterp.setAxis(0, newdepth) steric_height_halo_anom2_depthInterp.setAxis(1, so.getAxis(1)) steric_height_halo_anom2_depthInterp.setAxis(2, so.getAxis(2)) steric_height_halo_anom2_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)' # Cleanup workspace del (newdepth) gc.collect() # Write variables to file if os.path.isfile(outFileName): os.remove(outFileName) filehandle = cdm.open(outFileName, 'w') # Global attributes globalAttWrite(filehandle, options=None) # Use function to write standard global atts # Write seawater version filehandle.seawater_library_version = sw.__version__ # Write makeSteric version makeStericPath = str(makeSteric.__code__).split(' ')[6] makeStericPath = replace(replace(makeStericPath, '"', ''), ',', '') # Clean scraped path filehandle.makeSteric_version = ' '.join(getGitInfo(makeStericPath)[0:3]) # Master variables filehandle.write(so.astype('float32')) filehandle.write(so_chg.astype('float32')) filehandle.write(so_depthAve.astype('float32')) filehandle.write(temp.astype('float32')) filehandle.write(temp_chg.astype('float32')) filehandle.write(temp_depthAve.astype('float32')) # Derived variables filehandle.write(cp.astype('float32')) filehandle.write(cp_halo.astype('float32')) filehandle.write(cp_thermo.astype('float32')) filehandle.write(rho.astype('float32')) filehandle.write(rho_halo.astype('float32')) filehandle.write(rho_thermo.astype('float32')) filehandle.write(heat_content.astype('float32')) filehandle.write(heat_content_sanom.astype('float32')) filehandle.write(heat_content_sanom_depthInteg.astype('float32')) filehandle.write(heat_content_tanom.astype('float32')) filehandle.write(heat_content_tanom_depthInteg.astype('float32')) filehandle.write(heat_content_tsanom.astype('float32')) filehandle.write(heat_content_tsanom_depthInteg.astype('float32')) filehandle.write(steric_height.astype('float32')) filehandle.write(steric_height_depthInterp.astype('float32')) filehandle.write(steric_height_anom.astype('float32')) filehandle.write(steric_height_anom_depthInterp.astype('float32')) filehandle.write(steric_height_halo_anom.astype('float32')) filehandle.write(steric_height_halo_anom2.astype('float32')) filehandle.write(steric_height_halo_anom_depthInterp.astype('float32')) filehandle.write(steric_height_halo_anom2_depthInterp.astype('float32')) filehandle.write(steric_height_thermo_anom.astype('float32')) filehandle.write(steric_height_thermo_anom_depthInterp.astype('float32')) filehandle.close() # Cleanup workspace del (outFileName) gc.collect()
#------------------------------------------------------------------------ # Calculate depths of each rho layer #------------------------------------------------------------------------ z = np.zeros(shape=(N ,M,L)) zw = np.zeros(shape=(N+1,M,L)) z = depths_rho(h,zeta,s_r,Cs_r,hc) #z = z[::-1,:,:] zw = depths_w( h,zeta,s_w,Cs_w,hc) #z = z[::-1,:,:] Hz = abs(zw[1:N+1,:,:]-zw[0:N,:,:]) #------------------------------------------------------------------------ # Calculate various seawater properties #------------------------------------------------------------------------ pres=sw.pres(z*-1,lat) #------------------------------------------------------------------------ # Find layer with max dT/d(sigma) #------------------------------------------------------------------------ dT=np.zeros(shape=(N-1)) for i in range(0,M): for j in range(0,L): # Cell is over the water if mask[i,j]>0: #----------------------------------------------------------------- # Load in temp,salt, age, residence time #---------------------------------------------------------------- temp =input_data.variables['temp' ][tdim,:,i,j] salt =input_data.variables['salt' ][tdim,:,i,j]
def _plot_fvcomfile(): if (w.config['fvcom']['shiftlonTF'] == 'True' and w.fvcom['shifted'] == False): w.fvcom['lon'] = w.fvcom['lon'] - 360.0 w.fvcom['trigrid'] = mplt.Triangulation(w.fvcom['lon'], w.fvcom['lat'], w.fvcom['nv']) w.fvcom['shifted'] = True elif (w.config['fvcom']['shiftlonTF'] == 'False' and w.fvcom['shifted'] == True): w.fvcom['lon'] = w.fvcom['lon'] + 360.0 w.fvcom['trigrid'] = mplt.Triangulation(w.fvcom['lon'], w.fvcom['lat'], w.fvcom['nv']) w.fvcom['shifted'] = False if 'fvcom' not in w.FIGS: w.FIGS['fvcom'] = {} if not hasattr(w, 'cb'): w.cb = {} #print(w.fvcom['lon'][0],w.fvcom['lat'][0]) state = True try: if w.fvcomplot in w.FIGS['fvcom']: w.FIGS['fvcom'][w.fvcomplot].remove() state = w.TF['fvcom'] except: w.fvcomplot = '' if w.overmenu.get() != '': if w.overmenu.get() in w.fvcom['pable']: w.fvcomplot = w.overmenu.get() else: w.fvcomplot = w.FVCOMMenuVar.get() if w.etime != '': w.timeTF = True w.time = int(w.etime.get()) else: w.timeTF = False if w.elvl != '': w.lvlTF = True w.lvl = int(w.elvl.get()) else: w.lvlTF = False #print(w.fvcomplot) if w.fvcomplot == 'dhh': dname = 'dhh' if w.fvcomplot not in w.fvcom: w.fvcom = ut.get_dhh(w.fvcom) elif w.fvcomplot == 'sidelength': dname = 'sl' if w.fvcomplot not in w.fvcom: w.fvcom = ut.get_sidelength(w.fvcom) elif (w.fvcomplot == 'speed_da' and w.timeTF): dname = 'speed_da' w.fvcom['speed_da'] = np.sqrt(w.fvcom['ua'][w.time, :]**2 + w.fvcom['va'][w.time, :]**2) elif (w.fvcomplot == 'speed' and w.timeTF and w.lvlTF): dname = 'speed' w.fvcom['speed'] = np.sqrt(w.fvcom['u'][w.time, w.lvl, :]**2 + w.fvcom['v'][w.time, w.lvl, :]**2) elif (w.fvcomplot == 'vorticity_da' and w.timeTF): dname = 'field' i = w.time dudy = w.fvcom['a2u'][0,:]*w.fvcom['ua'][i,:]+w.fvcom['a2u'][1,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,0]] +\ w.fvcom['a2u'][2,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,1]]+w.fvcom['a2u'][3,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,2]] dvdx = w.fvcom['a1u'][0,:]*w.fvcom['va'][i,:]+w.fvcom['a1u'][1,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,0]] +\ w.fvcom['a1u'][2,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,1]]+w.fvcom['a1u'][3,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,2]] w.fvcom[dname] = dvdx - dudy elif (w.fvcomplot == 'vorticity' and w.timeTF and w.lvlTF): dname = 'field' i = w.time layer = w.lvl dudy = w.fvcom['a2u'][0,:]*w.fvcom['u'][i,layer,:]+w.fvcom['a2u'][1,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,0]] +\ w.fvcom['a2u'][2,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,1]]+w.fvcom['a2u'][3,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,2]] dvdx = w.fvcom['a1u'][0,:]*w.fvcom['v'][i,layer,:]+w.fvcom['a1u'][1,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,0]] +\ w.fvcom['a1u'][2,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,1]]+w.fvcom['a1u'][3,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,2]] w.fvcom[dname] = dvdx - dudy elif (w.fvcomplot == 'density' and w.timeTF and w.lvlTF): dname = 'field' i = w.time layer = w.lvl pres = sw.pres(w.fvcom['h'] + w.fvcom['zeta'][i, :], w.fvcom['lat']) w.fvcom[dname] = sw.dens(w.fvcom['salinity'][i, layer, :], w.fvcom['temp'][i, layer, :], pres) else: dname = 'field' shp = np.shape(w.fvcom[w.fvcomplot]) tTF = (len(w.fvcom['time']) in shp) lTF = (w.fvcom['dims']['siglev'] in shp) or (w.fvcom['dims']['siglay'] in shp) if (tTF == False and lTF == False): w.fvcom[dname] = w.fvcom[w.fvcomplot] elif (tTF == True and lTF == False): w.fvcom[dname] = w.fvcom[w.fvcomplot][w.time, :] else: w.fvcom[dname] = w.fvcom[w.fvcomplot][w.time, w.lvl, :] cmin, cmax = getcb(w.fvcom[dname]) w.FIGS['fvcom'][w.fvcomplot] = w.ax.tripcolor( w.fvcom['trigrid'], w.fvcom[dname], vmin=cmin, vmax=cmax, visible=state, cmap=w.config['fvcom']['colormap'], zorder=int(w.config['fvcom']['zorder'])) w.cb[w.fvcomplot] = w.figure.colorbar(w.FIGS['fvcom'][w.fvcomplot], cax=w.cax) w.figure.canvas.draw() return