예제 #1
0
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)
예제 #2
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')
예제 #3
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')
예제 #4
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):
    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
예제 #6
0
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
예제 #7
0
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()
예제 #8
0
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)
예제 #9
0
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
예제 #10
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) != 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')
예제 #11
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):
        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')