def main(args): f = nc.Dataset(args.infile) if 'basin' in list(f.variables.keys()): sys.stdout.write( 'The basin field already appears to be in the static file. Exiting.' ) exit(1) if args.outfile is None: outfile = os.path.basename(args.infile) outfile = outfile.split('.') outfile.insert(-1, 'basins') outfile = str('.').join(outfile) else: outfile = args.outfile if os.path.exists(outfile): sys.stdout.write( 'File already exists ... would you like to overwrite? (y/n): ') choice = input().lower() if choice == 'y': if args.verbose: sys.stdout.write('Overwriting file: ' + outfile + '\n') elif choice == 'n': exit(1) else: sys.stdout.write('Please respond with \'y\' or \'n\'') geolon = np.array(f.variables['geolon'][:]) geolat = np.array(f.variables['geolat'][:]) deptho = np.array(f.variables['deptho'][:].filled(0)) basin_code = m6toolbox.genBasinMasks(geolon, geolat, deptho, args.verbose) shutil.copyfile(args.infile, outfile) nc_out = nc.Dataset(outfile, 'r+', format='NETCDF3_CLASSIC') basin_out = nc_out.createVariable('basin', np.int32, ('yh', 'xh')) basin_out.setncattr('long_name', 'Region Selection Index') basin_out.setncattr('standard_name', 'region') basin_out.setncattr('units', '1.0') basin_out.setncattr('interp_method', 'none') basin_out.setncattr('flag_values', '0 1 2 3 4 5 6 7 8 9 10') basin_out.setncattr('flag_meanings','global_land southern_ocean atlantic_ocean pacific_ocean '+\ 'arctic_ocean indian_ocean mediterranean_sea black_sea hudson_bay baltic_sea red_sea') basin_out[:] = basin_code[:] nc_out.close() exit(0)
def main(cmdLineArgs,stream=None): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError('Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): x = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['x'][::2,::2] xcenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['x'][1::2,1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][::2,::2] ycenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][1::2,1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_mask.nc').variables['mask'][:] area = msk*netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['area'][:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_topog.nc').variables['depth'][:] try: basin_code = netCDF4.Dataset(cmdLineArgs.gridspec+'/basin_codes.nc').variables['basin'][:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[::2,::2] xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[1::2,1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[::2,::2] ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[1::2,1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_mask.nc','mask')[:] area = msk*m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','area')[:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_topog.nc','depth')[:] try: basin_code = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'basin_codes.nc','basin')[:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError('Unable to extract grid information from gridspec directory/tar file.') if stream != None: if len(stream) != 2: raise ValueError('If specifying output streams, exactly two streams are needed for this analysis') rootGroup = netCDF4.MFDataset( cmdLineArgs.annual_file ) if 'vh' in rootGroup.variables: varName = 'vh'; conversion_factor = 1.e-9 elif 'vmo' in rootGroup.variables: varName = 'vmo'; conversion_factor = 1.e-9 else: raise Exception('Could not find "vh" or "vmo" in file "%s"'%(cmdLineArgs.annual_file)) if len(rootGroup.variables[varName].shape)==4: VHmod = rootGroup.variables[varName][:].mean(axis=0) else: VHmod = rootGroup.variables[varName][:] try: VHmod = VHmod.filled(0.) except: pass if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'][0] elif 'zw' in rootGroup.variables: zw = rootGroup.variables['zw'][:] Zmod = numpy.zeros((zw.shape[0], depth.shape[0], depth.shape[1] )) for k in range(zw.shape[0]): Zmod[k] = -numpy.minimum( depth, abs(zw[k]) ) else: raise Exception('Neither a model-space output file or a z-space diagnostic file?') def MOCpsi(vh, vmsk=None): """Sums 'vh' zonally and cumulatively in the vertical to yield an overturning stream function, psi(y,z).""" shape = list(vh.shape); shape[-3] += 1 psi = numpy.zeros(shape[:-1]) if len(shape)==3: for k in range(shape[-3]-1,0,-1): if vmsk is None: psi[k-1,:] = psi[k,:] - vh[k-1].sum(axis=-1) else: psi[k-1,:] = psi[k,:] - (vmsk*vh[k-1]).sum(axis=-1) else: for n in range(shape[0]): for k in range(shape[-3]-1,0,-1): if vmsk is None: psi[n,k-1,:] = psi[n,k,:] - vh[n,k-1].sum(axis=-1) else: psi[n,k-1,:] = psi[n,k,:] - (vmsk*vh[n,k-1]).sum(axis=-1) return psi def plotPsi(y, z, psi, ci, title): cmap = plt.get_cmap('dunnePM') plt.contourf(y, z, psi, levels=ci, cmap=cmap, extend='both') cbar = plt.colorbar() plt.contour(y, z, psi, levels=ci, colors='k', hold='on') plt.gca().set_yscale('splitscale',zval=[0,-2000,-6500]) plt.title(title) cbar.set_label('[Sv]'); plt.ylabel('Elevation [m]') def findExtrema(y, z, psi, min_lat=-90., max_lat=90., min_depth=0., mult=1.): psiMax = mult*numpy.amax( mult * numpy.ma.array(psi)[(y>=min_lat) & (y<=max_lat) & (z<-min_depth)] ) idx = numpy.argmin(numpy.abs(psi-psiMax)) (j,i) = numpy.unravel_index(idx, psi.shape) plt.plot(y[j,i],z[j,i],'kx',hold=True) plt.text(y[j,i],z[j,i],'%.1f'%(psi[j,i])) m6plot.setFigureSize(npanels=1) cmap = plt.get_cmap('dunnePM') if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label # Global MOC z = Zmod.min(axis=-1); psiPlot = MOCpsi(VHmod)*conversion_factor yy = y[1:,:].max(axis=-1)+0*z ci=m6plot.pmCI(0.,40.,5.) plotPsi(yy, z, psiPlot, ci, 'Global MOC [Sv]') plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) findExtrema(yy, z, psiPlot, max_lat=-30.) findExtrema(yy, z, psiPlot, min_lat=25.) findExtrema(yy, z, psiPlot, min_depth=2000., mult=-1.) if stream != None: plt.savefig(stream[0]) else: plt.savefig(cmdLineArgs.outdir+'/MOC_global.png') # Atlantic MOC plt.clf() m = 0*basin_code; m[(basin_code==2) | (basin_code==4) | (basin_code==6) | (basin_code==7) | (basin_code==8)]=1 ci=m6plot.pmCI(0.,22.,2.) z = (m*Zmod).min(axis=-1); psiPlot = MOCpsi(VHmod, vmsk=m*numpy.roll(m,-1,axis=-2))*conversion_factor yy = y[1:,:].max(axis=-1)+0*z plotPsi(yy, z, psiPlot, ci, 'Atlantic MOC [Sv]') plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) findExtrema(yy, z, psiPlot, min_lat=26.5, max_lat=27.) # RAPID findExtrema(yy, z, psiPlot, max_lat=-33.) findExtrema(yy, z, psiPlot) findExtrema(yy, z, psiPlot, min_lat=5.) if stream != None: plt.savefig(stream[1]) else: plt.savefig(cmdLineArgs.outdir+'/MOC_Atlantic.png')
def main(cmdLineArgs, stream=None): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError( 'Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): x = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][::2, ::2] xcenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][1::2, 1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][::2, ::2] ycenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_mask.nc').variables['mask'][:] area = msk * netCDF4.Dataset( cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['area'][:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_topog.nc').variables['depth'][:] try: basin_code = netCDF4.Dataset( cmdLineArgs.gridspec + '/basin_codes.nc').variables['basin'][:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[::2, ::2] xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[1::2, 1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[::2, ::2] ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_mask.nc', 'mask')[:] area = msk * m6toolbox.readNCFromTar( cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'area')[:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_topog.nc', 'depth')[:] try: basin_code = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'basin_codes.nc', 'basin')[:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError( 'Unable to extract grid information from gridspec directory/tar file.' ) if stream != None: if len(stream) != 2: raise ValueError( 'If specifying output streams, exactly two streams are needed for this analysis' ) rootGroup = netCDF4.MFDataset(cmdLineArgs.annual_file) if 'vh' in rootGroup.variables: varName = 'vh' conversion_factor = 1.e-9 elif 'vmo' in rootGroup.variables: varName = 'vmo' conversion_factor = 1.e-9 else: raise Exception('Could not find "vh" or "vmo" in file "%s"' % (cmdLineArgs.annual_file)) if len(rootGroup.variables[varName].shape) == 4: VHmod = rootGroup.variables[varName][:].mean(axis=0) else: VHmod = rootGroup.variables[varName][:] try: VHmod = VHmod.filled(0.) except: pass if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'][0] elif 'zw' in rootGroup.variables: zw = rootGroup.variables['zw'][:] Zmod = numpy.zeros((zw.shape[0], depth.shape[0], depth.shape[1])) for k in range(zw.shape[0]): Zmod[k] = -numpy.minimum(depth, abs(zw[k])) else: raise Exception( 'Neither a model-space output file or a z-space diagnostic file?') def MOCpsi(vh, vmsk=None): """Sums 'vh' zonally and cumulatively in the vertical to yield an overturning stream function, psi(y,z).""" shape = list(vh.shape) shape[-3] += 1 psi = numpy.zeros(shape[:-1]) if len(shape) == 3: for k in range(shape[-3] - 1, 0, -1): if vmsk is None: psi[k - 1, :] = psi[k, :] - vh[k - 1].sum(axis=-1) else: psi[k - 1, :] = psi[k, :] - (vmsk * vh[k - 1]).sum(axis=-1) else: for n in range(shape[0]): for k in range(shape[-3] - 1, 0, -1): if vmsk is None: psi[n, k - 1, :] = psi[n, k, :] - vh[n, k - 1].sum(axis=-1) else: psi[n, k - 1, :] = psi[n, k, :] - (vmsk * vh[n, k - 1]).sum(axis=-1) return psi def plotPsi(y, z, psi, ci, title): cmap = plt.get_cmap('dunnePM') plt.contourf(y, z, psi, levels=ci, cmap=cmap, extend='both') cbar = plt.colorbar() plt.contour(y, z, psi, levels=ci, colors='k', hold='on') plt.gca().set_yscale('splitscale', zval=[0, -2000, -6500]) plt.title(title) cbar.set_label('[Sv]') plt.ylabel('Elevation [m]') def findExtrema(y, z, psi, min_lat=-90., max_lat=90., min_depth=0., mult=1.): psiMax = mult * numpy.amax( mult * numpy.ma.array(psi)[(y >= min_lat) & (y <= max_lat) & (z < -min_depth)]) idx = numpy.argmin(numpy.abs(psi - psiMax)) (j, i) = numpy.unravel_index(idx, psi.shape) plt.plot(y[j, i], z[j, i], 'kx', hold=True) plt.text(y[j, i], z[j, i], '%.1f' % (psi[j, i])) m6plot.setFigureSize(npanels=1) cmap = plt.get_cmap('dunnePM') if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label # Global MOC z = Zmod.min(axis=-1) psiPlot = MOCpsi(VHmod) * conversion_factor yy = y[1:, :].max(axis=-1) + 0 * z ci = m6plot.pmCI(0., 40., 5.) plotPsi(yy, z, psiPlot, ci, 'Global MOC [Sv]') plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) findExtrema(yy, z, psiPlot, max_lat=-30.) findExtrema(yy, z, psiPlot, min_lat=25.) findExtrema(yy, z, psiPlot, min_depth=2000., mult=-1.) if stream != None: plt.savefig(stream[0]) else: plt.savefig(cmdLineArgs.outdir + '/MOC_global.png') # Atlantic MOC plt.clf() m = 0 * basin_code m[(basin_code == 2) | (basin_code == 4) | (basin_code == 6) | (basin_code == 7) | (basin_code == 8)] = 1 ci = m6plot.pmCI(0., 22., 2.) z = (m * Zmod).min(axis=-1) psiPlot = MOCpsi(VHmod, vmsk=m * numpy.roll(m, -1, axis=-2)) * conversion_factor yy = y[1:, :].max(axis=-1) + 0 * z plotPsi(yy, z, psiPlot, ci, 'Atlantic MOC [Sv]') plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) findExtrema(yy, z, psiPlot, min_lat=26.5, max_lat=27.) # RAPID findExtrema(yy, z, psiPlot, max_lat=-33.) findExtrema(yy, z, psiPlot) findExtrema(yy, z, psiPlot, min_lat=5.) if stream != None: plt.savefig(stream[1]) else: plt.savefig(cmdLineArgs.outdir + '/MOC_Atlantic.png')
def main(cmdLineArgs,stream=None): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError('Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): xcenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['x'][1::2,1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][1::2,1::2].max(axis=-1) ycenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][1::2,1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_mask.nc').variables['mask'][:] area = msk*netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['area'][:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_topog.nc').variables['depth'][:] try: basin = netCDF4.Dataset(cmdLineArgs.gridspec+'/basin_codes.nc').variables['basin'][:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[1::2,1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[1::2,1::2].max(axis=-1) ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[1::2,1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_mask.nc','mask')[:] area = msk*m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','area')[:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_topog.nc','depth')[:] try: basin = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'basin_codes.nc','basin')[:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError('Unable to extract grid information from gridspec directory/tar file.') if stream != None: if len(stream) != 4: raise ValueError('If specifying output streams, exactly four (4) streams are needed for this analysis') Sobs = netCDF4.Dataset( cmdLineArgs.woa ).variables['salt'] if len(Sobs.shape)==3: Sobs = Sobs[:] else: Sobs = Sobs[:].mean(axis=0) Zobs = netCDF4.Dataset( cmdLineArgs.woa ).variables['eta'][:] rootGroup = netCDF4.MFDataset( cmdLineArgs.annual_file ) if 'salt' in rootGroup.variables: varName = 'salt' elif 'so' in rootGroup.variables: varName = 'so' else:raise Exception('Could not find "salt" or "so" in file "%s"'%(cmdLineArgs.annual_file)) if len(rootGroup.variables[varName].shape)==4: Smod = rootGroup.variables[varName][:].mean(axis=0) else: Smod = rootGroup.variables[varName][:] if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'][0] else: Zmod = Zobs # Using model z-output def zonalAverage(S, eta, area, mask=1.): vols = ( mask * area ) * ( eta[:-1] - eta[1:] ) # mask * area * level thicknesses return numpy.sum( vols * S, axis=-1 ) / numpy.sum( vols, axis=-1 ), (mask*eta).min(axis=-1) ci=m6plot.pmCI(0.125,2.25,.25) if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label # Global sPlot, z = zonalAverage(Smod, Zmod, area) sObsPlot, _ = zonalAverage(Sobs, Zobs, area) if stream != None: objOut = stream[0] else: objOut = cmdLineArgs.outdir+'/S_global_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Global zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare( sPlot, sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Global zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20,30,10, 31,39,.5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir+'/S_global_xave_bias_WOA05.3_panel.png') # Atlantic + Arctic newMask = 1.*msk; newMask[ (basin!=2) & (basin!=4) ] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[1] else: objOut = cmdLineArgs.outdir+'/S_Atlantic_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Atlantic zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare( sPlot, sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Atlantic zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20,30,10, 31,39,.5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir+'/S_Atlantic_xave_bias_WOA05.3_panel.png') # Pacific newMask = 1.*msk; newMask[ (basin!=3) ] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[2] else: objOut = cmdLineArgs.outdir+'/S_Pacific_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Pacific zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare( sPlot, sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Pacific zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20,30,10, 31,39,.5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir+'/S_Pacific_xave_bias_WOA05.3_panel.png') # Indian newMask = 1.*msk; newMask[ (basin!=5) ] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[3] else: objOut = cmdLineArgs.outdir+'/S_Indian_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Indian zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare( sPlot, sObsPlot , y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Indian zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20,30,10, 31,39,.5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir+'/S_Indian_xave_bias_WOA05.3_panel.png')
msk = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_mask.nc').variables['mask'][:] area = msk*netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['area'][:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_topog.nc').variables['depth'][:] elif os.path.isfile(cmdLineArgs.gridspec): x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[1::2,1::2] xg = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[0::2,0::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[1::2,1::2] yg = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[0::2,0::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_mask.nc','mask')[:] area = msk*m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','area')[:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_topog.nc','depth')[:] else: raise ValueError('Unable to extract grid information from gridspec directory/tar file.') # Basin codes basin = m6toolbox.genBasinMasks(x, y, depth) # All ocean points seeded from South Atlantic obsRootGroup = netCDF4.Dataset( cmdLineArgs.woa ) if 'temp' in obsRootGroup.variables: OTvar = 'temp' else: OTvar = 'ptemp' Zobs = netCDF4.Dataset( cmdLineArgs.woa ).variables['eta'] rootGroup = netCDF4.Dataset( cmdLineArgs.annual_file ) if 'temp' in rootGroup.variables: varName = 'temp' elif 'ptemp' in rootGroup.variables: varName = 'ptemp' elif 'thetao' in rootGroup.variables: varName = 'thetao' else: raise Exception('Could not find "temp", "ptemp" or "thetao" in file "%s"'%(cmdLineArgs.annual_file)) if len(rootGroup.variables[varName].shape)==4: need_time_average = True else: need_time_average = False if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'] else: Zmod = Zobs # Using model z-output
def main(cmdLineArgs, stream=False): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError( 'Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): x = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][::2, ::2] xcenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][1::2, 1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][::2, ::2] ycenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_mask.nc').variables['mask'][:] area = msk * netCDF4.Dataset( cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['area'][:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_topog.nc').variables['depth'][:] try: basin_code = netCDF4.Dataset( cmdLineArgs.gridspec + '/basin_codes.nc').variables['basin'][:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[::2, ::2] xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[1::2, 1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[::2, ::2] ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_mask.nc', 'mask')[:] area = msk * m6toolbox.readNCFromTar( cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'area')[:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_topog.nc', 'depth')[:] try: basin_code = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'basin_codes.nc', 'basin')[:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError( 'Unable to extract grid information from gridspec directory/tar file.' ) rootGroup = netCDF4.MFDataset(cmdLineArgs.infile) if 'T_ady_2d' in rootGroup.variables: varName = 'T_ady_2d' advective = rootGroup.variables[varName] advective.data = advective[:].filled(0.) else: raise Exception('Could not find "T_ady_2d" in file "%s"' % (cmdLineArgs.infile)) if 'T_diffy_2d' in rootGroup.variables: varName = 'T_diffy_2d' diffusive = rootGroup.variables[varName][:].filled(0.) else: diffusive = None warnings.warn( 'Diffusive temperature term not found. This will result in an underestimation of the heat transport.' ) def heatTrans(advective, diffusive=None, vmask=None): """Converts vertically integrated temperature advection into heat transport""" if diffusive != None: HT = advective[:] + diffusive[:] else: HT = advective[:] if len(HT.shape) == 3: HT = HT.mean(axis=0) if advective.units == "Celsius meter3 second-1": rho0 = 1.035e3 Cp = 3989. HT = HT * (rho0 * Cp) HT = HT * 1.e-15 # convert to PW elif advective.units == "W m-2": HT = HT * 1.e-15 else: print('Unknown units') if vmask != None: HT = HT * vmask HT = HT.sum(axis=-1) HT = HT.squeeze() # sum in x-direction return HT def plotHeatTrans(y, HT, title, xlim=(-80, 90)): plt.plot(y, y * 0., 'k', linewidth=0.5) plt.plot(y, HT, 'r', linewidth=1.5, label='Model') plt.xlim(xlim) plt.ylim(-2.5, 3.0) plt.title(title) plt.grid(True) def annotatePlot(label): fig = plt.gcf() #fig.text(0.1,0.85,label) fig.text(0.535, 0.12, label) def annotateObs(): fig = plt.gcf() fig.text( 0.1, 0.85, r"Trenberth, K. E. and J. M. Caron, 2001: Estimates of Meridional Atmosphere and Ocean Heat Transports. J.Climate, 14, 3433-3443.", fontsize=8) fig.text( 0.1, 0.825, r"Ganachaud, A. and C. Wunsch, 2000: Improved estimates of global ocean circulation, heat transport and mixing from hydrographic data.", fontsize=8) fig.text(0.13, 0.8, r"Nature, 408, 453-457", fontsize=8) m6plot.setFigureSize(npanels=1) # Load Observations fObs = netCDF4.Dataset( '/archive/John.Krasting/obs/TC2001/Trenberth_and_Caron_Heat_Transport.nc' ) #Trenberth and Caron yobs = fObs.variables['ylat'][:] NCEP = {} NCEP['Global'] = fObs.variables['OTn'] NCEP['Atlantic'] = fObs.variables['ATLn'][:] NCEP['IndoPac'] = fObs.variables['INDPACn'][:] ECMWF = {} ECMWF['Global'] = fObs.variables['OTe'][:] ECMWF['Atlantic'] = fObs.variables['ATLe'][:] ECMWF['IndoPac'] = fObs.variables['INDPACe'][:] #G and W Global = {} Global['lat'] = numpy.array([-30., -19., 24., 47.]) Global['trans'] = numpy.array([-0.6, -0.8, 1.8, 0.6]) Global['err'] = numpy.array([0.3, 0.6, 0.3, 0.1]) Atlantic = {} Atlantic['lat'] = numpy.array( [-45., -30., -19., -11., -4.5, 7.5, 24., 47.]) Atlantic['trans'] = numpy.array( [0.66, 0.35, 0.77, 0.9, 1., 1.26, 1.27, 0.6]) Atlantic['err'] = numpy.array( [0.12, 0.15, 0.2, 0.4, 0.55, 0.31, 0.15, 0.09]) IndoPac = {} IndoPac['lat'] = numpy.array([-30., -18., 24., 47.]) IndoPac['trans'] = numpy.array([-0.9, -1.6, 0.52, 0.]) IndoPac['err'] = numpy.array([ 0.3, 0.6, 0.2, 0.05, ]) GandW = {} GandW['Global'] = Global GandW['Atlantic'] = Atlantic GandW['IndoPac'] = IndoPac def plotGandW(lat, trans, err): low = trans - err high = trans + err for n in range(0, len(low)): if n == 0: plt.plot([lat[n], lat[n]], [low[n], high[n]], 'c', linewidth=2.0, label='G&W') else: plt.plot([lat[n], lat[n]], [low[n], high[n]], 'c', linewidth=2.0) plt.scatter(lat, trans, marker='s', facecolor='cyan') if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label imgbufs = [] # Global Heat Transport HTplot = heatTrans(advective, diffusive) yy = y[1:, :].max(axis=-1) plotHeatTrans(yy, HTplot, title='Global Y-Direction Heat Transport [PW]') plt.plot(yobs, NCEP['Global'], 'k--', linewidth=0.5, label='NCEP') plt.plot(yobs, ECMWF['Global'], 'k.', linewidth=0.5, label='ECMWF') plotGandW(GandW['Global']['lat'], GandW['Global']['trans'], GandW['Global']['err']) plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) plt.legend(loc=0, fontsize=10) annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/HeatTransport_global.png' plt.savefig(objOut) if stream is True: imgbufs.append(objOut) # Atlantic Heat Transport plt.clf() m = 0 * basin_code m[(basin_code == 2) | (basin_code == 4) | (basin_code == 6) | (basin_code == 7) | (basin_code == 8)] = 1 HTplot = heatTrans(advective, diffusive, vmask=m * numpy.roll(m, -1, axis=-2)) yy = y[1:, :].max(axis=-1) HTplot[yy < -34] = numpy.nan plotHeatTrans(yy, HTplot, title='Atlantic Y-Direction Heat Transport [PW]') plt.plot(yobs, NCEP['Atlantic'], 'k--', linewidth=0.5, label='NCEP') plt.plot(yobs, ECMWF['Atlantic'], 'k.', linewidth=0.5, label='ECMWF') plotGandW(GandW['Atlantic']['lat'], GandW['Atlantic']['trans'], GandW['Atlantic']['err']) plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) plt.legend(loc=0, fontsize=10) annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/HeatTransport_Atlantic.png' plt.savefig(objOut) if stream is True: imgbufs.append(objOut) # Indo-Pacific Heat Transport plt.clf() m = 0 * basin_code m[(basin_code == 3) | (basin_code == 5)] = 1 HTplot = heatTrans(advective, diffusive, vmask=m * numpy.roll(m, -1, axis=-2)) yy = y[1:, :].max(axis=-1) HTplot[yy < -34] = numpy.nan plotHeatTrans(yy, HTplot, title='Indo-Pacific Y-Direction Heat Transport [PW]') plt.plot(yobs, NCEP['IndoPac'], 'k--', linewidth=0.5, label='NCEP') plt.plot(yobs, ECMWF['IndoPac'], 'k.', linewidth=0.5, label='ECMWF') plotGandW(GandW['IndoPac']['lat'], GandW['IndoPac']['trans'], GandW['IndoPac']['err']) plt.xlabel(r'Latitude [$\degree$N]') annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') plt.suptitle(suptitle) plt.legend(loc=0, fontsize=10) if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/HeatTransport_IndoPac.png' plt.savefig(objOut) if stream is True: imgbufs.append(objOut) if stream is True: return imgbufs
import matplotlib.colors import matplotlib.patches as mpatches import os import sys gridspec = '/archive/gold/datasets/OM4_025/mosaic.v20140610.unpacked' x = netCDF4.Dataset(gridspec+'/ocean_hgrid.nc').variables['x'][::2,::2] xcenter = netCDF4.Dataset(gridspec+'/ocean_hgrid.nc').variables['x'][1::2,1::2] y = netCDF4.Dataset(gridspec+'/ocean_hgrid.nc').variables['y'][::2,::2] ycenter = netCDF4.Dataset(gridspec+'/ocean_hgrid.nc').variables['y'][1::2,1::2] msk = netCDF4.Dataset(gridspec+'/ocean_mask.nc').variables['mask'][:] area = msk*netCDF4.Dataset(gridspec+'/ocean_hgrid.nc').variables['area'][:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(gridspec+'/ocean_topog.nc').variables['depth'][:] code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) cmap = matplotlib.colors.ListedColormap(['#a1a1a1','#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99', '#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a']) colors = ['#a1a1a1','#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99', '#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] cmap = matplotlib.colors.ListedColormap(colors) plt.figure() plt.pcolormesh(code,cmap=cmap) plt.title('Basin Mask') ax = plt.gca()
gridspec = '/archive/gold/datasets/OM4_025/mosaic.v20140610.unpacked' x = netCDF4.Dataset(gridspec + '/ocean_hgrid.nc').variables['x'][::2, ::2] xcenter = netCDF4.Dataset(gridspec + '/ocean_hgrid.nc').variables['x'][1::2, 1::2] y = netCDF4.Dataset(gridspec + '/ocean_hgrid.nc').variables['y'][::2, ::2] ycenter = netCDF4.Dataset(gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2] msk = netCDF4.Dataset(gridspec + '/ocean_mask.nc').variables['mask'][:] area = msk * netCDF4.Dataset( gridspec + '/ocean_hgrid.nc').variables['area'][:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(gridspec + '/ocean_topog.nc').variables['depth'][:] code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) cmap = matplotlib.colors.ListedColormap([ '#a1a1a1', '#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a' ]) colors = [ '#a1a1a1', '#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a' ] cmap = matplotlib.colors.ListedColormap(colors) plt.figure() plt.pcolormesh(code, cmap=cmap)
def main(cmdLineArgs, stream=False): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError( 'Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): xcenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][1::2, 1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2].max( axis=-1) ycenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_mask.nc').variables['mask'][:] area = msk * netCDF4.Dataset( cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['area'][:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_topog.nc').variables['depth'][:] try: basin = netCDF4.Dataset(cmdLineArgs.gridspec + '/basin_codes.nc').variables['basin'][:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[1::2, 1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2].max(axis=-1) ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_mask.nc', 'mask')[:] area = msk * m6toolbox.readNCFromTar( cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'area')[:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_topog.nc', 'depth')[:] try: basin = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'basin_codes.nc', 'basin')[:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError( 'Unable to extract grid information from gridspec directory/tar file.' ) Sobs = netCDF4.Dataset(cmdLineArgs.woa).variables['salt'] if len(Sobs.shape) == 3: Sobs = Sobs[:] else: Sobs = Sobs[:].mean(axis=0) Zobs = netCDF4.Dataset(cmdLineArgs.woa).variables['eta'][:] rootGroup = netCDF4.MFDataset(cmdLineArgs.infile) if 'salt' in rootGroup.variables: varName = 'salt' elif 'so' in rootGroup.variables: varName = 'so' else: raise Exception('Could not find "salt" or "so" in file "%s"' % (cmdLineArgs.infile)) if len(rootGroup.variables[varName].shape) == 4: Smod = rootGroup.variables[varName][:].mean(axis=0) else: Smod = rootGroup.variables[varName][:] if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'][0] else: Zmod = Zobs # Using model z-output def zonalAverage(S, eta, area, mask=1.): vols = (mask * area) * (eta[:-1] - eta[1:] ) # mask * area * level thicknesses return numpy.sum(vols * S, axis=-1) / numpy.sum(vols, axis=-1), ( mask * eta).min(axis=-1) ci = m6plot.pmCI(0.125, 2.25, .25) if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label imgbufs = [] # Global sPlot, z = zonalAverage(Smod, Zmod, area) sObsPlot, _ = zonalAverage(Sobs, Zobs, area) if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/S_global_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Global zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is True: imgbufs.append(objOut) if stream is None: m6plot.yzcompare(sPlot, sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Global zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20, 30, 10, 31, 39, .5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/S_global_xave_bias_WOA05.3_panel.png') # Atlantic + Arctic newMask = 1. * msk newMask[(basin != 2) & (basin != 4)] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/S_Atlantic_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Atlantic zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is True: imgbufs.append(objOut) if stream is None: m6plot.yzcompare(sPlot, sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Atlantic zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20, 30, 10, 31, 39, .5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/S_Atlantic_xave_bias_WOA05.3_panel.png') # Pacific newMask = 1. * msk newMask[(basin != 3)] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/S_Pacific_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Pacific zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is True: imgbufs.append(objOut) if stream is None: m6plot.yzcompare(sPlot, sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Pacific zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20, 30, 10, 31, 39, .5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/S_Pacific_xave_bias_WOA05.3_panel.png') # Indian newMask = 1. * msk newMask[(basin != 5)] = 0. sPlot, z = zonalAverage(Smod, Zmod, area, mask=newMask) sObsPlot, _ = zonalAverage(Sobs, Zobs, area, mask=newMask) if stream is True: objOut = io.BytesIO() else: objOut = cmdLineArgs.outdir + '/S_Indian_xave_bias_WOA05.png' m6plot.yzplot( sPlot - sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title='''Indian zonal-average salinity bias (w.r.t. WOA'05) [ppt]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is True: imgbufs.append(objOut) if stream is None: m6plot.yzcompare(sPlot, sObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1='Indian zonal-average salinity [ppt]', title2='''WOA'05 salinity [ppt]''', clim=m6plot.linCI(20, 30, 10, 31, 39, .5), colormap='dunneRainbow', extend='both', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/S_Indian_xave_bias_WOA05.3_panel.png') if stream is True: return imgbufs
def main(cmdLineArgs,stream=None): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError('Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): x = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['x'][::2,::2] xcenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['x'][1::2,1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][::2,::2] ycenter = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['y'][1::2,1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_mask.nc').variables['mask'][:] area = msk*netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_hgrid.nc').variables['area'][:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec+'/ocean_topog.nc').variables['depth'][:] try: basin_code = netCDF4.Dataset(cmdLineArgs.gridspec+'/basin_codes.nc').variables['basin'][:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[::2,::2] xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','x')[1::2,1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[::2,::2] ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','y')[1::2,1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_mask.nc','mask')[:] area = msk*m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_hgrid.nc','area')[:,:].reshape([msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'ocean_topog.nc','depth')[:] try: basin_code = m6toolbox.readNCFromTar(cmdLineArgs.gridspec,'basin_codes.nc','basin')[:] except: basin_code = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError('Unable to extract grid information from gridspec directory/tar file.') if stream != None: if len(stream) != 3: raise ValueError('If specifying output streams, exactly three streams are needed for this analysis') rootGroup = netCDF4.MFDataset( cmdLineArgs.annual_file ) if 'T_ady_2d' in rootGroup.variables: varName = 'T_ady_2d' if len(rootGroup.variables[varName].shape)==3: advective = rootGroup.variables[varName][:].mean(axis=0).filled(0.) else: advective = rootGroup.variables[varName][:].filled(0.) else: raise Exception('Could not find "T_ady_2d" in file "%s"'%(cmdLineArgs.annual_file)) if 'T_diffy_2d' in rootGroup.variables: varName = 'T_diffy_2d' if len(rootGroup.variables[varName].shape)==3: diffusive = rootGroup.variables[varName][:].mean(axis=0).filled(0.) else: diffusive = rootGroup.variables[varName][:].filled(0.) else: diffusive = None warnings.warn('Diffusive temperature term not found. This will result in an underestimation of the heat transport.') def heatTrans(advective, diffusive=None, vmask=None): """Converts vertically integrated temperature advection into heat transport""" rho0 = 1.035e3; Cp = 3989. if diffusive != None: HT = advective + diffusive else: HT = advective HT = HT * (rho0 * Cp); HT = HT * 1.e-15 # convert to PW if vmask != None: HT = HT*vmask HT = HT.sum(axis=-1); HT = HT.squeeze() # sum in x-direction return HT def plotHeatTrans(y, HT, title, xlim=(-80,90)): plt.plot(y, y*0., 'k', linewidth=0.5) plt.plot(y, HT, 'r', linewidth=1.5,label='Model') plt.xlim(xlim); plt.ylim(-2.5,3.0) plt.title(title) plt.grid(True) def annotatePlot(label): fig = plt.gcf() #fig.text(0.1,0.85,label) fig.text(0.535,0.12,label) def annotateObs(): fig = plt.gcf() fig.text(0.1,0.85,r"Trenberth, K. E. and J. M. Caron, 2001: Estimates of Meridional Atmosphere and Ocean Heat Transports. J.Climate, 14, 3433-3443.", fontsize=8) fig.text(0.1,0.825,r"Ganachaud, A. and C. Wunsch, 2000: Improved estimates of global ocean circulation, heat transport and mixing from hydrographic data.", fontsize=8) fig.text(0.13,0.8,r"Nature, 408, 453-457", fontsize=8) m6plot.setFigureSize(npanels=1) # Load Observations fObs = netCDF4.Dataset('/archive/John.Krasting/obs/TC2001/Trenberth_and_Caron_Heat_Transport.nc') #Trenberth and Caron yobs = fObs.variables['ylat'][:] NCEP = {}; NCEP['Global'] = fObs.variables['OTn'] NCEP['Atlantic'] = fObs.variables['ATLn'][:]; NCEP['IndoPac'] = fObs.variables['INDPACn'][:] ECMWF = {}; ECMWF['Global'] = fObs.variables['OTe'][:] ECMWF['Atlantic'] = fObs.variables['ATLe'][:]; ECMWF['IndoPac'] = fObs.variables['INDPACe'][:] #G and W Global = {} Global['lat'] = numpy.array([-30., -19., 24., 47.]) Global['trans'] = numpy.array([-0.6, -0.8, 1.8, 0.6]) Global['err'] = numpy.array([0.3, 0.6, 0.3, 0.1]) Atlantic = {} Atlantic['lat'] = numpy.array([-45., -30., -19., -11., -4.5, 7.5, 24., 47.]) Atlantic['trans'] = numpy.array([0.66, 0.35, 0.77, 0.9, 1., 1.26, 1.27, 0.6]) Atlantic['err'] = numpy.array([0.12, 0.15, 0.2, 0.4, 0.55, 0.31, 0.15, 0.09]) IndoPac = {} IndoPac['lat'] = numpy.array([-30., -18., 24., 47.]) IndoPac['trans'] = numpy.array([-0.9, -1.6, 0.52, 0.]) IndoPac['err'] = numpy.array([0.3, 0.6, 0.2, 0.05,]) GandW = {} GandW['Global'] = Global GandW['Atlantic'] = Atlantic GandW['IndoPac'] = IndoPac def plotGandW(lat,trans,err): low = trans - err high = trans + err for n in range(0,len(low)): if n == 0: plt.plot([lat[n],lat[n]], [low[n],high[n]], 'c', linewidth=2.0, label='G&W') else: plt.plot([lat[n],lat[n]], [low[n],high[n]], 'c', linewidth=2.0) plt.scatter(lat,trans,marker='s',facecolor='cyan') if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label # Global Heat Transport HTplot = heatTrans(advective,diffusive) yy = y[1:,:].max(axis=-1) plotHeatTrans(yy,HTplot,title='Global Y-Direction Heat Transport [PW]') plt.plot(yobs,NCEP['Global'],'k--',linewidth=0.5,label='NCEP') plt.plot(yobs,ECMWF['Global'],'k.',linewidth=0.5,label='ECMWF') plotGandW(GandW['Global']['lat'],GandW['Global']['trans'],GandW['Global']['err']) plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) plt.legend(loc=0,fontsize=10) annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') if stream != None: plt.savefig(stream[0]) else: plt.savefig(cmdLineArgs.outdir+'/HeatTransport_global.png') # Atlantic Heat Transport plt.clf() m = 0*basin_code; m[(basin_code==2) | (basin_code==4) | (basin_code==6) | (basin_code==7) | (basin_code==8)] = 1 HTplot = heatTrans(advective, diffusive, vmask=m*numpy.roll(m,-1,axis=-2)) yy = y[1:,:].max(axis=-1) HTplot[yy<-34] = numpy.nan plotHeatTrans(yy,HTplot,title='Atlantic Y-Direction Heat Transport [PW]') plt.plot(yobs,NCEP['Atlantic'],'k--',linewidth=0.5,label='NCEP') plt.plot(yobs,ECMWF['Atlantic'],'k.',linewidth=0.5,label='ECMWF') plotGandW(GandW['Atlantic']['lat'],GandW['Atlantic']['trans'],GandW['Atlantic']['err']) plt.xlabel(r'Latitude [$\degree$N]') plt.suptitle(suptitle) plt.legend(loc=0,fontsize=10) annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') if stream != None: plt.savefig(stream[1]) else: plt.savefig(cmdLineArgs.outdir+'/HeatTransport_Atlantic.png') # Indo-Pacific Heat Transport plt.clf() m = 0*basin_code; m[(basin_code==3) | (basin_code==5)] = 1 HTplot = heatTrans(advective, diffusive, vmask=m*numpy.roll(m,-1,axis=-2)) yy = y[1:,:].max(axis=-1) HTplot[yy<-34] = numpy.nan plotHeatTrans(yy,HTplot,title='Indo-Pacific Y-Direction Heat Transport [PW]') plt.plot(yobs,NCEP['IndoPac'],'k--',linewidth=0.5,label='NCEP') plt.plot(yobs,ECMWF['IndoPac'],'k.',linewidth=0.5,label='ECMWF') plotGandW(GandW['IndoPac']['lat'],GandW['IndoPac']['trans'],GandW['IndoPac']['err']) plt.xlabel(r'Latitude [$\degree$N]') annotateObs() if diffusive is None: annotatePlot('Warning: Diffusive component of transport is missing.') plt.suptitle(suptitle) plt.legend(loc=0,fontsize=10) if stream != None: plt.savefig(stream[2]) else: plt.savefig(cmdLineArgs.outdir+'/HeatTransport_IndoPac.png')
def main(cmdLineArgs, stream=None): if not os.path.exists(cmdLineArgs.gridspec): raise ValueError( 'Specified gridspec directory/tar file does not exist.') if os.path.isdir(cmdLineArgs.gridspec): xcenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['x'][1::2, 1::2] y = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2].max( axis=-1) ycenter = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['y'][1::2, 1::2] msk = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_mask.nc').variables['mask'][:] area = msk * netCDF4.Dataset( cmdLineArgs.gridspec + '/ocean_hgrid.nc').variables['area'][:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = netCDF4.Dataset(cmdLineArgs.gridspec + '/ocean_topog.nc').variables['depth'][:] try: basin = netCDF4.Dataset(cmdLineArgs.gridspec + '/basin_codes.nc').variables['basin'][:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) elif os.path.isfile(cmdLineArgs.gridspec): xcenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'x')[1::2, 1::2] y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2].max(axis=-1) ycenter = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'y')[1::2, 1::2] msk = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_mask.nc', 'mask')[:] area = msk * m6toolbox.readNCFromTar( cmdLineArgs.gridspec, 'ocean_hgrid.nc', 'area')[:, :].reshape( [msk.shape[0], 2, msk.shape[1], 2]).sum(axis=-3).sum(axis=-1) depth = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_topog.nc', 'depth')[:] try: basin = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'basin_codes.nc', 'basin')[:] except: basin = m6toolbox.genBasinMasks(xcenter, ycenter, depth) else: raise ValueError( 'Unable to extract grid information from gridspec directory/tar file.' ) if stream != None: if len(stream) != 4: raise ValueError( 'If specifying output streams, exactly four (4) streams are needed for this analysis' ) Tobs = netCDF4.Dataset(cmdLineArgs.woa) if 'temp' in Tobs.variables: Tobs = Tobs.variables['temp'] else: Tobs = Tobs.variables['ptemp'] if len(Tobs.shape) == 3: Tobs = Tobs[:] else: Tobs = Tobs[:].mean(axis=0) Zobs = netCDF4.Dataset(cmdLineArgs.woa).variables['eta'][:] rootGroup = netCDF4.MFDataset(cmdLineArgs.annual_file) if 'temp' in rootGroup.variables: varName = 'temp' elif 'ptemp' in rootGroup.variables: varName = 'ptemp' elif 'thetao' in rootGroup.variables: varName = 'thetao' else: raise Exception( 'Could not find "temp", "ptemp" or "thetao" in file "%s"' % (cmdLineArgs.annual_file)) if len(rootGroup.variables[varName].shape) == 4: Tmod = rootGroup.variables[varName][:].mean(axis=0) else: Tmod = rootGroup.variables[varName][:] if 'e' in rootGroup.variables: Zmod = rootGroup.variables['e'][0] else: Zmod = Zobs # Using model z-ou:put def zonalAverage(T, eta, area, mask=1.): vols = (mask * area) * (eta[:-1] - eta[1:] ) # mask * area * level thicknesses return numpy.sum(vols * T, axis=-1) / numpy.sum(vols, axis=-1), ( mask * eta).min(axis=-1) ci = m6plot.pmCI(0.25, 4.5, .5) if cmdLineArgs.suptitle != '': suptitle = cmdLineArgs.suptitle + ' ' + cmdLineArgs.label else: suptitle = rootGroup.title + ' ' + cmdLineArgs.label # Global tPlot, z = zonalAverage(Tmod, Zmod, area) tObsPlot, _ = zonalAverage(Tobs, Zobs, area) if stream != None: objOut = stream[0] else: objOut = cmdLineArgs.outdir + '/T_global_xave_bias_WOA05.png' m6plot.yzplot( tPlot - tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title= r'''Global zonal-average $\theta$ bias (w.r.t. WOA'05) [$\degree$C]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare(tPlot, tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1=r'Global zonal-average $\theta$ [$\degree$C]', title2=r'''WOA'05 $\theta$ [$\degree$C]''', clim=m6plot.linCI(-2, 29, .5), colormap='dunneRainbow', extend='max', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/T_global_xave_bias_WOA05.3_panel.png') # Atlantic + Arctic newMask = 1. * msk newMask[(basin != 2) & (basin != 4)] = 0. tPlot, z = zonalAverage(Tmod, Zmod, area, mask=newMask) tObsPlot, _ = zonalAverage(Tobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[1] else: objOut = cmdLineArgs.outdir + '/T_Atlantic_xave_bias_WOA05.png' m6plot.yzplot( tPlot - tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title= r'''Atlantic zonal-average $\theta$ bias (w.r.t. WOA'05) [$\degree$C]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare( tPlot, tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1=r'Atlantic zonal-average $\theta$ [$\degree$C]', title2=r'''WOA'05 $\theta$ [$\degree$C]''', clim=m6plot.linCI(-2, 29, .5), colormap='dunneRainbow', extend='max', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/T_Atlantic_xave_bias_WOA05.3_panel.png') # Pacific newMask = 1. * msk newMask[(basin != 3)] = 0. tPlot, z = zonalAverage(Tmod, Zmod, area, mask=newMask) tObsPlot, _ = zonalAverage(Tobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[2] else: objOut = cmdLineArgs.outdir + '/T_Pacific_xave_bias_WOA05.png' m6plot.yzplot( tPlot - tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title= r'''Pacific zonal-average $\theta$ bias (w.r.t. WOA'05) [$\degree$C]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare(tPlot, tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1=r'Pacific zonal-average $\theta$ [$\degree$C]', title2=r'''WOA'05 $\theta$ [$\degree$C]''', clim=m6plot.linCI(-2, 29, .5), colormap='dunneRainbow', extend='max', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/T_Pacific_xave_bias_WOA05.3_panel.png') # Indian newMask = 1. * msk newMask[(basin != 5)] = 0. tPlot, z = zonalAverage(Tmod, Zmod, area, mask=newMask) tObsPlot, _ = zonalAverage(Tobs, Zobs, area, mask=newMask) if stream != None: objOut = stream[3] else: objOut = cmdLineArgs.outdir + '/T_Indian_xave_bias_WOA05.png' m6plot.yzplot( tPlot - tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title= r'''Indian zonal-average $\theta$ bias (w.r.t. WOA'05) [$\degree$C]''', clim=ci, colormap='dunnePM', centerlabels=True, extend='both', save=objOut) if stream is None: m6plot.yzcompare(tPlot, tObsPlot, y, z, splitscale=[0., -1000., -6500.], suptitle=suptitle, title1=r'Indian zonal-average $\theta$ [$\degree$C]', title2=r'''WOA'05 $\theta$ [$\degree$C]''', clim=m6plot.linCI(-2, 29, .5), colormap='dunneRainbow', extend='max', dlim=ci, dcolormap='dunnePM', dextend='both', centerdlabels=True, save=cmdLineArgs.outdir + '/T_Indian_xave_bias_WOA05.3_panel.png')