Exemple #1
0
MLD_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['MLD'][:]
x_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['LONGITUDE'][:]
y_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['LATITUDE'][:]

ciMin = m6plot.linCI(0,95,5)
ciMax = m6plot.linCI(0,680,20)

# Plot of shallowest model MLD (summer)
m6plot.xyplot( MLD.min(axis=0), x, y, area=area,
      suptitle=rootGroup.title+' '+cmdLineArgs.label, title='Annual-minimum MLD$_{0.03}$ [m]',
      clim=ciMin, extend='max', colormap='dunneRainbow',
      save=cmdLineArgs.outdir+'/MLD_003_minimum.png')

# 2-panel plot of shallowest model MLD + obs (summer)
m6plot.setFigureSize(aspect=[3,3], verticalresolution=976, npanels=0)
ax1 = plt.subplot(2,1,1)
m6plot.xyplot( numpy.roll(MLD_obs.min(axis=0),300,axis=-1), x_obs-300, y_obs,
      suptitle=rootGroup.title+' '+cmdLineArgs.label, title='Hosoda et al., 2010, annual-minimum MLD$_{0.03}$ [m]',
      clim=ciMin, extend='max', colormap='dunneRainbow',
      axis=ax1)
ax2 = plt.subplot(2,1,2)
m6plot.xyplot( MLD.min(axis=0), x, y, area=area,
      suptitle=rootGroup.title+' '+cmdLineArgs.label, title='Annual-minimum MLD$_{0.03}$ [m]',
      clim=ciMin, extend='max', colormap='dunneRainbow',
      axis=ax2,
      save=cmdLineArgs.outdir+'/MLD_003_minimum.2_panel.png')

# Plot of deepest model MLD (winter)
m6plot.xyplot( MLD.max(axis=0), x, y, area=area,
      suptitle=rootGroup.title+' '+cmdLineArgs.label, title='Annual-maximum MLD$_{0.03}$ [m]',
Exemple #2
0
def main(cmdLineArgs, stream=False):
    rootGroup = netCDF4.MFDataset(cmdLineArgs.infile)
    if 'MLD_003' not in rootGroup.variables:
        raise Exception('Could not find "MLD_003" in file "%s"' %
                        (cmdLineArgs.infile))

    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]
        y = netCDF4.Dataset(cmdLineArgs.gridspec +
                            '/ocean_hgrid.nc').variables['y'][::2, ::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)
    elif os.path.isfile(cmdLineArgs.gridspec):
        x = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc',
                                    'x')[::2, ::2]
        y = m6toolbox.readNCFromTar(cmdLineArgs.gridspec, 'ocean_hgrid.nc',
                                    'y')[::2, ::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)
    else:
        raise ValueError(
            'Unable to extract grid information from gridspec directory/tar file.'
        )

    variable = rootGroup.variables['MLD_003']
    shape = variable.shape
    MLD = variable[:].reshape(shape[0] / 12, 12, shape[1],
                              shape[2]).mean(axis=0)

    if not hasattr(cmdLineArgs, 'obsdata') or cmdLineArgs.obsdata == '':
        cmdLineArgs.obsdata = '/archive/gold/datasets/obs/Hosada2010_MLD_climatology.v20140515.nc'

    MLD_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['MLD'][:]
    x_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['LONGITUDE'][:]
    y_obs = netCDF4.Dataset(cmdLineArgs.obsdata).variables['LATITUDE'][:]

    ciMin = m6plot.linCI(0, 95, 5)
    ciMax = m6plot.linCI(0, 680, 20)

    imgbufs = []

    # Plot of shallowest model MLD (summer)
    m6plot.xyplot(MLD.min(axis=0),
                  x,
                  y,
                  area=area,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Annual-minimum MLD$_{0.03}$ [m]',
                  clim=ciMin,
                  extend='max',
                  colormap='dunneRainbow',
                  save=cmdLineArgs.outdir + '/MLD_003_minimum.png')

    # 2-panel plot of shallowest model MLD + obs (summer)
    if stream is True: img = io.BytesIO()
    else: img = cmdLineArgs.outdir + '/MLD_003_minimum.2_panel.png'
    m6plot.setFigureSize(aspect=[3, 3], verticalresolution=976, npanels=0)
    ax1 = plt.subplot(2, 1, 1)
    m6plot.xyplot(numpy.roll(MLD_obs.min(axis=0), 300, axis=-1),
                  x_obs - 300,
                  y_obs,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Hosoda et al., 2010, annual-minimum MLD$_{0.03}$ [m]',
                  clim=ciMin,
                  extend='max',
                  colormap='dunneRainbow',
                  axis=ax1)
    ax2 = plt.subplot(2, 1, 2)
    m6plot.xyplot(MLD.min(axis=0),
                  x,
                  y,
                  area=area,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Annual-minimum MLD$_{0.03}$ [m]',
                  clim=ciMin,
                  extend='max',
                  colormap='dunneRainbow',
                  axis=ax2,
                  save=img)
    if stream is True: imgbufs.append(img)

    # Plot of deepest model MLD (winter)
    m6plot.xyplot(MLD.max(axis=0),
                  x,
                  y,
                  area=area,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Annual-maximum MLD$_{0.03}$ [m]',
                  clim=ciMax,
                  extend='max',
                  colormap='dunneRainbow',
                  save=cmdLineArgs.outdir + '/MLD_003_maximum.png')

    # 2-panel plot of deepest model MLD + obs (winter)
    if stream is True: img = io.BytesIO()
    else: img = cmdLineArgs.outdir + '/MLD_003_maximum.2_panel.png'
    m6plot.setFigureSize(aspect=[3, 3], verticalresolution=976, npanels=0)
    ax1 = plt.subplot(2, 1, 1)
    m6plot.xyplot(numpy.roll(MLD_obs.max(axis=0), 300, axis=-1),
                  x_obs - 300,
                  y_obs,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Hosoda et al., 2010, annual-maximum MLD$_{0.03}$ [m]',
                  clim=ciMax,
                  extend='max',
                  colormap='dunneRainbow',
                  axis=ax1)
    ax2 = plt.subplot(2, 1, 2)
    m6plot.xyplot(MLD.max(axis=0),
                  x,
                  y,
                  area=area,
                  suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
                  title='Annual-maximum MLD$_{0.03}$ [m]',
                  clim=ciMax,
                  extend='max',
                  colormap='dunneRainbow',
                  axis=ax2,
                  save=img)
    if stream is True: imgbufs.append(img)

    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) != 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')
Exemple #5
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
Exemple #6
0
ciMax = m6plot.linCI(0, 680, 20)

# Plot of shallowest model MLD (summer)
m6plot.xyplot(MLD.min(axis=0),
              x,
              y,
              area=area,
              suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
              title='Annual-minimum MLD$_{0.03}$ [m]',
              clim=ciMin,
              extend='max',
              colormap='dunneRainbow',
              save=cmdLineArgs.outdir + '/MLD_003_minimum.png')

# 2-panel plot of shallowest model MLD + obs (summer)
m6plot.setFigureSize(aspect=[3, 3], verticalresolution=976, npanels=0)
ax1 = plt.subplot(2, 1, 1)
m6plot.xyplot(numpy.roll(MLD_obs.min(axis=0), 300, axis=-1),
              x_obs - 300,
              y_obs,
              suptitle=rootGroup.title + ' ' + cmdLineArgs.label,
              title='Hosoda et al., 2010, annual-minimum MLD$_{0.03}$ [m]',
              clim=ciMin,
              extend='max',
              colormap='dunneRainbow',
              axis=ax1)
ax2 = plt.subplot(2, 1, 2)
m6plot.xyplot(MLD.min(axis=0),
              x,
              y,
              area=area,
      suptitle=rootGroup.title+' '+cmdLineArgs.label, title=r'''170$\degree$W $\theta$ bias (w.r.t. WOA'05) [$\degree$C]''',
      clim=ci, colormap='dunnePM', centerlabels=True, extend='both')
cs1 = plt.contour( y[j0:j1,i][:] + 0*z, z, tObsPlot, levels=numpy.arange(0.,45,2.), colors='k' ); plt.clabel(cs1,fmt='%.0f')
cs2 = plt.contour( y[j0:j1,i][:] + 0*z, z, tPlot, levels=numpy.arange(0.,45,2.), colors='g' ); plt.clabel(cs2,fmt='%.0f')
plt.ylim(-1200,0)
plt.savefig(cmdLineArgs.outdir+'/T_170W_bias_WOA05.png')

m6plot.yzcompare( tPlot, tObsPlot , y[j0:j1,i], zi, splitscale=[0., -1000., -6500.],
      suptitle=rootGroup.title+' '+cmdLineArgs.label,
      title1=r'170$\degree$W $\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_170W_bias_WOA05.3_panel.png')

m6plot.setFigureSize(); axis=plt.gca()
uPlot = rootGroup.variables['uo'][0,:,j0:j1,i]
plt.contourf( y[j0:j1,i][:] + 0*z, z, uPlot, levels=m6plot.linCI(-0.5,1.3,0.1), cmap='spectral', extend='both')
plt.colorbar(extend='both')
cs1 = plt.contour( y[j0:j1,i][:] + 0*z, z, uPlot, levels=m6plot.linCI(-0.5,1.3,0.1), colors='k'); plt.clabel(cs1,cs1.levels[::2],fmt='%.1f',inline_spacing=1)
plt.ylim(-600,0); plt.suptitle(rootGroup.title+' '+cmdLineArgs.label);plt.title(r'170$\degree$W u [m/s]')
plt.xlabel(r'Latitude [$\degree$N]'); plt.ylabel('Elevation [m]')
plt.savefig(cmdLineArgs.outdir+'/U_170W_bias_WOA05.png')

# 140W, 20S-20N
j0 = numpy.abs( y[:,0] + 20. ).argmin()
j1 = numpy.abs( y[:,0] - 20. ).argmin()
i = numpy.abs( numpy.mod( x[j0,:] + 140. + 360., 360. ) ).argmin()
tPlot = rootGroup.variables[varName][0,:,j0:j1,i]
tObsPlot = obsRootGroup.variables[OTvar][0,:,j0:j1,i]
zi = Zobs[:,j0:j1,i]; z = 0.5 * ( zi[:-1] + zi[1:] )
Exemple #8
0
  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]')
  #plt.xlabel(r'Latitude [$\degree$N]')

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=3)
if len(cmdLineArgs.label1): title1 = cmdLineArgs.label1
else: title1 = rootGroup.title
if len(cmdLineArgs.label2): title2 = cmdLineArgs.label2
else: title2 = rootGroupRef.title

# Global MOC
z = Zmod.min(axis=-1)
yy = y[1:,:].max(axis=-1)+0*z
psiPlotM = MOCpsi(VHmod)/1e6
psiPlotR = MOCpsi(VHref)/1e6
ci=m6plot.pmCI(0.,40.,5.)
di=m6plot.pmCI(0.,5.,0.5)
plt.subplot(311)
plotPsi(yy, z, psiPlotM, ci, title1)
findExtrema(yy, z, psiPlotM, max_lat=-30.)
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')