def printvol():
    entry = "   %9.7f"
    print  # empty line
    print "                         SPECIFIC VOLUME V [1e-3 M**3/KG]"
    print "PRESSURE                     TEMPERATURE",
    print deg + "C  IPTS-68                 SALINTY:", "%2.0f" % S[0]
    print "DECIBARS %8d %11d %11d %11d %11d" % tuple(T)
    for p in P:
        print "%6.0f" % p, 5 * entry % tuple(1e3 / dens(S[0], T, p))
    for s in S[1:]:
        print 68 * "-" + "SALINTIY:", "%2.0f" % s
        for p in P:
            print "%6.0f" % p, 5 * entry % tuple(1e3 / dens(s, T, p))
def processor(input_list):
    print('Compute ', lout, ' from ', lin)
    # Select variables
    votemper = input_list['votemper']
    vosaline = input_list['vosaline']
    DepthLayers = votemper.DepthLayers
    LatCells = votemper.LatCells
    # Replicate geometry 3D (to be updated with complete model geometry variables)
    if np.ndim(votemper.LatCells) == 1 and np.ndim(votemper.LonCells) == 1 and np.ndim(votemper.DepthLayers) == 1:
        DepthLayers = np.transpose(np.tile(votemper.DepthLayers,
                                           (votemper.LatCells.shape[0], votemper.LonCells.shape[0], 1)), (2, 0, 1))
        LatCells = np.transpose(np.tile(votemper.LatCells,
                                        (votemper.LonCells.shape[0], 1)), (1, 0))
    # Concatenate latitude, longitude and depth cells at the centers of the grid
    # (COMIC TYPE CHARACTERISTIC reserved procedure)
    depths = 1 / 4 * (DepthLayers[1:, 1:, 1:] + DepthLayers[: - 1, : - 1, 1:] +
                      DepthLayers[: - 1, 1:, : - 1] + DepthLayers[: - 1, : - 1, : - 1])
    lats = 1 / 4 * (LatCells[1:, 1:] + LatCells[: - 1, 1:] +
                    LatCells[1:, : - 1] + LatCells[: - 1, : - 1])
    # Cut time dimension
    temp = votemper.COSM[0, ...]
    salt = vosaline.COSM[0, ...]
    # Compute Pressure 3D
    pressure = sw.pres(depths, lats)
    # Compute Potential Density field 3D
    density = ma.array(np.empty(shape=votemper.COSM.shape), mask=False, fill_value=1.e20, dtype=float)
    density[0, ...] = sw.dens(salt, temp, pressure)
    # Attributes of Characteristic class are (StandardName,
    # VariableName, DepthLayers, LonCells, LatCells, TimeCells, ConcatenatioOfSpatialMaps, MaskedAs=None)
    potential_d = sp_type.Characteristic(StandardName='sea_water_density',
                                         VariableName='vodnsity', DepthLayers=votemper.DepthLayers,
                                         LonCells=votemper.LonCells, LatCells=votemper.LatCells,
                                         TimeCells=votemper.TimeCells, ConcatenatioOfSpatialMaps=density)
    return potential_d
Ejemplo n.º 3
0
    def read_raw(self, var):
        '''
        If profile is None the entire 2d array (depth,time) is returned
        If a profile object is provided, a 1d array (dimension depth) is returned
        corresponding to the pointprofile provided
        '''
        if not self.__file_already_read :
            ncIN = NC.netcdf_file(self.filename,'r')
            self._timesInFile = ncIN.variables['TIME'].data.copy()
            self._VAR         = ncIN.variables[var   ].data.copy()
            self._QC         = ncIN.variables[var + "_QC"  ].data.copy()
            if ncIN.variables.has_key('PRES'):
                self._PRES        = ncIN.variables['PRES'].data.copy()
                pres_qc           = ncIN.variables['PRES_QC'].data.copy()
            else:
                self._PRES        = ncIN.variables['DEPH'].data.copy()
                pres_qc           = ncIN.variables['DEPH_QC'].data.copy()

            self._TEMP = ncIN.variables['TEMP'].data.copy()
            self._PSAL = ncIN.variables['PSAL'].data.copy()

            temp_qc = ncIN.variables['TEMP_QC'].data.copy()
            psal_qc = ncIN.variables['PSAL_QC'].data.copy()
            ncIN.close()
            self._good_data = (temp_qc == 1 ) & (psal_qc == 1 ) & (pres_qc == 1 ) & (self._QC == 1)
            self.__file_already_read = True

            tconv = T90conv(self._TEMP)
            self._RHO = seawater.dens(self._PSAL,tconv, self._PRES)
        return self._VAR, self._PRES, self._QC, self._timesInFile
def plot_fun(i):
    print(i)
    f=plt.figure(figsize=(25/2.539,15/2.536))
    ax=plt.axes([.13,.11,.8825,.8125])       
    if coastflag:
        plotcoast(ax,filename='mid_nwatl6c_sjh_lr.nc', filepath=coastpath, color='k', fill=True)
    
    pres=sw.pres(data['h'],data['lat'])
    dens=sw.dens(data['salinity'][i,layer,:],data['temp'][i,layer,:],pres)
    triax=ax.tripcolor(data['trigrid'],dens,vmin=cmin,vmax=cmax)

    if vectorflag:
        Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],data['u'][i,layer,vidx],data['v'][i,layer,vidx],angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.001)    
        qaxk=ax.quiverkey(Q1,.9,.88,2, r'2 ms$^{-1}$')
    if uniformvectorflag:
        norm=np.sqrt(data['u'][i,layer,vidx]**2+data['v'][i,layer,vidx]**2)
        Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],np.divide(data['u'][i,layer,vidx],norm),np.divide(data['v'][i,layer,vidx],norm),angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.002,color='k')  
    
    cb=plt.colorbar(triax)
    cb.set_label(r'Density (kg m$^{3}$)',fontsize=10)    
    ax.set_xlabel(r'Longitude ($^{\circ}$)')
    ax.set_ylabel(r'Latitude ($^{\circ}$)')
    ax.axis(region['region'])
    ax.annotate('{} {}'.format(data['Time'][i][:10],data['Time'][i][11:19]),xy=(.425,.93),xycoords='axes fraction')
    for label in ax.get_xticklabels()[::2]:
        label.set_visible(False)
    f.savefig(savepath + grid + '_' + region['regionname'] +'_density_' + ("%04d" %(i)) + '.png',dpi=300)
    plt.close(f)
Ejemplo n.º 5
0
def visc(s, t, p):
    """Calculates kinematic viscosity of sea-water.  Based on Dan Kelley's fit
    to Knauss's TABLE II-8.

    Parameters
    ----------
    s : array_like
        salinity [psu (PSS-78)]
    t : array_like
        temperature [℃ (ITS-90)]  # FIXME: [degree C (IPTS-68)]
    p : array_like
        pressure [db]
    Returns
    -------
    visc : kinematic viscosity of sea-water [m^2/s]

    Notes
    -----
    From matlab airsea

    Examples
    --------
    >>> from oceans import sw_extras as swe
    >>> swe.visc(40., 40., 1000.)
    8.2001924966338036e-07

    Modifications: Original 1998/01/19 - Ayal Anis 1998
                   2010/11/25. Filipe Fernandes, python translation.
    """
    s, t, p = np.broadcast_arrays(s, t, p)

    visc = 1e-4 * (17.91 - 0.5381 * t + 0.00694 * t**2 + 0.02305 * s)
    visc /= sw.dens(s, t, p)

    return visc
Ejemplo n.º 6
0
    def plot(self):
        fig = plt.figure(figsize=self.figuresize(), dpi=self.dpi)

        plt.title(gettext("T/S Diagram for %s (%s)") % (
            ", ".join(self.names),
            self.date_formatter(self.timestamp)))

        smin = np.amin(self.salinity) - (np.amin(self.salinity) * 0.01)
        smax = np.amax(self.salinity) + (np.amax(self.salinity) * 0.01)
        tmin = np.amin(self.temperature) - (
            np.abs(np.amax(self.temperature) * 0.1))
        tmax = np.amax(self.temperature) + (
            np.abs(np.amax(self.temperature) * 0.1))

        xdim = int(round((smax - smin) / 0.1 + 1, 0))
        ydim = int(round((tmax - tmin) + 1, 0))

        dens = np.zeros((ydim, xdim))
        ti = np.linspace(0, ydim - 1, ydim) + tmin
        si = np.linspace(0, xdim - 1, xdim) * 0.1 + smin

        for j in range(0, int(ydim)):
            for i in range(0, int(xdim)):
                dens[j, i] = seawater.dens(si[i], ti[j], 0)

        dens = dens - 1000

        CS = plt.contour(si, ti, dens, linestyles='dashed', colors='k')
        plt.clabel(CS, fontsize=16, inline=1, fmt=r"$\sigma_t = %1.1f$")

        for idx, _ in enumerate(self.temperature):
            plt.plot(self.salinity[idx], self.temperature[idx], '-')

        plt.xlabel(gettext("Salinity (PSU)"))
        plt.ylabel(gettext("Temperature (Celsius)"))

        self.plot_legend(fig, self.names)
        if len(self.points) == 1:
            labels = []
            for idx, d in enumerate(self.temperature_depths[0]):
                if np.ma.is_masked(self.temperature[0][idx]):
                    break
                digits = max(np.ceil(np.log10(d)), 3)
                d = np.round(d, -int(digits - 1))
                if d not in labels:
                    labels.append(d)
                    for idx2, _ in enumerate(self.temperature):
                        plt.annotate(
                            '{:.0f}m'.format(d),
                            xy=(self.salinity[idx2][
                                idx], self.temperature[idx2][idx]),
                            xytext=(15, -15),
                            ha='left',
                            textcoords='offset points',
                            arrowprops=dict(arrowstyle='->')  # , shrinkA=0)
                        )

        return super(TemperatureSalinityPlotter, self).plot(fig)
Ejemplo n.º 7
0
def select_field(data, field, i, layer='da'):
    """
    Helper function to select the correct field and name for the field
    """
    
    fn = {'temp' : r'Temperature ($^{\circ}$)',
          'salinity' : r'Salinity (PSU)',
          'speed' : r'Speed (m/s)',
          'u' : r'U-Velocity (m/s)',
          'v' : r'V-Velocity (m/s)',
          'vorticity' : r'Vorticity',
          'density' : r'Density (kg m$^{3}$)',
          'zeta' : 'Elevation (m)'}    
    
    
    if 'speed' in field:
        if layer=='da':
            fieldout = np.sqrt(data['ua'][i,:]**2 + data['va'][i,:]**2)
        else:
            fieldout = np.sqrt(data['u'][i,layer,:]**2 + data['v'][i,layer,:]**2)
            
    elif 'vorticity' in field:
        if layer=='da':
            dudy = data['a2u'][0,:]*data['ua'][i,:]+data['a2u'][1,:]*data['ua'][i,data['nbe'][:,0]] +\
                   data['a2u'][2,:]*data['ua'][i,data['nbe'][:,1]]+data['a2u'][3,:]*data['ua'][i,data['nbe'][:,2]]
            dvdx = data['a1u'][0,:]*data['va'][i,:]+data['a1u'][1,:]*data['va'][i,data['nbe'][:,0]] +\
                   data['a1u'][2,:]*data['va'][i,data['nbe'][:,1]]+data['a1u'][3,:]*data['va'][i,data['nbe'][:,2]]
        else:
            dudy = data['a2u'][0,:]*data['u'][i,layer,:]+data['a2u'][1,:]*data['u'][i,layer,data['nbe'][:,0]] +\
                   data['a2u'][2,:]*data['u'][i,layer,data['nbe'][:,1]]+data['a2u'][3,:]*data['u'][i,layer,data['nbe'][:,2]]
            dvdx = data['a1u'][0,:]*data['v'][i,layer,:]+data['a1u'][1,:]*data['v'][i,layer,data['nbe'][:,0]] +\
                   data['a1u'][2,:]*data['v'][i,layer,data['nbe'][:,1]]+data['a1u'][3,:]*data['v'][i,layer,data['nbe'][:,2]]
        fieldout = dvdx - dudy   
        
    elif 'density' in field:
        if layer==None:
            print("Can't get density for layer None. Using layer=0.")
            layer = 0
        pres = sw.pres(data['h']+data['zeta'][i,:],data['lat'])
        fieldout = sw.dens(data['salinity'][i,layer,:],data['temp'][i,layer,:],pres)
        
    else:
        if layer=='da':
            fieldout = data[field][i,:]
        else:
            fieldout = data[field][i,layer,:]
           
            
    
    try:     
        fieldname = fn[field]
    except KeyError:
        fieldname = field
    
    return fieldout, fieldname
def values(S, T, P):
    """Compute a row in the table"""
    return (
        P / 10,
        S,
        T,
        dens(S, T, P) - 1000,
        drhods(S, T, P),
        10 ** 7 * alpha(S, T, P),
        heatcap(S, T, P),
        1000 * temppot0(S, T, P),
        soundvel(S, T, P),
    )
Ejemplo n.º 9
0
    def plot_ts_diagram(self, ax, sal, temp, xlabel='Salinity', ylabel='Temperature', title='',
                        axis_font={}, title_font={}, tick_font={}, **kwargs):

        if not axis_font:
            axis_font = axis_font_default
        if not title_font:
            title_font = title_font_default

        sal = np.ma.array(sal, mask=np.isnan(sal))
        temp = np.ma.array(temp, mask=np.isnan(temp))
        if len(sal) != len(temp):
            raise Exception('Sal and Temp arrays are not the same size!')

        # Figure out boudaries (mins and maxs)
        smin = sal.min() - (0.01 * sal.min())
        smax = sal.max() + (0.01 * sal.max())
        tmin = temp.min() - (0.1 * temp.max())
        tmax = temp.max() + (0.1 * temp.max())

        # Calculate how many gridcells we need in the x and y dimensions
        xdim = round((smax-smin)/0.1+1, 0)
        ydim = round((tmax-tmin)+1, 0)

        # Create empty grid of zeros
        dens = np.zeros((ydim, xdim))

        # Create temp and sal vectors of appropiate dimensions
        ti = np.linspace(1, ydim-1, ydim)+tmin
        si = np.linspace(1, xdim-1, xdim)*0.1+smin

        # Loop to fill in grid with densities
        for j in range(0, int(ydim)):
            for i in range(0, int(xdim)):
                dens[j, i] = sw.dens(si[i], ti[j], 0)

        # Substract 1000 to convert to sigma-t
        dens = dens - 1000

        # Plot data
        cs = plt.contour(si, ti, dens, linestyles='dashed', colors='k')

        plt.clabel(cs, fontsize=12, inline=1, fmt='%1.0f')  # Label every second level
        ppl.scatter(ax, sal, temp, **kwargs)

        ax.set_xlabel(xlabel.replace("_", " "), labelpad=10, **axis_font)
        ax.set_ylabel(ylabel.replace("_", " "), labelpad=10, **axis_font)
        ax.set_title(title.replace("_", " "), **title_font)
        ax.set_aspect(1./ax.get_data_ratio())  # make axes square
        if tick_font:
            ax.tick_params(**tick_font)
        plt.tight_layout()
Ejemplo n.º 10
0
def sigma_t(s, t, p):
    r""":math:`\\sigma_{t}` is the remainder of subtracting 1000 kg m :sup:`-3`
    from the density of a sea water sample at atmospheric pressure.

    Parameters
    ----------
    s(p) : array_like
           salinity [psu (PSS-78)]
    t(p) : array_like
           temperature [:math:`^\\circ` C (ITS-90)]
    p : array_like
        pressure [db]

    Returns
    -------
    sgmt : array_like
           density  [kg m :sup:`3`]

    Notes
    -----
    Density of Sea Water using UNESCO 1983 (EOS 80) polynomial.

    Examples
    --------
    Data from Unesco Tech. Paper in Marine Sci. No. 44, p22

    >>> import seawater.csiro as sw
    >>> import seawater.extras as swe
    >>> s = [0, 0, 0, 0, 35, 35, 35, 35]
    >>> t = sw.T90conv([0, 0, 30, 30, 0, 0, 30, 30])
    >>> p = [0, 10000, 0, 10000, 0, 10000, 0, 10000]
    >>> swe.sigma_t(s, t, p)
    array([ -0.157406  ,  45.33710972,  -4.34886626,  36.03148891,
            28.10633141,  70.95838408,  21.72863949,  60.55058771])

    References
    ----------
    .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for
    computation of fundamental properties of seawater. UNESCO Tech. Pap. in
    Mar. Sci., No. 44, 53 pp.  Eqn.(31) p.39.
    http://www.scor-int.org/Publications.htm

    .. [2] Millero, F.J., Chen, C.T., Bradshaw, A., and Schleicher, K. A new
    high pressure equation of state for seawater. Deap-Sea Research., 1980,
    Vol27A, pp255-264. doi:10.1016/0198-0149(80)90016-3

    Modifications: Filipe Fernandes, 2010
                   10-01-26. Filipe Fernandes, first version.
    """
    s, t, p = map(np.asanyarray, (s, t, p))
    return sw.dens(s, t, p) - 1000.0
Ejemplo n.º 11
0
def tsdiagramjmk(salt,temp,cls=[]):
    import numpy as np
    import seawater
    import matplotlib.pyplot as plt
     
     
    # Figure out boudaries (mins and maxs)
    smin = salt.min() - (0.01 * salt.min())
    smax = salt.max() + (0.01 * salt.max())
    tmin = temp.min() - (0.1 * temp.max())
    tmax = temp.max() + (0.1 * temp.max())
 
    # Calculate how many gridcells we need in the x and y dimensions
    xdim = round((smax-smin)/0.1+1,0)
    ydim = round((tmax-tmin)+1,0)

     
    # Create empty grid of zeros
    dens = np.zeros((ydim,xdim))
     
    # Create temp and salt vectors of appropiate dimensions
    ti = np.linspace(1,ydim-1,ydim)+tmin
    si = np.linspace(1,xdim-1,xdim)*0.1+smin
     
    # Loop to fill in grid with densities
    for j in range(0,int(ydim)):
        for i in range(0, int(xdim)):
            dens[j,i]=seawater.dens(si[i],ti[j],0)
     
    # Substract 1000 to convert to sigma-t
    dens = dens - 1000
 
    # Plot data ***********************************************
    if not(cls==[]):
        CS = plt.contour(si,ti,dens, cls,linestyles='dashed', colors='k')
    else:
        CS = plt.contour(si,ti,dens,linestyles='dashed', colors='k')
        
    plt.clabel(CS, fontsize=9, inline=1, fmt='%1.2f') # Label every second level
    ax1=gca()
    #    ax1.plot(salt,temp,'or',markersize=4)
     
    ax1.set_xlabel('S [psu]')
    ax1.set_ylabel('T [C]')
Ejemplo n.º 12
0
def visc(s, t, p):
    r"""Calculates kinematic viscosity of sea-water.

    Parameters
    ----------
    s(p) : array_like
           salinity [psu (PSS-78)]
    t(p) : array_like
           temperature [:math:`^\\circ` C (ITS-90)]
    p : array_like
        pressure [db]

    Returns
    -------
    visw : array_like
           [m :sup: `2` s :sup: `-1`]

    See Also
    --------
    visc_air from airsea toolbox

    Notes
    -----
    From matlab airsea

    Examples
    --------
    >>> import seawater.extras as swe
    >>> swe.visc(40, 40, 1000)
    8.2001924966338036e-07

    References
    ----------
    .. [1] Dan Kelley's fit to Knauss's TABLE II-8.

    Modifications: Original 1998/01/19 - Ayal Anis 1998
                   2010/11/25. Filipe Fernandes, python translation.
    """
    s, t, p = map(np.asanyarray, (s, t, p))
    return (1e-4 * (17.91 - 0.5381 * t + 0.00694 * t ** 2 + 0.02305 * s) /
            sw.dens(s, t, p))
Ejemplo n.º 13
0
def makeTSPlot(float_data, units, cmax=500, close_all=False):

	if close_all:
		plt.close('all')

	# ymin = np.floor(min(float_data['Temperature']))
	# ymax = np.ceil(max(float_data['Temperature']))
	ymin = -2
	ymax = 15

	xmin = 33.5
	xmax = 35.5

	# pmin = np.floor(min(float_data['Density']))
	# pmax = np.ceil(max(float_data['Density']))
	pmin = 25
	pmax = 28.5

	#plot sample data
	plt.figure()
	pres = sw.pres(float_data['Depth'], float_data['Lat'])
	ptemp = sw.ptmp(float_data['Salinity'], float_data['Temperature'], pres, 0)
	plt.scatter(float_data['Salinity'], ptemp, c=float_data['Depth'], lw=0, cmap=plt.cm.rainbow, vmin=0, vmax=cmax)
	plt.ylabel('Pot. Temperature (%s)' %units['Temperature'])
	plt.xlabel('Salinity (PSS)')
	plt.title("T vs. S for SOCCOM float '%s'" %float_data['Cruise'][0])
	plt.clim(cmax, 0)
	plt.xlim(xmin, xmax)
	plt.ylim(ymin, ymax)
	cbar = plt.colorbar(extend='max')
	cbar.ax.set_ylabel('Depth (%s)' %units['Depth'])

	#add density lines	
	temps = np.arange(ymin, ymax,0.1)
	sals = np.arange(xmin, xmax, 0.1)
	sal_grid, temp_grid = np.meshgrid(np.ma.masked_invalid(sals), np.ma.masked_invalid(temps))
	pdens_grid= sw.dens(sal_grid, temp_grid, 0)-1000
	plvls = np.arange(pmin, pmax, 0.2)
	cs = plt.contour(sal_grid, temp_grid, pdens_grid, plvls, colors='0.5',linewidth=0.5)
	plt.clabel(cs, inline=1, fontsize=10,fmt='%1.1f',inline_spacing=10) 
	plt.show()
Ejemplo n.º 14
0
  #------------------------------------------------------------------------
  # Calculate depths of each rho layer
  #------------------------------------------------------------------------
  z  = np.zeros(shape=(N  ,M,L))
  zw = np.zeros(shape=(N+1,M,L))
  z  = depths_rho(h,zeta,s_r,Cs_r,hc)
  #z  = z[::-1,:,:]
  zw = depths_w(  h,zeta,s_w,Cs_w,hc)
  #z  = z[::-1,:,:]
  Hz = abs(zw[1:N+1,:,:]-zw[0:N,:,:])

  #------------------------------------------------------------------------
  # Calculate various seawater properties
  #------------------------------------------------------------------------
  pres=sw.pres(z*-1,lat)
  dens=sw.dens(salt,temp,pres)-1000.

  #------------------------------------------------------------------------
  # Find layer with max dT/d(sigma)
  #------------------------------------------------------------------------
  dT=np.zeros(shape=(N-1))
  for i in range(0,M):
    for j in range(0,L):
      
      # Cell is over the water
      if mask[i,j]>0:
        drdZ = abs(dens[1:N-1,i,j]-dens[0:N-2,i,j])/abs(z[1:N-1,i,j]-z[0:N-2,i,j])
        drdZ_ind=np.argmax(drdZ)
        
        #-----------------------------------------------------------------
        # Average above and below the pycnocline
Ejemplo n.º 15
0
		ts_filtered.data = high_pass_filter(ts_filtered.data,upper_limit_years)
		ts_filtered.data = low_pass_filter(ts_filtered.data,lower_limit_years)	
		#density
		file = glob.glob(directory+model+'_*'+'tos'+'*r1i1p1*.nc')
		cube1 = iris.load_cube(file)
		file = glob.glob(directory+model+'_*'+'sos'+'*r1i1p1*.nc')
		cube2 = iris.load_cube(file)
		coord = cube1.coord('time')
		dt = coord.units.num2date(coord.points)
		years1 = np.array([coord.units.num2date(value).year for value in coord.points])
		locs = np.in1d(years, years1)
		cube1 = cube1[locs]
		cube2 = cube2[locs]
		ts_filtered = ts_filtered[locs]
		cube = cube1.copy()
		cube.data = seawater.dens(cube2.data,cube1.data-273.15)
		cube.data = high_pass_filter(cube.data,upper_limit_years)
		cube.data = low_pass_filter(cube.data,lower_limit_years)
		ts_filtered_2D = cube.copy()
		ts_filtered_2D.data = np.swapaxes(np.swapaxes(np.tile(ts_filtered.data,[180,360,1]),1,2),0,1)
		data[model] = {}
		data[model]['density'] = {}
		data[model]['density'] = istats.pearsonr(ts_filtered_2D,cube,corr_coords=['time'])
		cube1.data = high_pass_filter(cube1.data,upper_limit_years)
		cube1.data = low_pass_filter(cube1.data,lower_limit_years)
		data[model]['tos'] = {}
		data[model]['tos'] = istats.pearsonr(ts_filtered_2D,cube1,corr_coords=['time'])



plt.close('all')
Ejemplo n.º 16
0
    def getFloatMatchups(self,Profilelist,nav_lev,outdir="./"):
        '''
        Dumps an image png file and a NetCDF file for each profile
        The filenames refers to time and float wmo.
        Both files contain matchups about chl,O2o,N3n,temperature, salinity


        Matchups are provided at fixed depths: every 5 meters from 0 to 400m,
        because in biofloats physical and biological variables do not have the same sampling.

        Arguments:
        * Profilelist * is provided by FloatSelector
        * nav_lev * is the model level
        * outdir * optional is the output location


        The matchups are couples of values (Model,Ref)
        obtained to a given selection in space and time,
        to be used in statistics.


        At the moment it can happen that a short model profile is extrapolated over a long float profile.
        Then, a replication of matchups could occur.

        Returns nothing
        '''
        from validation.online.profileplotter import figure_generator, ncwriter#, add_metadata
        zlevels_out=np.arange(0,401,5)
        MODELVARLIST=['P_l','O2o','N3n','votemper','vosaline']
        plotvarname = [r'Chl $[mg/m^3]$',r'Oxy $[mmol/m^3]$',r'Nitr $[mmol/m^3]$',r'Temp $[^\circ C]$','Sal']
        read_adjusted = [True,False,True,False,False]
        mapgraph = [3,4,5,1,2]

        for p in Profilelist:
            Model_time = self.modeltime(p)

            if Model_time is None :
                print p.time.strftime("%Y%m%d-%H:%M:%S is a time not included by profiler")
                continue
            else:
                if not self.TI.contains(Model_time) :
                    print Model_time.strftime("%Y%m%d-%H:%M:%S is a time not included by profiler")
                    continue
            VARLIST = p._my_float.available_params.strip().rsplit(" ")
            VARLIST.remove('PRES')
            Modelfile = self.profilingDir + "PROFILES/" + Model_time.strftime("ave.%Y%m%d-%H:%M:%S.profiles.nc")


            #density calculator on zlevels_out
            model_varname = 'votemper'
            ref_varname = self.reference_var(p, model_varname)
            ModelProfile = self.readModelProfile(Modelfile, model_varname, p.ID())
            seaPoints = ~np.isnan(ModelProfile)
            if np.isnan(ModelProfile).all() : # potrebbe essere fuori dalla tmask
                print "No model data for (lon,lat) = (%g, %g) " %(p.lon, p.lat)
                continue
            Pres, temp, Qc = p.read(ref_varname,read_adjusted[3])
            Temp_out = np.interp(zlevels_out,Pres,temp).astype(np.float32)

            model_varname = 'vosaline'
            ref_varname = self.reference_var(p, model_varname)
            Pres, sal, Qc = p.read(ref_varname,read_adjusted[4])
            sal_out = np.interp(zlevels_out,sal,temp).astype(np.float32)
            density = sw.dens(sal_out,Temp_out,zlevels_out)
            #end density calculator

            correction = [1,1000./density,1,1,1]

            filename = outdir+"/"+Model_time.strftime('%Y%m%d') +"_"+p.name()
            ncOUT, model_handlers, float_handlers =ncwriter(filename+".nc", zlevels_out,p)

            fig, axs = figure_generator(p)
            #pl.rc('text', usetex=True)

            for i,model_varname in enumerate(MODELVARLIST):
                ref_varname = self.reference_var(p, model_varname)
                if ref_varname not in VARLIST: continue
                ModelProfile = self.readModelProfile(Modelfile, model_varname, p.ID())
                seaPoints = ~np.isnan(ModelProfile)
                Pres, Profile, Qc = p.read(ref_varname,read_adjusted[i])
                if len(Pres) == 0:
                    Pres, Profile, Qc = p.read(ref_varname,not read_adjusted[i])

                print model_varname, len(Profile)
                if len(Profile) < 2 : continue
                model_on_common_grid=np.interp(zlevels_out,nav_lev[seaPoints],ModelProfile[seaPoints]).astype(np.float32)
                float_on_common_grid=np.interp(zlevels_out,Pres,Profile).astype(np.float32)
                #float_on_common_grid = float_on_common_grid*correction[i]

                Matchup = matchup.matchup.ProfileMatchup(model_on_common_grid, float_on_common_grid, zlevels_out, Qc, p)

                model_handlers[i][:] = model_on_common_grid[:] #write on NC file
                float_handlers[i][:] = float_on_common_grid[:]


                ax=axs[mapgraph[i]] #get subplot
                fig, ax = Matchup.plot_subplot(plotvarname[i], fig, ax)

            ncOUT.close()
            pngfile = filename + ".png"
            fig.savefig(pngfile)
            pl.close(fig)
            #add_metadata(pngfile, p)

        return
Ejemplo n.º 17
0
      
      # Cell is over the water
      if mask[i,j]>0:
        #-----------------------------------------------------------------
        # Load in temp,salt, age, residence time
        #----------------------------------------------------------------
        temp  =input_data.variables['temp'       ][tdim,:,i,j]
        salt  =input_data.variables['salt'       ][tdim,:,i,j]
        Grtime=Gtime_data.variables['age_02'     ][tdim,:,i,j]
        Artime=Atime_data.variables['age_02'     ][tdim,:,i,j]
        rtime =Grtime+Artime

        #-----------------------------------------------------------------
        # Calculate depth of the pycnocline
        #----------------------------------------------------------------
        dens=sw.dens(salt,temp,np.squeeze(pres[:,i,j]))-1000.
        drdZ = abs(dens[1:N]-dens[0:N-1])/abs(np.squeeze(z[1:N,i,j]-z[0:N-1,i,j]))
        drdZ_ind=np.argmax(drdZ)
        
        #-----------------------------------------------------------------
        # Average residence time above the pycnocline
        #----------------------------------------------------------------
        # Cell is within shelf scope
        if Gscope[i,j]>0:
          rtime02[tdim,i,j]=sum(np.squeeze(   Hz[drdZ_ind::,i,j])*\
                                           rtime[drdZ_ind::])/\
                                np.squeeze(abs(z[drdZ_ind,i,j]))
        else:
          rtime02[tdim,i,j]=np.nan
    
      # Cell is over land
Ejemplo n.º 18
0
def makeHeatContent(salt,temp,destMask,thetao,pressure):
    """
    The makeHeatContent() function takes 3D (not temporal) arguments and creates
    heat content which is then mapped to a destination grid and written to a
    specified variable

    Author: Paul J. Durack : [email protected] : @durack1.
    Created on Tue Nov 24 15:34:30 2015.

    Inputs:
    ------
    - salt(lev,lat,lon) - 3D array.
    - temp(lev,lat,lon) - 3D array either in-situ or potential temperature.
    - destGridArray(str) - 2D array with valid grid and mask.
    - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided.
    - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m).

    Usage:
    ------
        >>> from oceanLib import makeHeatContent
        >>> makeHeatContent(salt,temp,destGridArray,thetao=True,pressure=False)

    Notes:
    -----
    - PJD 24 Nov 2015 - Migrated into new oceanLib from heatContentLib
    - TODO: Better deal with insitu vs thetao variables
    - TODO:
    """

    # Remap variables to short names
    #print salt.getAxisIds()
    s       = salt(squeeze=1) ; # Trim off singleton time dimension
    #print s.getAxisIds()
    t       = temp(squeeze=1)
    mask    = destMask
    #print mask.getAxisIds()
    del(salt,temp,destMask) ; gc.collect()
    depthInd = 0 ; # Set depth coordinate index

    #print 's:    ',s.min(),s.max()
    #print 't:    ',t.min(),t.max()

    # Fix out of bounds values
    t = mv.where(t<-2.6,-2.6,t) ; # Fix for NaN values

    # Calculate pressure - inputs depth & lat
    # Create z-coordinate from salinity input
    if not pressure:
        zCoord                         = s.getAxis(depthInd) ; # Assume time,depth,latitude,longitude grid
        yCoord                         = s.getAxis(depthInd+1)
        yCoord                         = tile(yCoord,(s.shape[depthInd+2],1)).transpose()
        depthLevels                    = tile(zCoord.getValue(),(s.shape[depthInd+2],s.shape[depthInd+1],1)).transpose()
        pressureLevels                 = sw.pres(np.array(depthLevels),np.array(yCoord))
        del(zCoord,yCoord,depthLevels) ; gc.collect()
    else:
        pressureLevels                 = s.getAxis(depthInd)
        #print pressureLevels.getValue()
        pressureLevels                 = transpose(tile(pressureLevels,(s.shape[depthInd+2],s.shape[depthInd+1],1)))
    pressureLevels                 = cdm.createVariable(pressureLevels,id='pressureLevels')
    pressureLevels.setAxis(0,s.getAxis(depthInd))
    pressureLevels.setAxis(1,s.getAxis(depthInd+1))
    pressureLevels.setAxis(2,s.getAxis(depthInd+2))
    pressureLevels.units_long      = 'decibar (pressure)'
    pressureLevels.positive        = 'down'
    pressureLevels.long_name       = 'sea_water_pressure'
    pressureLevels.standard_name   = 'sea_water_pressure'
    pressureLevels.units           = 'decibar'
    pressureLevels.axis            = 'Z'

    #print 'pres: ',pressureLevels.min(),pressureLevels.max()
    #print pressureLevels.shape
    #print s.shape
    #print t.shape
    #print mask.shape

    # Calculate temp,rho,cp - inputs temp,salt,pressure
    if thetao:
        # Process potential temperature to in-situ
        temp        = sw.temp(np.array(s),np.array(t),np.array(pressureLevels)); # units degrees C
    rho             = sw.dens(np.array(s),np.array(temp),np.array(pressureLevels)) ; # units kg m-3
    cp              = sw.cp(np.array(s),np.array(temp),np.array(pressureLevels)) ; # units J kg-1 C-1

    # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset
    temp            = scrubNaNAndMask(temp,s)
    rho             = scrubNaNAndMask(rho,s)
    cp              = scrubNaNAndMask(cp,s)

    #print 'temp: ',temp.min(),temp.max()
    #print 'rho:  ',rho.min(),rho.max()
    #print 'cp:   ',cp.min(),cp.max()

    # Calculate heatContent - inputs temp,rho,cp
    heatContent     = np.array(temp)*np.array(rho)*np.array(cp) ; # units J

    # Correct instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset
    heatContent     = scrubNaNAndMask(heatContent,s)
    #print 'hc:   ',heatContent.min(),heatContent.max()

    # Interpolate to standard levels - inputs heatContent,levels
    newDepth        = np.array([5,10,20,30,40,50,75,100,125,150,200,300,500,700,1000,1500,1800,2000]).astype('f');
    newDepth_bounds = np.array([[0,5],[5,10],[10,20],[20,30],[30,40],[40,50],[50,75],[75,100],[100,125],[125,150],
                                [150,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f')
    # Interpolate to standard levels
    #print heatContent.shape
    #print heatContent.getAxisIds()
    #print pressureLevels.shape
    #print pressureLevels.getAxisIds()

    # Reset variable axes
    heatContent.setAxis(0,s.getAxis(0))
    #heatContent.setAxis(1,s.getAxis(1))
    #heatContent.setAxis(2,s.getAxis(2))

    pdb.set_trace()

    heatContent.setGrid(s.getGrid())


    #print heatContent.shape
    #print heatContent.getAxisIds()
    #print pressureLevels.shape
    #print pressureLevels.getAxisIds()

    heatContent_depthInterp     = cdu.linearInterpolation(heatContent,pressureLevels,levels=newDepth)
    # Fix bounds
    newDepth = heatContent_depthInterp.getAxis(0)
    newDepth.setBounds(newDepth_bounds)
    del(newDepth_bounds)
    newDepth.id             = 'depth2'
    newDepth.units_long     = 'decibar (pressure)'
    newDepth.positive       = 'down'
    newDepth.long_name      = 'sea_water_pressure'
    newDepth.standard_name  = 'sea_water_pressure'
    newDepth.units          = 'decibar'
    newDepth.axis           = 'Z'

    #print 'hc_interp:',heatContent_depthInterp.min(),heatContent_depthInterp.max()

    # Integrate to 700 dbar - inputs heatContent

    heatContent_depthInteg = cdu.averager(heatContent_depthInterp[0:14,...],axis=0,weights='weighted',action='sum')(squeeze=1) # Calculate depth-weighted-integrated thetao
    # Assign all axis info

    #print heatContent_depthInteg.shape
    pdb.set_trace()
    # Interpolate in x,y - inputs heatContent
    #tmp1 = heatContent_depthInteg.regrid(mask.getGrid(),regridTool='esmf',regridMethod='linear') ; # Use defaults - ,coordSys='deg',diag = {},periodicity=1)
    tmp1 = heatContent_depthInteg.regrid(mask,regridTool='esmf',regridMethod='linear') ; # Use defaults - ,coordSys='deg',diag = {},periodicity=1)
    #print tmp1.shape

    tmp1 = mv.where(tmp1<0,0,tmp1) ; # Fix for negative values

    # Infill - inputs heatContent
    # Create inputs for interpolation
    points = np.zeros([(mask.shape[0]*mask.shape[1]),2]) ; # Create 25380 vectors of lon/lat
    latcounter = 0 ; loncounter = 0
    for count,data in enumerate(points):
        if not np.mod(count,180) and not count == 0:
            latcounter = latcounter + 1
            loncounter = 0
        points[count,0] = mask.getLatitude().getValue()[latcounter]
        points[count,1] = mask.getLongitude().getValue()[loncounter]
        loncounter = loncounter + 1
    del(count,data,latcounter,loncounter); gc.collect()
    valid = np.logical_not(tmp1.mask) ; # Get inverted-logic boolean mask from variable
    if valid.size == 1:
        print '** No valid mask found, skipping **'
        return
    valid = valid.flatten() ; # Flatten 2D to 1D

    #maskFilled  = mask(tmp,points,valid)
    interpolant = interpolate.LinearNDInterpolator(points[valid,:],np.array(tmp1.flatten())[valid]) ; # Create interpolant
    maskFill    = interpolant(points[:,0].squeeze(),points[:,1].squeeze()) ; # Use interpolant to create filled matrix
    maskFill    = np.reshape(maskFill,mask.shape) ; # Resize to original dimensions

    # Fix issues with interpolant
    tmp2 = mv.where(np.isnan(maskFill),1e+20,maskFill) ; # Fix for NaN values
    tmp2 = mv.where(tmp2>tmp1.max(),0,tmp2) ; # Fix for max values
    tmp2 = mv.where(tmp2<tmp1.min(),0,tmp2) ; # Fix for min values
    tmp = mv.masked_where(mask.mask,tmp2)
    #print tmp.shape

    # Redress variable
    heatContent                 = cdm.createVariable([tmp],id='heatContent')
    depthInt                    = cdm.createAxis([350],id='depth')
    depthInt.setBounds(np.array([0,700]))
    depthInt.units_long     = 'decibar (pressure)'
    depthInt.positive       = 'down'
    depthInt.long_name      = 'sea_water_pressure'
    depthInt.standard_name  = 'sea_water_pressure'
    depthInt.units          = 'decibar'
    depthInt.axis           = 'Z'
    heatContent.setAxis(0,depthInt)
    heatContent.setAxis(1,mask.getAxis(0))
    heatContent.setAxis(2,mask.getAxis(1))
    heatContent.units_long      = 'Joules'
    heatContent.long_name       = 'sea_water_heat_content'
    heatContent.standard_name   = 'sea_water_heat_content'
    heatContent.units           = 'J'

    return heatContent ; #,tmp1 ; # 0-700 dbar standard masked variable
Ejemplo n.º 19
0
def makeSteric(salinity,salinityChg,temp,tempChg,outFileName,thetao,pressure):
    """
    The makeSteric() function takes 3D (not temporal) arguments and creates
    heat content and steric fields which are written to a specified outfile

    Author: Paul J. Durack : [email protected] : @durack1.
    Created on Thu Jul 18 13:03:37 2013.

    Inputs:
    ------
    - salinity(lev,lat,lon) - 3D array for the climatological period.
    - salinityChg(lev,lat,lon) - 3D array for the temporal change period.
    - temp(lev,lat,lon) - 3D array for the climatological period either in-situ or potential temperature.
    - tempChg(lev,lat,lon) - 3D array for the temporal change period as with temp, either in-situ or potential temperature.
    - outFileName(str) - output filename with full path specified.
    - thetao(bool) - boolean value specifying either in-situ or potential temperature arrays provided.
    - pressure(bool) - boolean value specifying whether lev-coordinate is pressure (dbar) or depth (m).

    Usage:
    ------
        >>> from makeStericLib import makeSteric
        >>> makeSteric(salinity,salinityChg,thetao,thetaoChg,'outfile.nc',True,False)

    Notes:
    -----
    - PJD 18 Jul 2013 - Validated Ishii v6.13 data against WOA94 - checks out ok. Units: dyn decimeter compared to http://www.nodc.noaa.gov/OC5/WOA94/dyn.html uses cm (not decimeter; x 10)
    - PJD 18 Jul 2013 - Added attribute scrub to incoming variables (so,so_chg,temp,temp_chg) to maintain output consistency
    - PJD 22 Jul 2013 - Added name attributes to so and temp variables, added units to so_chg
    - PJD 22 Jul 2013 - removed duplicated code by converting repetition to function scrubNaNAndMask
    - PJD 23 Jul 2013 - Further cleaned up so,so_chg,temp,temp_chg outputs specifying id/name attributes
    - PJD  5 Aug 2013 - Updated python-seawater library to version 3.3.1 from github repo, git clone http://github.com/ocefpaf/python-seawater, python setup.py install --user
    - PJD  7 Aug 2013 - FIXED: thetao rather than in-situ temperature propagating throughout calculations
    - PJD  7 Aug 2013 - Replaced looping with 3D gpan
    - PJD  7 Aug 2013 - Further code duplication cleanup
    - PJD  8 Aug 2013 - FIXED: scrubNanAndMask function type/mask/grid issue - encase sw arguments in np.array() (attempt to strip cdms fluff)
    - PJD  8 Aug 2013 - FIXED: removed depth variable unit edits - not all inputs are depth (m)
    - PJD 15 Aug 2013 - Increased interpolated field resolution [200,300,500,700,1000,1500,1800,2000] - [5,10,20,30,40,50,75,100,125,150,200, ...]
    - PJD 18 Aug 2013 - AR5 hard coded rho=1020,cp=4187 == 4.3e6 vs Ishii 1970 rho.mean=1024,cp.mean=3922 == 4.1e6 ~5% too high
    - PJD 13 Jan 2014 - Corrected steric_height_anom and steric_height_thermo_anom to true anomaly fields, needed to remove climatology
    - PJD  3 May 2014 - Turned off thetao conversion, although convert to numpy array rather than cdms2 transient variable
    - PJD 13 Oct 2014 - Added seawater_library_version as a global attribute
    - PJD 13 Oct 2014 - FIXED: bug with calculation of rho_halo variable was calculating gpan
    - PJD 13 Oct 2014 - Added alternate calculation of halosteric anomaly (direct salinity anomaly calculation, rather than total-thermosteric)
    - PJD 13 Oct 2014 - Added makeSteric_version as a global attribute
    - TODO: Better deal with insitu vs thetao variables
    - TODO: Query Charles on why *.name attributes are propagating
    - TODO: validate outputs and compare to matlab versions - 10e-7 errors.
    """

    # Remap all variables to short names
    so          = salinity
    so_chg      = salinityChg
    temp        = temp
    temp_chg    = tempChg
    del(salinity,salinityChg,tempChg) ; gc.collect()

    # Strip attributes to maintain consistency between datasets
    for count,x in enumerate(so.attributes.keys()):
        delattr(so,x)
    #print so.listattributes() ; # Print remaining attributes
    for count,x in enumerate(so_chg.attributes.keys()):
        delattr(so_chg,x)
    for count,x in enumerate(temp.attributes.keys()):
        delattr(temp,x)
    for count,x in enumerate(temp_chg.attributes.keys()):
        delattr(temp_chg,x)
    del(count,x)

    # Create z-coordinate from salinity input
    if not pressure:
        z_coord                         = so.getAxis(0)
        y_coord                         = so.getAxis(1)
        y_coord                         = tile(y_coord,(so.shape[2],1)).transpose()
        depth_levels                    = tile(z_coord.getValue(),(so.shape[2],so.shape[1],1)).transpose()
        pressure_levels                 = sw.pres(np.array(depth_levels),np.array(y_coord))
        del(z_coord,y_coord,depth_levels) ; gc.collect()
    else:
        pressure_levels                 = so.getAxis(0)
        pressure_levels                 = transpose(tile(pressure_levels,(so.shape[2],so.shape[1],1)))

    pressure_levels                 = cdm.createVariable(pressure_levels,id='pressure_levels')
    pressure_levels.setAxis(0,so.getAxis(0))
    pressure_levels.setAxis(1,so.getAxis(1))
    pressure_levels.setAxis(2,so.getAxis(2))
    pressure_levels.id              = 'pressure_levels'
    pressure_levels.units_long      = 'decibar (pressure)'
    pressure_levels.positive        = 'down'
    pressure_levels.long_name       = 'sea_water_pressure'
    pressure_levels.standard_name   = 'sea_water_pressure'
    pressure_levels.units           = 'decibar'
    pressure_levels.axis            = 'Z'

    # Cleanup depth axis attributes
    depth               = so.getAxis(0)
    depth.id            = 'depth'
    depth.name          = 'depth'
    depth.long_name     = 'depth'
    depth.standard_name = 'depth'
    depth.axis          = 'Z'
    so.setAxis(0,depth)
    so_chg.setAxis(0,depth)
    temp.setAxis(0,depth)
    temp_chg.setAxis(0,depth)
    del(depth)

    # Convert using python-seawater library (v3.3.1 - 130807)
    if thetao:
        # Process potential temperature to in-situ - default conversion sets reference pressure to 0 (surface)
        #temp_chg                = sw.temp(np.array(so),np.array(temp_chg),np.array(pressure_levels)); # units degrees C
        #temp                    = sw.temp(np.array(so),np.array(temp),np.array(pressure_levels)); # units degrees C
        #temp_chg                = sw.ptmp(np.array(so),np.array(temp_chg),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C
        #temp                    = sw.ptmp(np.array(so),np.array(temp),np.array(pressure_levels),np.array(pressure_levels)); # units degrees C
        temp_chg                = np.array(temp_chg); # units degrees C
        temp                    = np.array(temp); # units degrees C

    # Climatologies - rho,cp,steric_height
    rho                         = sw.dens(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units kg m-3
    cp                          = sw.cp(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units J kg-1 C-1
    steric_height               = sw.gpan(np.array(so),np.array(temp),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)

    # Halosteric - rho,cp
    ss                          = map(array,(so+so_chg))
    rho_halo                    = sw.dens(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units kg m-3
    cp_halo                     = sw.cp(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units J kg-1 C-1
    tmp                         = sw.gpan(np.array(ss),np.array(temp),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)
    steric_height_halo_anom2    = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)

    # Full steric - steric_height
    tt                          = map(array,(temp+temp_chg))
    tmp                         = sw.gpan(np.array(ss),np.array(tt),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)
    steric_height_anom          = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)
    del(ss,tmp) ; gc.collect()

    # Thermosteric - rho,cp,steric_height
    rho_thermo                  = sw.dens(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units kg m-3
    cp_thermo                   = sw.cp(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units J kg-1 C-1
    tmp                         = sw.gpan(np.array(so),np.array(tt),np.array(pressure_levels)) ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)
    steric_height_thermo_anom   = tmp-steric_height ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)
    del(tt,tmp) ; gc.collect()

    # Halosteric - steric_height
    steric_height_halo_anom     = steric_height_anom-steric_height_thermo_anom ; # units m3 kg-1 Pa == m2 s-2 == J kg-1 (dynamic decimeter)

    # Create heat content
    heat_content                = np.array(temp)*np.array(rho)*np.array(cp) ; # units J
    heat_content_sanom          = np.array(temp)*np.array(rho_halo)*np.array(cp_halo) ; # units J
    heat_content_tanom          = np.array(temp_chg)*np.array(rho)*np.array(cp) ; # units J
    #heat_content_tanom          = np.array(temp_chg)*np.array(1020)*np.array(4187) ; # units J - try hard-coded - AR5 numbers
    heat_content_tsanom         = np.array(temp_chg)*np.array(rho_halo)*np.array(cp_halo) ; # units J

    # Correct all instances of NaN values and fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset
    temp                        = scrubNaNAndMask(temp,so)
    temp_chg                    = scrubNaNAndMask(temp_chg,so)
    rho                         = scrubNaNAndMask(rho,so)
    cp                          = scrubNaNAndMask(cp,so)
    rho_halo                    = scrubNaNAndMask(rho_halo,so)
    cp_halo                     = scrubNaNAndMask(cp_halo,so)
    rho_thermo                  = scrubNaNAndMask(rho_thermo,so)
    cp_thermo                   = scrubNaNAndMask(cp_thermo,so)
    steric_height               = scrubNaNAndMask(steric_height,so)
    steric_height_anom          = scrubNaNAndMask(steric_height_anom,so)
    steric_height_thermo_anom   = scrubNaNAndMask(steric_height_thermo_anom,so)
    steric_height_halo_anom     = scrubNaNAndMask(steric_height_halo_anom,so)
    steric_height_halo_anom2    = scrubNaNAndMask(steric_height_halo_anom2,so)
    heat_content                = scrubNaNAndMask(heat_content,so)
    heat_content_sanom          = scrubNaNAndMask(heat_content_sanom,so)
    heat_content_tanom          = scrubNaNAndMask(heat_content_tanom,so)
    heat_content_tsanom         = scrubNaNAndMask(heat_content_tsanom,so)

    # Recreate and redress variables
    so.id                           = 'so_mean'
    so.units                        = '1e-3'
    so_chg.id                       = 'so_chg'
    so_chg.units                    = '1e-3'
    temp                            = cdm.createVariable(temp,id='temp_mean')
    temp.setAxis(0,so.getAxis(0))
    temp.setAxis(1,so.getAxis(1))
    temp.setAxis(2,so.getAxis(2))
    temp.units                      = 'degrees_C'
    temp_chg                        = cdm.createVariable(temp_chg,id='temp_chg')
    temp_chg.setAxis(0,so.getAxis(0))
    temp_chg.setAxis(1,so.getAxis(1))
    temp_chg.setAxis(2,so.getAxis(2))
    temp_chg.units                  = 'degrees_C'
    rho                             = cdm.createVariable(rho,id='rho')
    rho.setAxis(0,so.getAxis(0))
    rho.setAxis(1,so.getAxis(1))
    rho.setAxis(2,so.getAxis(2))
    rho.name                        = 'density_mean'
    rho.units                       = 'kg m^-3'
    cp                              = cdm.createVariable(cp,id='cp')
    cp.setAxis(0,so.getAxis(0))
    cp.setAxis(1,so.getAxis(1))
    cp.setAxis(2,so.getAxis(2))
    cp.name                         = 'heat_capacity_mean'
    cp.units                        = 'J kg^-1 C^-1'
    rho_halo                        = cdm.createVariable(rho_halo,id='rho_halo')
    rho_halo.setAxis(0,so.getAxis(0))
    rho_halo.setAxis(1,so.getAxis(1))
    rho_halo.setAxis(2,so.getAxis(2))
    rho_halo.name                   = 'density_mean_halo'
    rho_halo.units                  = 'kg m^-3'
    cp_halo                         = cdm.createVariable(cp_halo,id='cp_halo')
    cp_halo.setAxis(0,so.getAxis(0))
    cp_halo.setAxis(1,so.getAxis(1))
    cp_halo.setAxis(2,so.getAxis(2))
    cp_halo.name                    = 'heat_capacity_mean_halo'
    cp_halo.units                   = 'J kg^-1 C^-1'
    rho_thermo                      = cdm.createVariable(rho_thermo,id='rho_thermo')
    rho_thermo.setAxis(0,so.getAxis(0))
    rho_thermo.setAxis(1,so.getAxis(1))
    rho_thermo.setAxis(2,so.getAxis(2))
    rho_thermo.name                 = 'density_mean_thermo'
    rho_thermo.units                = 'kg m^-3'
    cp_thermo                       = cdm.createVariable(cp_thermo,id='cp_thermo')
    cp_thermo.setAxis(0,so.getAxis(0))
    cp_thermo.setAxis(1,so.getAxis(1))
    cp_thermo.setAxis(2,so.getAxis(2))
    cp_thermo.name                  = 'heat_capacity_mean_thermo'
    cp_thermo.units                 = 'J kg^-1 C^-1'
    steric_height                   = cdm.createVariable(steric_height,id='steric_height')
    steric_height.setAxis(0,so.getAxis(0))
    steric_height.setAxis(1,so.getAxis(1))
    steric_height.setAxis(2,so.getAxis(2))
    steric_height.units             = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_anom              = cdm.createVariable(steric_height_anom,id='steric_height_anom')
    steric_height_anom.setAxis(0,so.getAxis(0))
    steric_height_anom.setAxis(1,so.getAxis(1))
    steric_height_anom.setAxis(2,so.getAxis(2))
    steric_height_anom.units        = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_thermo_anom       = cdm.createVariable(steric_height_thermo_anom,id='steric_height_thermo_anom')
    steric_height_thermo_anom.setAxis(0,so.getAxis(0))
    steric_height_thermo_anom.setAxis(1,so.getAxis(1))
    steric_height_thermo_anom.setAxis(2,so.getAxis(2))
    steric_height_thermo_anom.units = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_halo_anom         = cdm.createVariable(steric_height_halo_anom,id='steric_height_halo_anom')
    steric_height_halo_anom.setAxis(0,so.getAxis(0))
    steric_height_halo_anom.setAxis(1,so.getAxis(1))
    steric_height_halo_anom.setAxis(2,so.getAxis(2))
    steric_height_halo_anom.units   = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_halo_anom2         = cdm.createVariable(steric_height_halo_anom2,id='steric_height_halo_anom2')
    steric_height_halo_anom2.setAxis(0,so.getAxis(0))
    steric_height_halo_anom2.setAxis(1,so.getAxis(1))
    steric_height_halo_anom2.setAxis(2,so.getAxis(2))
    steric_height_halo_anom2.units   = 'm^3 kg^-1 Pa (dynamic decimeter)'
    heat_content                    = cdm.createVariable(heat_content,id='heat_content')
    heat_content.setAxis(0,so.getAxis(0))
    heat_content.setAxis(1,so.getAxis(1))
    heat_content.setAxis(2,so.getAxis(2))
    heat_content.units         = 'J'
    heat_content_sanom              = cdm.createVariable(heat_content_sanom,id='heat_content_sanom')
    heat_content_sanom.setAxis(0,so.getAxis(0))
    heat_content_sanom.setAxis(1,so.getAxis(1))
    heat_content_sanom.setAxis(2,so.getAxis(2))
    heat_content_sanom.units        = 'J'
    heat_content_tanom              = cdm.createVariable(heat_content_tanom,id='heat_content_tanom')
    heat_content_tanom.setAxis(0,so.getAxis(0))
    heat_content_tanom.setAxis(1,so.getAxis(1))
    heat_content_tanom.setAxis(2,so.getAxis(2))
    heat_content_tanom.units        = 'J'
    heat_content_tsanom             = cdm.createVariable(heat_content_tsanom,id='heat_content_tsanom')
    heat_content_tsanom.setAxis(0,so.getAxis(0))
    heat_content_tsanom.setAxis(1,so.getAxis(1))
    heat_content_tsanom.setAxis(2,so.getAxis(2))
    heat_content_tsanom.units       = 'J'

    # Create model-based depth index for subset target levels
    newdepth = np.array([5,10,20,30,40,50,75,100,125,150,200,300,500,700,1000,1500,1800,2000]).astype('f');
    newdepth_bounds = np.array([[0,5],[5,10],[10,20],[20,30],[30,40],[40,50],[50,75],[75,100],[100,125],[125,150],
    [150,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f')
    #newdepth = np.array([200,300,500,700,1000,1500,1800,2000]).astype('f');
    #newdepth_bounds = np.array([[0,200],[200,300],[300,500],[500,700],[700,1000],[1000,1500],[1500,1800],[1800,2000]]).astype('f')

    # Interpolate to depths
    so_depthInterp                          = cdu.linearInterpolation(so,pressure_levels,levels=newdepth)
    temp_depthInterp                        = cdu.linearInterpolation(temp,pressure_levels,levels=newdepth)
    steric_height_depthInterp               = cdu.linearInterpolation(steric_height,pressure_levels,levels=newdepth)
    steric_height_anom_depthInterp          = cdu.linearInterpolation(steric_height_anom,pressure_levels,levels=newdepth)
    steric_height_thermo_anom_depthInterp   = cdu.linearInterpolation(steric_height_thermo_anom,pressure_levels,levels=newdepth)
    steric_height_halo_anom_depthInterp     = cdu.linearInterpolation(steric_height_halo_anom,pressure_levels,levels=newdepth)
    steric_height_halo_anom2_depthInterp    = cdu.linearInterpolation(steric_height_halo_anom2,pressure_levels,levels=newdepth)
    heat_content_sanom_depthInterp          = cdu.linearInterpolation(heat_content_sanom,pressure_levels,levels=newdepth)
    heat_content_tanom_depthInterp          = cdu.linearInterpolation(heat_content_tanom,pressure_levels,levels=newdepth)
    heat_content_tsanom_depthInterp         = cdu.linearInterpolation(heat_content_tanom,pressure_levels,levels=newdepth)

    # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset
    temp_depthInterp                        = scrubNaNAndMask(temp_depthInterp,so_depthInterp)
    steric_height_depthInterp               = scrubNaNAndMask(steric_height_depthInterp,so_depthInterp)
    steric_height_anom_depthInterp          = scrubNaNAndMask(steric_height_anom_depthInterp,so_depthInterp)
    steric_height_thermo_anom_depthInterp   = scrubNaNAndMask(steric_height_thermo_anom_depthInterp,so_depthInterp)
    steric_height_halo_anom_depthInterp     = scrubNaNAndMask(steric_height_halo_anom_depthInterp,so_depthInterp)
    steric_height_halo_anom2_depthInterp    = scrubNaNAndMask(steric_height_halo_anom2_depthInterp,so_depthInterp)
    heat_content_sanom_depthInterp          = scrubNaNAndMask(heat_content_sanom_depthInterp,so_depthInterp)
    heat_content_tanom_depthInterp          = scrubNaNAndMask(heat_content_tanom_depthInterp,so_depthInterp)
    heat_content_tsanom_depthInterp         = scrubNaNAndMask(heat_content_tsanom_depthInterp,so_depthInterp)

    # Fix bounds
    newdepth = so_depthInterp.getAxis(0)
    newdepth.setBounds(newdepth_bounds)
    del(newdepth_bounds)
    newdepth.id             = 'depth2'
    newdepth.units_long     = 'decibar (pressure)'
    newdepth.positive       = 'down'
    newdepth.long_name      = 'sea_water_pressure'
    newdepth.standard_name  = 'sea_water_pressure'
    newdepth.units          = 'decibar'
    newdepth.axis           = 'Z'

    # Assign corrected bounds
    so_depthInterp.setAxis(0,newdepth)
    temp_depthInterp.setAxis(0,newdepth)
    steric_height_depthInterp.setAxis(0,newdepth)
    steric_height_anom_depthInterp.setAxis(0,newdepth)
    steric_height_thermo_anom_depthInterp.setAxis(0,newdepth)
    steric_height_halo_anom_depthInterp.setAxis(0,newdepth)
    steric_height_halo_anom2_depthInterp.setAxis(0,newdepth)
    heat_content_sanom_depthInterp.setAxis(0,newdepth)
    heat_content_tanom_depthInterp.setAxis(0,newdepth)
    heat_content_tsanom_depthInterp.setAxis(0,newdepth)

    # Average/integrate to surface - configure bounds
    # Preallocate arrays
    so_depthAve                     = np.ma.zeros([len(newdepth),shape(so)[1],shape(so)[2]])
    temp_depthAve                   = so_depthAve.copy()
    heat_content_sanom_depthInteg   = so_depthAve.copy()
    heat_content_tanom_depthInteg   = so_depthAve.copy()
    heat_content_tsanom_depthInteg  = so_depthAve.copy()
    for count,depth in enumerate(newdepth):
        tmp = cdu.averager(so_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='average')
        so_depthAve[count,]                     = tmp;
        tmp = cdu.averager(temp_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='average')
        temp_depthAve[count,]                   = tmp;
        tmp = cdu.averager(heat_content_sanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum')
        heat_content_sanom_depthInteg[count,]   = tmp
        tmp = cdu.averager(heat_content_tanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum')
        heat_content_tanom_depthInteg[count,]   = tmp
        tmp = cdu.averager(heat_content_tsanom_depthInterp[0:(count+1),...],axis=0,weights='weighted',action='sum')
        heat_content_tsanom_depthInteg[count,]  = tmp
    del(heat_content_tanom_depthInterp,heat_content_tsanom_depthInterp); gc.collect()

    # Fix masks - applied before cdms variables are created otherwise names/ids/attributes are reset
    so_depthAve = scrubNaNAndMask(so_depthAve,so_depthInterp)
    temp_depthAve = scrubNaNAndMask(temp_depthAve,so_depthInterp)
    heat_content_sanom_depthInteg = scrubNaNAndMask(heat_content_sanom_depthInteg,so_depthInterp)
    heat_content_tanom_depthInteg = scrubNaNAndMask(heat_content_tanom_depthInteg,so_depthInterp)
    heat_content_tsanom_depthInteg = scrubNaNAndMask(heat_content_tsanom_depthInteg,so_depthInterp)
    del(so_depthInterp)

    # Convert numpy arrays to cdms objects
    heat_content_sanom_depthInteg               = cdm.createVariable(heat_content_sanom_depthInteg,id='heat_content_sanom_depthInteg')
    heat_content_sanom_depthInteg.id            = 'heat_content_sanom_depthInteg'
    heat_content_sanom_depthInteg.setAxis(0,newdepth)
    heat_content_sanom_depthInteg.setAxis(1,so.getAxis(1))
    heat_content_sanom_depthInteg.setAxis(2,so.getAxis(2))
    heat_content_sanom_depthInteg.units         = 'J'
    heat_content_tanom_depthInteg               = cdm.createVariable(heat_content_tanom_depthInteg,id='heat_content_tanom_depthInteg')
    heat_content_tanom_depthInteg.id            = 'heat_content_tanom_depthInteg'
    heat_content_tanom_depthInteg.setAxis(0,newdepth)
    heat_content_tanom_depthInteg.setAxis(1,so.getAxis(1))
    heat_content_tanom_depthInteg.setAxis(2,so.getAxis(2))
    heat_content_tanom_depthInteg.units         = 'J'
    heat_content_tsanom_depthInteg              = cdm.createVariable(heat_content_tsanom_depthInteg,id='heat_content_tsanom_depthInteg')
    heat_content_tsanom_depthInteg.id           = 'heat_content_tsanom_depthInteg'
    heat_content_tsanom_depthInteg.setAxis(0,newdepth)
    heat_content_tsanom_depthInteg.setAxis(1,so.getAxis(1))
    heat_content_tsanom_depthInteg.setAxis(2,so.getAxis(2))
    heat_content_tsanom_depthInteg.units        = 'J'
    so_depthAve                                 = cdm.createVariable(so_depthAve,id='so_depthAve')
    so_depthAve.id                              = 'so_depthAve'
    so_depthAve.setAxis(0,newdepth)
    so_depthAve.setAxis(1,so.getAxis(1))
    so_depthAve.setAxis(2,so.getAxis(2))
    so_depthAve.units                           = '1e-3'
    temp_depthAve                               = cdm.createVariable(temp_depthAve,id='temp_depthAve')
    temp_depthAve.id                            = 'temp_depthAve'
    temp_depthAve.setAxis(0,newdepth)
    temp_depthAve.setAxis(1,so.getAxis(1))
    temp_depthAve.setAxis(2,so.getAxis(2))
    temp_depthAve.units                         = 'degrees_C'
    steric_height_depthInterp                   = cdm.createVariable(steric_height_depthInterp,id='steric_height_depthInterp')
    steric_height_depthInterp.setAxis(0,newdepth)
    steric_height_depthInterp.setAxis(1,so.getAxis(1))
    steric_height_depthInterp.setAxis(2,so.getAxis(2))
    steric_height_depthInterp.units             = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_anom_depthInterp              = cdm.createVariable(steric_height_anom_depthInterp,id='steric_height_anom_depthInterp')
    steric_height_anom_depthInterp.setAxis(0,newdepth)
    steric_height_anom_depthInterp.setAxis(1,so.getAxis(1))
    steric_height_anom_depthInterp.setAxis(2,rho.getAxis(2))
    steric_height_anom_depthInterp.units        = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_thermo_anom_depthInterp       = cdm.createVariable(steric_height_thermo_anom_depthInterp,id='steric_height_thermo_anom_depthInterp')
    steric_height_thermo_anom_depthInterp.setAxis(0,newdepth)
    steric_height_thermo_anom_depthInterp.setAxis(1,so.getAxis(1))
    steric_height_thermo_anom_depthInterp.setAxis(2,so.getAxis(2))
    steric_height_thermo_anom_depthInterp.units = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_halo_anom_depthInterp         = cdm.createVariable(steric_height_halo_anom_depthInterp,id='steric_height_halo_anom_depthInterp')
    steric_height_halo_anom_depthInterp.setAxis(0,newdepth)
    steric_height_halo_anom_depthInterp.setAxis(1,so.getAxis(1))
    steric_height_halo_anom_depthInterp.setAxis(2,so.getAxis(2))
    steric_height_halo_anom_depthInterp.units   = 'm^3 kg^-1 Pa (dynamic decimeter)'
    steric_height_halo_anom2_depthInterp         = cdm.createVariable(steric_height_halo_anom2_depthInterp,id='steric_height_halo_anom2_depthInterp')
    steric_height_halo_anom2_depthInterp.setAxis(0,newdepth)
    steric_height_halo_anom2_depthInterp.setAxis(1,so.getAxis(1))
    steric_height_halo_anom2_depthInterp.setAxis(2,so.getAxis(2))
    steric_height_halo_anom2_depthInterp.units   = 'm^3 kg^-1 Pa (dynamic decimeter)'
    # Cleanup workspace
    del(newdepth) ; gc.collect()


    # Write variables to file
    if os.path.isfile(outFileName):
        os.remove(outFileName)
    filehandle = cdm.open(outFileName,'w')
    # Global attributes
    globalAttWrite(filehandle,options=None) ; # Use function to write standard global atts
    # Write seawater version
    filehandle.seawater_library_version = sw.__version__
    # Write makeSteric version
    makeStericPath = str(makeSteric.__code__).split(' ')[6]
    makeStericPath = replace(replace(makeStericPath,'"',''),',','') ; # Clean scraped path
    filehandle.makeSteric_version = ' '.join(getGitInfo(makeStericPath)[0:3])
    # Master variables
    filehandle.write(so.astype('float32'))
    filehandle.write(so_chg.astype('float32'))
    filehandle.write(so_depthAve.astype('float32'))
    filehandle.write(temp.astype('float32'))
    filehandle.write(temp_chg.astype('float32'))
    filehandle.write(temp_depthAve.astype('float32'))
    # Derived variables
    filehandle.write(cp.astype('float32'))
    filehandle.write(cp_halo.astype('float32'))
    filehandle.write(cp_thermo.astype('float32'))
    filehandle.write(rho.astype('float32'))
    filehandle.write(rho_halo.astype('float32'))
    filehandle.write(rho_thermo.astype('float32'))
    filehandle.write(heat_content.astype('float32'))
    filehandle.write(heat_content_sanom.astype('float32'))
    filehandle.write(heat_content_sanom_depthInteg.astype('float32'))
    filehandle.write(heat_content_tanom.astype('float32'))
    filehandle.write(heat_content_tanom_depthInteg.astype('float32'))
    filehandle.write(heat_content_tsanom.astype('float32'))
    filehandle.write(heat_content_tsanom_depthInteg.astype('float32'))
    filehandle.write(steric_height.astype('float32'))
    filehandle.write(steric_height_depthInterp.astype('float32'))
    filehandle.write(steric_height_anom.astype('float32'))
    filehandle.write(steric_height_anom_depthInterp.astype('float32'))
    filehandle.write(steric_height_halo_anom.astype('float32'))
    filehandle.write(steric_height_halo_anom2.astype('float32'))
    filehandle.write(steric_height_halo_anom_depthInterp.astype('float32'))
    filehandle.write(steric_height_halo_anom2_depthInterp.astype('float32'))
    filehandle.write(steric_height_thermo_anom.astype('float32'))
    filehandle.write(steric_height_thermo_anom_depthInterp.astype('float32'))
    filehandle.close()
    # Cleanup workspace
    del(outFileName) ; gc.collect()
	try:
		pr_depths = pr_cube.coord('depth').points
		pr_cube = pr_cube.extract(iris.Constraint(depth = np.min(pr_depths)))
	except:
		print 'no precipitation depth coordinate'
	temporary_cube = pr_cube.intersection(longitude = (west, east))
	pr_cube_n_iceland = temporary_cube.intersection(latitude = (south, north))
	try:
		pr_cube_n_iceland.coord('latitude').guess_bounds()
		pr_cube_n_iceland.coord('longitude').guess_bounds()
	except:
		print 'already have bounds'
	grid_areas = iris.analysis.cartography.area_weights(pr_cube_n_iceland)
	pr_cube_n_iceland_mean = pr_cube_n_iceland.collapsed(['latitude', 'longitude'],iris.analysis.MEAN, weights=grid_areas).data
	#density
	tmp_density = seawater.dens(s_cube_n_iceland_mean,t_cube_n_iceland_mean-273.15)
	test = np.size(t_cube_n_iceland_mean)
	if test <= 1000:
		temp_t_mean = np.mean(t_cube_n_iceland_mean)
	if test > 1000:
		temp_t_mean = np.mean(t_cube_n_iceland_mean[0:1000])
	test = np.size(s_cube_n_iceland_mean)
	if test <= 1000:
		temp_s_mean = np.mean(s_cube_n_iceland_mean)
	if test > 1000:
		temp_s_mean = np.mean(s_cube_n_iceland_mean[0:1000])
	tmp_temp_mean_density = seawater.dens(s_cube_n_iceland_mean,t_cube_n_iceland_mean*0.0+temp_t_mean-273.15)
	tmp_sal_mean_density = seawater.dens(s_cube_n_iceland_mean*0.0+temp_s_mean, t_cube_n_iceland_mean-273.15)
	#years
	coord = t_cube_n_iceland.coord('time')
	dt = coord.units.num2date(coord.points)
for i,model in enumerate(models):
    	print 'testing: '+model
        file1 = glob.glob(directory+model+'_*'+variables[0]+'*r1i1p1*.nc')
        file2 = glob.glob(directory+model+'_*'+variables[1]+'*r1i1p1*.nc')
        file3 = glob.glob(directory+model+'_*'+variables[2]+'*r1i1p1*.nc')
        if ((np.size(file1) > 0) & (np.size(file2) > 0) & (np.size(file3) > 0)):
            print 'processing: '+model
            size = np.size(np.where(data[model]['tos_year']))
            data[model]['density'] = np.zeros(size)
            data[model]['density'][:] = np.NAN
	    if np.size(data[model]['sos']) == np.size(data[model]['tos']):
            	for yr in data[model]['tas_year']:
                	loc = np.where(data[model]['tos_year'] == yr)
                	if np.size(loc) > 0:
                            if np.mean(data[model]['sos'].data) < 10.0:
                    		data[model]['density'][loc] = seawater.dens(data[model]['sos'][loc]*1000.0,data[model]['tos'][loc]-273.15)
                            if np.mean(data[model]['sos'].data) > 10.0:
                    		data[model]['density'][loc] = seawater.dens(data[model]['sos'][loc],data[model]['tos'][loc]-273.15)


for i,model in enumerate(models):
    	print 'testing: '+model
        file1 = glob.glob(directory+model+'_*'+variables[0]+'*r1i1p1*.nc')
        file2 = glob.glob(directory+model+'_*'+variables[1]+'*r1i1p1*.nc')
        file3 = glob.glob(directory+model+'_*'+variables[2]+'*r1i1p1*.nc')
        if ((np.size(file1) > 0) & (np.size(file2) > 0) & (np.size(file3) > 0)):
            plt.plot(data[model]['tas'].data - np.mean(data[model]['tas'].data),'r')
            plt.plot(data[model]['density'] - scipy.stats.nanmean(data[model]['density']),'b')
            plt.title(model)
            plt.show()
salinity_atlantic_meridional = salinity_atlantic.collapsed('longitude',MEAN)
figure()
qplt.contourf(salinity_atlantic_meridional,linspace(33,38,50))
savefig('/home/ph290/Documents/figures/atl_meridional_salinity.png')
show()

#We can use the above, and the python package 'seawater' to calculate seawaters density for us 

density_cube = temperature_cube.copy()
#first we need to make a new cube to hold the density data when we calculate it. This is what we do here. 

#we also want to give that cube the right metadata
density_cube.standard_name = 'sea_water_density'
density_cube.units = 'kg m-3'

density_cube.data = seawater.dens(salinity_cube.data,temperature_cube.data,1)
density_atlantic = density_cube.extract(atlantic_region2)
density_atlantic_meridional = density_atlantic.collapsed('longitude',MEAN)

figure()
qplt.contourf(cfc_atlantic_meridional,linspace(0,300,50))
CS=iplt.contour(density_atlantic_meridional,array([1026.2,1026.4,1027.6,1026.8,1027.0,1027.2,1027.3,1027.4,1027.5,1027.6,1027.7,1027.8]),colors='gray')
clabel(CS, fontsize=12, inline=1)
savefig('/home/ph290/Documents/figures/atl_meridional_cfc_density.png')
show()


'''
And how might we do some future analysis?
'''
Ejemplo n.º 23
0
    def selector(self,var,T_int, region):
        '''
        Returns a profile list by selecting for
          variable (string),
          T_int   (TimeInterval object)
          region  (region object)

         '''

        ivar  = find_index(var, self.VARIABLES)
        values= self.DATA[ivar,:]
        units = self.UNITS[ivar,:].tostring()

        if units =="\\mumol/kg":
            itemp  = find_index('temp'    , self.VARIABLES)
            ipsal  = find_index('salinity', self.VARIABLES)
            idens  = find_index('density' , self.VARIABLES)
            temp   = self.DATA[itemp,:]
            sali   = self.DATA[ipsal,:]
            pres   = self.DATA[5,:]
            dens   = self.DATA[idens,:]
            good_rho  = (sali < 1.e+19 ) & (sali>0) & (temp < 1.e+19 ) & (temp>0) & (pres < 1.e+19 ) & (pres>0)
            t = T90conv(temp)
            n = len(values)
            calculated_rho  = np.ones((n),np.float32)*np.nan
            assumed_density = np.ones((n),np.float32)*np.nan
            calculated_rho[good_rho]  = seawater.dens(sali[good_rho],t[good_rho],pres[good_rho])


            good_dens = (dens < 1.e+19 ) & (dens>0)
            for i in range(n):
                if good_dens[i]:
                    assumed_density[i] = dens[i]
                else:
                    if good_rho[i]:
                        assumed_density[i] = calculated_rho[i]


            good = ~np.isnan(assumed_density)
            values[good] = values[good] * assumed_density[good] /1000.
            values[~good] = 1.e+20

        good  = (values < 1e+19) & (values > 0)
        
        values = values[good]
        
        year    = self.DATA[ 0,good]
        month   = self.DATA[ 1,good]
        day     = self.DATA[ 2,good]
        lat     = self.DATA[ 3,good]
        lon     = self.DATA[ 4,good]
        depth   = self.DATA[ 5,good]
        dataset = self.DATA[-1,good]
        
        nValues=values.size
        Selected = np.zeros((nValues,),dtype=np.bool)
        TIME     = np.zeros((nValues), dtype=np.int32)
        for i in range(nValues):
            time = datetime.datetime(year[i],month[i],day[i])
            TIME[i] = time.toordinal()
            if T_int.contains(time) & region.is_inside(lon[i], lat[i]):
                Selected[i] = True 
    
        Time    = TIME[Selected]
        Lon     =  lon[Selected]
        Lat     =  lat[Selected]
        values  =  values[Selected]
        depth   =   depth[Selected]
        dataset = dataset[Selected]
        
        return self.profileGenerator(Time, Lon, Lat, values, depth, dataset)