Esempio n. 1
0
def __calc_pressure(depth, latitude):
    pressure = []
    try:
        pressure = [seawater.pres(d, latitude) for d in depth]
    except TypeError:
        pressure = seawater.pres(depth, latitude)

    return np.array(pressure)
Esempio n. 2
0
    def load_data(self):
        super(SoundSpeedPlotter, self).load_data()

        self.pressure = [
            seawater.pres(self.temperature_depths[idx], ll[0])
            for idx, ll in enumerate(self.points)
        ]

        ureg = pint.UnitRegistry()
        try:
            u = ureg.parse_units(self.variable_units[0].lower())
        except:
            u = ureg.dimensionless

        if u == ureg.boltzmann_constant:
            u = ureg.kelvin

        if u == ureg.kelvin:
            unit = "Celsius"
            temperature_c = ureg.Quantity(self.temperature,
                                          u).to(ureg.celsius).magnitude
        else:
            temperature_c = self.temperature

        self.sspeed = seawater.svel(self.salinity, temperature_c,
                                    self.pressure)
def pressure(filename, yS, yN):

    avg_lat = (yS + yN) / 2.0
    depths = depth_list(filename)
    pressure = sw.pres(depths, avg_lat)

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

    if vectorflag:
        Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],data['u'][i,layer,vidx],data['v'][i,layer,vidx],angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.001)    
        qaxk=ax.quiverkey(Q1,.9,.88,2, r'2 ms$^{-1}$')
    if uniformvectorflag:
        norm=np.sqrt(data['u'][i,layer,vidx]**2+data['v'][i,layer,vidx]**2)
        Q1=ax.quiver(data['uvnodell'][vidx,0],data['uvnodell'][vidx,1],np.divide(data['u'][i,layer,vidx],norm),np.divide(data['v'][i,layer,vidx],norm),angles='xy',scale_units='xy',scale=vector_scale,zorder=100,width=.002,color='k')  
    
    cb=plt.colorbar(triax)
    cb.set_label(r'Density (kg m$^{3}$)',fontsize=10)    
    ax.set_xlabel(r'Longitude ($^{\circ}$)')
    ax.set_ylabel(r'Latitude ($^{\circ}$)')
    ax.axis(region['region'])
    ax.annotate('{} {}'.format(data['Time'][i][:10],data['Time'][i][11:19]),xy=(.425,.93),xycoords='axes fraction')
    for label in ax.get_xticklabels()[::2]:
        label.set_visible(False)
    f.savefig(savepath + grid + '_' + region['regionname'] +'_density_' + ("%04d" %(i)) + '.png',dpi=300)
    plt.close(f)
def processor(input_list):
    print('Compute ', lout, ' from ', lin)
    # Select variables
    votemper = input_list['votemper']
    vosaline = input_list['vosaline']
    DepthLayers = votemper.DepthLayers
    LatCells = votemper.LatCells
    # Replicate geometry 3D (to be updated with complete model geometry variables)
    if np.ndim(votemper.LatCells) == 1 and np.ndim(votemper.LonCells) == 1 and np.ndim(votemper.DepthLayers) == 1:
        DepthLayers = np.transpose(np.tile(votemper.DepthLayers,
                                           (votemper.LatCells.shape[0], votemper.LonCells.shape[0], 1)), (2, 0, 1))
        LatCells = np.transpose(np.tile(votemper.LatCells,
                                        (votemper.LonCells.shape[0], 1)), (1, 0))
    # Concatenate latitude, longitude and depth cells at the centers of the grid
    # (COMIC TYPE CHARACTERISTIC reserved procedure)
    depths = 1 / 4 * (DepthLayers[1:, 1:, 1:] + DepthLayers[: - 1, : - 1, 1:] +
                      DepthLayers[: - 1, 1:, : - 1] + DepthLayers[: - 1, : - 1, : - 1])
    lats = 1 / 4 * (LatCells[1:, 1:] + LatCells[: - 1, 1:] +
                    LatCells[1:, : - 1] + LatCells[: - 1, : - 1])
    # Cut time dimension
    temp = votemper.COSM[0, ...]
    salt = vosaline.COSM[0, ...]
    # Compute Pressure 3D
    pressure = sw.pres(depths, lats)
    # Compute Potential Density field 3D
    density = ma.array(np.empty(shape=votemper.COSM.shape), mask=False, fill_value=1.e20, dtype=float)
    density[0, ...] = sw.dens(salt, temp, pressure)
    # Attributes of Characteristic class are (StandardName,
    # VariableName, DepthLayers, LonCells, LatCells, TimeCells, ConcatenatioOfSpatialMaps, MaskedAs=None)
    potential_d = sp_type.Characteristic(StandardName='sea_water_density',
                                         VariableName='vodnsity', DepthLayers=votemper.DepthLayers,
                                         LonCells=votemper.LonCells, LatCells=votemper.LatCells,
                                         TimeCells=votemper.TimeCells, ConcatenatioOfSpatialMaps=density)
    return potential_d
Esempio n. 6
0
def get_full(fn):
    # gets v_dict for the full extent of one history file
    ds = nc.Dataset(fn)
    G, S, T = zrfun.get_basic_info(fn)        

    # extract needed info from history file
    v_dict = dict()
    if print_info:
        print('\nINPUT Variable Info:')
    for vn in ['alkalinity', 'TIC', 'salt', 'temp','rho']:
        v = ds[vn][:]
        v = fillit(v)
        v_dict[vn] = v
                
    # create depth, pressure, and in situ temperature
    h = ds['h'][:]
    h = fillit(h)
    lat = G['lat_rho'][:]
    z_rho = zrfun.get_z(h, 0*h, S, only_rho=True)
    depth = -z_rho
    pres = sw.pres(depth, lat)
    v_dict['pres'] = pres
    temp = sw.ptmp(v_dict['salt'], v_dict['temp'], 0, v_dict['pres'])
    v_dict['temp'] = temp
    
    # convert from umol/L to umol/kg using in situ dentity
    v_dict['alkalinity'] = 1000 * v_dict['alkalinity'] / (v_dict['rho'] + 1000)
    v_dict['TIC'] = 1000 * v_dict['TIC'] / (v_dict['rho'] + 1000)
    
    # clean up
    v_dict.pop('rho') # no longer needed, so don't pass to worker
    ds.close()
    
    return v_dict
def sspeed(depth, latitude, temperature, salinity):
    """
    Calculates the speed of sound.

    Parameters:
    depth: The depth(s) in meters
    latitude: The latitude(s) in degrees North
    temperature: The temperatures(s) in Celsius
    salinity: The salinity (unitless)
    """
    try:
        press = [seawater.pres(d, latitude) for d in depth]
    except TypeError:
        press = seawater.pres(depth, latitude)

    speed = seawater.svel(salinity, temperature, press)
    return np.array(speed)
Esempio n. 8
0
def buoy_calc(Z,
              EOS,
              T=None,
              S=None,
              alpha=None,
              sbeta=None,
              g=None,
              lat=None,
              Tref=None,
              Sref=None):
    """Calculate the buoyancy given the temperature T, salinity S,depth,
    specified equation of state, thermal expansion coefficient (if necessary)
    haline coefficient (if necessary) and latitude (if necessary)"""
    if g is None:
        g = 9.81
    if EOS == 'lin':
        """Set default parameters if not otherwise specified"""
        if g is None:
            g = 9.81
        if alpha is None:
            alpha = 2e-4
        if sbeta is None:
            sbeta = 7.4e-4
        if Tref is None:
            Tref = 0
        if Sref is None:
            Sref = 0
        #Calculate the buoyancy contributions where relevant
        if S is None and T is not None:
            """Thermal contribution only"""
            buoy = g * alpha * (T - Tref)
        if T is None and S is not None:
            """Haline contribution only"""
            buoy = -g * sbeta * (S - Sref)
        if T is not None and S is not None:
            buoy = g * alpha * (T - Tref) - g * sbeta * (S - Sref)

    if EOS == 'jmd':
        import jmd95
        import seawater
        if T is None:
            T = np.zeros(np.shape(S))
        if S is None:
            S = np.zeros(np.shape(T))
        rhoConst = 1000
        #Pressure needed in decibars
        press = seawater.pres(-Z, 45)
        #Loop this routine along t and y to avoid running out of memory
        sp = np.shape(S)
        buoy = np.empty(np.shape(S))
        for ti in np.arange(0, sp[-1]):
            for rw in np.arange(0, sp[0]):
                buoy_fac = g / rhoConst
                b = -buoy_fac * (jmd95.densjmd95(np.squeeze(
                    S[rw, :, :, ti]), np.squeeze(T[rw, :, :, ti]), press) -
                                 1030)
                buoy[rw, :, :, ti] = b
    return buoy
Esempio n. 9
0
    def load_data(self):
        super(SoundSpeedPlotter, self).load_data()

        self.pressure = [seawater.pres(self.temperature_depths[idx], ll[0])
                         for idx, ll in enumerate(self.points)]

        self.sspeed = seawater.svel(
            self.salinity, self.temperature, self.pressure
        )
Esempio n. 10
0
    def load_data(self):
        super(SoundSpeedPlotter, self).load_data()

        self.pressure = [
            seawater.pres(self.temperature_depths[idx], ll[0])
            for idx, ll in enumerate(self.points)
        ]

        self.sspeed = seawater.svel(self.salinity, self.temperature,
                                    self.pressure)
Esempio n. 11
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
Esempio n. 12
0
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)
Esempio n. 13
0
def buoy_dgl(dgl,
             eos,
             alpha=None,
             sbeta=None,
             g=None,
             lat=None,
             Tref=None,
             Sref=None):
    """Calculate the buoyancy field for a structured array dgl"""
    import mit
    b_exists = mit.check_field(dgl, 'b')
    if not b_exists:
        dgl = mit.add_field(dgl, 'b')
    S_exists = mit.check_field(dgl, 's')
    T_exists = mit.check_field(dgl, 't')
    if eos == 'lin':
        alpha, sbeta, g, Tref, Sref = lin_eos_params(alpha, sbeta, g, lat,
                                                     Tref, Sref)
        for rw in np.arange(0, len(dgl[0]['y'])):
            if T_exists and not S_exists:
                """Thermal contribution only"""
                dgl[0]['b'][rw, :, :, :] = g * alpha * (
                    dgl[0]['t'][rw, :, :, :] - Tref)
            if S_exists and not T_exists:
                """Haline contribution only"""
                dgl[0]['b'][rw, :, :, :] = -g * sbeta * (
                    dgl[0]['s'][rw, :, :, :] - Sref)
            if T_exists and S_exists:
                dgl[0]['b'][rw, :, :, :] = g * alpha * (
                    dgl[0]['t'][rw, :, :, :] - Tref)
                -g * sbeta * (dgl[0]['s'][rw, :, :, :] - Sref)

    elif eos == 'jmd':
        g = 9.81
        import jmd95
        import seawater
        import mit
        if not T_exists:
            T = np.zeros(np.shape(dgl[0]['s']))
        if not S_exists:
            S = np.zeros(np.shape(dgl[0]['t']))
        rhoConst = 1000
        ylen, xlen, zlen, tlen = mit.dgl_dims(dgl)
        #Pressure needed in decibars
        press = seawater.pres(-dgl[0]['z'], lat=45)
        buoy_fac = g / rhoConst
        #Loop this routine along t and y to avoid running out of memory
        for ti in np.arange(0, tlen):
            for rw in np.arange(0, ylen):
                dgl[0]['b'][rw, :, :, ti] = -buoy_fac * (jmd95.densjmd95(
                    np.squeeze(dgl[0]['s'][rw, :, :, ti]),
                    np.squeeze(dgl[0]['t'][rw, :, :, ti]), press) - 1030)
    return dgl
def get_SG(file,
           get_data=True,
           get_dives=None,
           remove_seawater=False,
           wavelength=700):
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=UserWarning)
        warnings.simplefilter("ignore", category=RuntimeWarning)

        nc = Dataset(file, 'r')

        inds = np.arange(len(
            nc.variables['time'])) if get_dives is None else get_dives

        rd = dt.datetime(1970, 1, 1)
        sd = dt.datetime(2018, 1, 1)

        t = np.nanmedian(nc.variables['time'][inds], axis=1)
        t = [rd + dt.timedelta(seconds=tt) - sd for tt in t]
        t = np.array([tt.days + tt.seconds / 86400 for tt in t])
        lat = np.nanmedian(nc.variables['lat'][inds], axis=1)
        lon = np.nanmedian(nc.variables['lon'][inds], axis=1)

        if get_data:
            T = np.ma.getdata(nc.variables['T'][inds])
            S = np.ma.getdata(nc.variables['S'][inds])
            z = np.repeat(np.atleast_2d(np.ma.getdata(nc.variables['z'][:])),
                          T.shape[0],
                          axis=0)
            if remove_seawater:
                VSF_sw = betasw_wetlabs(700, 20, 124, 41, T, S,
                                        sw.pres(z, lat=50.5))
            else:
                VSF_sw = 0
            VSF = np.ma.getdata(
                nc.variables['baseline_%03dnm' % wavelength][inds]) - VSF_sw

        bad_inds = (t > END_DATE)  # beyond time of the main EXPORTS experiment
        t = t[~bad_inds]
        lat = lat[~bad_inds]
        lon = lon[~bad_inds]
        inds = inds[~bad_inds]

        if get_data:
            T = T[~bad_inds]
            S = S[~bad_inds]
            VSF = VSF[~bad_inds]
            z = z[~bad_inds]

    if get_data:
        return t, lat, lon, inds, T, S, z, VSF
    else:
        return t, lat, lon, inds
Esempio n. 15
0
def buoy_calc(Z, EOS, T = None, S = None, alpha = None,
              sbeta = None, g = None, lat = None,
              Tref = None, Sref = None):
    """Calculate the buoyancy given the temperature T, salinity S,depth,
    specified equation of state, thermal expansion coefficient (if necessary)
    haline coefficient (if necessary) and latitude (if necessary)"""
    if g is None:
        g = 9.81
    if EOS == 'lin':
        """Set default parameters if not otherwise specified"""
        if g is None:
            g = 9.81
        if alpha is None:
            alpha = 2e-4
        if sbeta is None:
            sbeta = 7.4e-4
        if Tref is None:
            Tref = 0
        if Sref is None:
            Sref = 0
        #Calculate the buoyancy contributions where relevant
        if S is None and T is not None:
            """Thermal contribution only"""
            buoy = g*alpha*(T - Tref)
        if T is None and S is not None:
            """Haline contribution only"""
            buoy = -g*sbeta*(S - Sref)
        if T is not None and S is not None:
            buoy = g*alpha*(T - Tref) -g*sbeta*(S - Sref)

    if EOS == 'jmd':
        import jmd95
        import seawater
        if T is None:
            T = np.zeros(np.shape(S))
        if S is None:
            S = np.zeros(np.shape(T))
        rhoConst = 1000
        #Pressure needed in decibars
        press = seawater.pres(-Z,45)
        #Loop this routine along t and y to avoid running out of memory
        sp = np.shape(S)
        buoy = np.empty(np.shape(S))
        for ti in np.arange(0,sp[-1]):
            for rw in np.arange(0,sp[0]):
                buoy_fac = g/rhoConst
                b =-buoy_fac*(jmd95.densjmd95(np.squeeze(S[rw,:,:,ti]),
                np.squeeze(T[rw,:,:,ti]),press) - 1030)
                buoy[rw,:,:,ti] = b
    return buoy
def get_WW(files,
           get_data=True,
           get_dives=None,
           remove_seawater=False,
           VSF_dark=0):
    SB_files = np.sort(glob.glob(files))

    if get_dives is not None:
        SB_files = SB_files[get_dives.astype('int32')]

    lat = ()
    lon = ()
    t = ()
    sta = ()
    if get_data:
        T = ()
        S = ()
        z = ()
        VSF = ()
    for i in range(len(SB_files)):
        SB = readSB(SB_files[i], no_warn=True)
        lat += (get_startlat(SB), )
        lon += (get_startlon(SB), )
        t += (get_starttime(SB), )
        sta += (i, )

        if get_data:
            T += (np.array(SB.data['wt']), )
            S += (np.array(SB.data['sal']), )
            z += (np.array(SB.data['depth']), )
            if remove_seawater:
                VSF_sw = betasw_wetlabs(700, 20, 124, 41, T[-1], S[-1],
                                        sw.pres(z[-1], lat=50.5))
            else:
                VSF_sw = 0
            VSF += (np.array(SB.data['bbp700']) / (np.pi * 2 * 1.1) - VSF_sw -
                    VSF_dark, )
            # convert using chi factor for 124deg angle used here

    output = (np.array(t, dtype='object'), np.array(lat, dtype='object'),
              np.array(lon, dtype='object'), np.array(sta, dtype='object'))
    if get_data:
        output += (
            np.array(T, dtype='object'),
            np.array(S, dtype='object'),
            np.array(z, dtype='object'),
            np.array(VSF, dtype='object'),
        )

    return output
Esempio n. 17
0
def calc_atm_equil_methane_depth(temp, sal, fg, depth):
    ''' Calculate atmospheric equilibrium methane concentration
        Bunsen  -  the volume of gas (corrected to st.temp 
        and pressure) absorbed in a unit volume of water 
        at the measured temp when the part.pressure of the gas is 760 mm.
        
        Coefficients and bunsen equation are taken from the paper 
       'Solubility of Methane in Distilled Water and Seawater' 1972 
       Sachio Yamamoto,' James B. Alcauskas, and Thomas E. Crozier
    '''

    abs_temp = temp + 273.15  # Absoulte Temp Kelvins
    a1 = -67.1962
    a2 = 99.1624
    a3 = 27.9015
    b1 = -0.072909
    b2 = 0.041674
    b3 = -0.0064603
    #print (temp,sal,depth)
    ln_bunsen = a1 + a2 * (100. / abs_temp) + a3 * math.log(
        abs_temp / 100.) + (sal * (b1 + b2 * (abs_temp / 100.) + b3 *
                                   ((abs_temp / 100.)**2)))

    bunsen = math.e**ln_bunsen

    # p_tot - the total pressure (atm)
    try:
        import seawater as sw
        st_lat = 76.47
        p_dbar = sw.pres(depth, st_lat)  # dbars
        p_tot = 0.987 * p_dbar / 10.  # convert dbars to atm
    except ModuleNotFoundError:
        p_tot = 1 + depth / 10.3  # in atm

    # fg -  the mole fraction of gas (fG) in the dry atmosphere
    h = 100  # h is the relative humidity (percent)

    # p_vapor is vapor pressure of the solution (atm).
    p_vapor = calculate_vapor(temp, sal)

    # Equation (4) from Weisenburg 1979
    c = (bunsen * (p_tot - ((h / 100.) * p_vapor)) * fg * 44.6 * 10**6
         )  #(nanomoles)

    return c  #,bunsen
Esempio n. 18
0
def buoy_dgl(dgl,eos,alpha = None,sbeta = None, g = None, lat = None,
        Tref = None, Sref = None):
    """Calculate the buoyancy field for a structured array dgl"""
    import mit
    b_exists = mit.check_field(dgl,'b')
    if not b_exists:
        dgl = mit.add_field(dgl,'b')
    S_exists = mit.check_field(dgl,'s')
    T_exists = mit.check_field(dgl,'t')
    if eos == 'lin':
        alpha, sbeta, g, Tref, Sref = lin_eos_params(alpha,sbeta,g,lat,Tref,Sref)
        for rw in np.arange(0,len(dgl[0]['y'])):
            if T_exists and not S_exists:
                """Thermal contribution only"""
                dgl[0]['b'][rw,:,:,:] = g*alpha*(dgl[0]['t'][rw,:,:,:] - Tref)
            if S_exists and not T_exists:
                """Haline contribution only"""
                dgl[0]['b'][rw,:,:,:] = -g*sbeta*(dgl[0]['s'][rw,:,:,:] - Sref)
            if T_exists and S_exists:
                dgl[0]['b'][rw,:,:,:] = g*alpha*(dgl[0]['t'][rw,:,:,:] - Tref)
                -g*sbeta*(dgl[0]['s'][rw,:,:,:] - Sref)

    elif eos == 'jmd':
        g = 9.81
        import jmd95
        import seawater
        import mit
        if not T_exists:
            T = np.zeros(np.shape(dgl[0]['s']))
        if not S_exists:
            S = np.zeros(np.shape(dgl[0]['t']))
        rhoConst = 1000
        ylen, xlen, zlen, tlen = mit.dgl_dims(dgl)
        #Pressure needed in decibars
        press = seawater.pres(-dgl[0]['z'],lat = 45)
        buoy_fac = g/rhoConst
        #Loop this routine along t and y to avoid running out of memory
        for ti in np.arange(0,tlen):
            for rw in np.arange(0,ylen):
                dgl[0]['b'][rw,:,:,ti] =-buoy_fac*(jmd95.densjmd95(
                np.squeeze(dgl[0]['s'][rw,:,:,ti]),
                np.squeeze(dgl[0]['t'][rw,:,:,ti]),press) - 1030)
    return dgl
Esempio n. 19
0
def conv_v02():
    '''
    conv_v02
    
    Takes a v01 DB and converts it to a v02 DB.
    v02:
    - contains sigmaT data, as calculated by seawater package   
    '''
    global CTD_DAT, STANDARD_KEYS
    
    print( '> Converting to v02')
    print('> Appending calculated sigmaT values')
    for cast in CTD_DAT:
        P = SW.pres(cast['Depth'],cast['Latitude'])
        cast['sigmaT'] = SW.dens(cast['Salinity'],cast['Temperature'],P)-1000
        inds = ~np.isnan(cast['sigmaT'])
        cast['sigmaT'] = np.interp(np.arange(0,len(cast['sigmaT'])),np.arange(0,len(cast['sigmaT']))[inds],cast['sigmaT'][inds])
        
    print('> Complete')
Esempio n. 20
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()
## Get data from dives
data1 = func1(files1,get_dives=data1_loc[3][inds1])
data2 = func2(files2,get_dives=data2_loc[3][inds2])

## filter all data with median filters
good_inds_1 = [np.isfinite(np.array(T.astype('float32'))) & np.isfinite(np.array(S.astype('float32'))) & np.isfinite(np.array(b.astype('float32')))
               for T,S,b in zip(data1[4],data1[5],data1[7])]
if inst1 == 'BB2FLSG': # Seaglider VSF data is already filtered
    filtered_dep1 = [var[i] for var,i in zip(data1[6],good_inds_1)]
    filtered_VSF1 = [var[i] for var,i in zip(data1[7],good_inds_1)]
else:
    filtered_dep1 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data1[6],good_inds_1)]
    filtered_VSF1 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data1[7],good_inds_1)]
filtered_T1 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep1,data1[6],data1[4],good_inds_1)]
filtered_S1 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep1,data1[6],data1[5],good_inds_1)]
filtered_dens1 = [sw.pden(S,T,sw.pres(z,lat=CENTRAL_LAT))
                  for T,S,z in zip(filtered_T1,filtered_S1,filtered_dep1)]

good_inds_2 = [np.isfinite(T.astype('float32')) & np.isfinite(S.astype('float32')) & np.isfinite(b.astype('float32'))
               for T,S,b in zip(data2[4],data2[5],data2[7])]
if inst2 == 'BB2FLSG': # Seaglider VSF data is already filtered
    filtered_dep2 = [var[i] for var,i in zip(data2[6],good_inds_2)]
    filtered_VSF2 = [var[i] for var,i in zip(data2[7],good_inds_2)]
else:
    filtered_dep2 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data2[6],good_inds_2)]
    filtered_VSF2 = [get_data.median_filter(var.astype('float32')[i]) for var,i in zip(data2[7],good_inds_2)]
filtered_T2 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep2,data2[6],data2[4],good_inds_2)]
filtered_S2 = [np.interp(fd,d.astype('float32')[i],var.astype('float32')[i]) for fd,d,var,i in zip(filtered_dep2,data2[6],data2[5],good_inds_2)]
filtered_dens2 = [sw.pden(S,T,sw.pres(z,lat=CENTRAL_LAT))
                  for T,S,z in zip(filtered_T2,filtered_S2,filtered_dep2)]
Esempio n. 22
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
Esempio n. 23
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()
Esempio n. 24
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
Esempio n. 25
0
def do_load_dataloop(mesh, data, fname_list, var_list, sel_timeidx, sel_levidx, \
                   nti, nsi, ndi, do_tmean, do_output,):    
    if ndi!=0:
        
        #_______________________________________________________________________
        # initialize data.value array
        if do_tmean:
            data.value = np.zeros((nsi,len(sel_levidx)),dtype='float32')
            if len(fname_list[1]): data.value2 = np.zeros((nsi,len(sel_levidx)),dtype='float32')
            if len(fname_list[1]): data.value3 = np.zeros((nsi,len(sel_levidx)),dtype='float32')
        else:
            data.value = np.zeros((nti,nsi,len(sel_levidx)))
            if len(fname_list[1]): data.value2 = np.zeros((nti*len(fname_list),nsi,len(sel_levidx)),dtype='float32')
            if len(fname_list[1]): data.value3 = np.zeros((nti*len(fname_list),nsi,len(sel_levidx)),dtype='float32')
        
        #_______________________________________________________________________
        # select time+depth range + compute time mean
        for it in range(0,len(fname_list[0])):
            if do_tmean:
                data.value = data.value + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx].mean(axis=0)
                if len(fname_list[1]): data.value2 = data.value2 + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx].mean(axis=0)
                if len(fname_list[2]): data.value3 = data.value3 + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx].mean(axis=0)
            else:
                t_idx = sel_timeidx+nti*it
                data.value[t_idx,:,:] = data.value[t_idx,:,:] + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx]
                if len(fname_list[1]): data.value2[t_idx,:,:] = data.value2[t_idx,:,:] + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx]
                if len(fname_list[2]): data.value3[t_idx,:,:] = data.value3[t_idx,:,:] + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx]
        
        # divide by loaded file number --> to final time mean
        if do_tmean:
            data.value = data.value/len(fname_list[0]) 
            if len(fname_list[1]): data.value2 = data.value2/len(fname_list[1]) 
            if len(fname_list[2]): data.value3 = data.value2/len(fname_list[2])
                
        #_______________________________________________________________________
        # compute potential density & temperatur if selected
        if any(x in data.var for x in ['pdens','ptemp','sigma']):
            dep      = np.matlib.repmat(mesh.zmid[sel_levidx],nsi,1)
            lat      = np.matlib.repmat(mesh.nodes_2d_yg[0:mesh.n2dn],nsi,1).transpose()
            press    = sw.pres(dep,lat)
            press_ref= 0
            if   '0' in data.var : press_ref=0
            elif '1' in data.var : press_ref=1000
            elif '2' in data.var : press_ref=2000
            elif '3' in data.var : press_ref=3000
            elif '4' in data.var : press_ref=4000
            elif '5' in data.var : press_ref=5000
            if press_ref!=0: data.lname = '$\sigma_{'+str(int(press_ref/1000))+'}$ '+data.lname
            del dep,lat
            if do_tmean:
                if 'ptemp' in data.var: data.value = sw.ptmp(data.value2,data.value,press,press_ref)
                if any(x in data.var for x in ['pdens','sigma']): data.value = sw.pden(data.value2,data.value,press,press_ref)-1000.025 
            else:
                for it in range(0,data.value.shape[0]):
                    if 'ptemp' in data.var: data.value[it,:,:] = sw.ptmp(data.value2[it,:,:],data.value[it,:,:],press,press_ref)
                    if any(x in data.var for x in ['pdens','sigma']): data.value[it,:,:] = sw.pden(data.value2[it,:,:],data.value[it,:,:],press,press_ref)-1000.025 
            fname_list[1]=[]
            
        #_______________________________________________________________________    
        # compute depth mean + linear interpolation to selected depth levels
        data.value = do_zinterp(mesh, data.value, data.depth, ndi, nsi, sel_levidx,do_output)
        if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, nsi, sel_levidx,do_output)
        if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, nsi, sel_levidx,do_output)
        
    # 2D data:
    else: 
        #_______________________________________________________________________
        # initialize data.value array
        if do_tmean:
            data.value = np.zeros((nsi,))
            if len(fname_list[1]): data.value2 = np.zeros((nsi,))
            if len(fname_list[1]): data.value3 = np.zeros((nsi,))
        else:
            data.value = np.zeros((nti,nsi))
            if len(fname_list[1]): data.value2 = np.zeros((nti*len(fname_list),nsi))
            if len(fname_list[1]): data.value3 = np.zeros((nti*len(fname_list),nsi))
        
        #_______________________________________________________________________
        # select time+depth range + compute time mean
        for it in range(0,len(fname_list[0])):
            if do_tmean:
                data.value = data.value + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:].mean(axis=0)
                if len(fname_list[1]): data.value2 = data.value2 + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:].mean(axis=0)
                if len(fname_list[2]): data.value3 = data.value3 + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:].mean(axis=0)
            else:
                t_idx = sel_timeidx+nti*it
                data.value[t_idx,:] = data.value[t_idx,:] + Dataset(fname_list[0][it],'r').variables[var_list[0]][sel_timeidx,:]
                if len(fname_list[1]): data.value2[t_idx,:] = data.value2[t_idx,:] + Dataset(fname_list[1][it],'r').variables[var_list[1]][sel_timeidx,:]
                if len(fname_list[2]): data.value3[t_idx,:] = data.value3[t_idx,:] + Dataset(fname_list[2][it],'r').variables[var_list[2]][sel_timeidx,:]
                
        # divide by loaded file number --> to final time mean
        if do_tmean:
            data.value = data.value/len(fname_list[0]) 
            if len(fname_list[1]): data.value2 = data.value2/len(fname_list[1]) 
            if len(fname_list[2]): data.value3 = data.value2/len(fname_list[2])
    
    return(data) 
        for var, i in zip(data1[7], good_inds_1)
    ]
filtered_T1 = [
    np.interp(fd,
              d.astype('float32')[i],
              var.astype('float32')[i])
    for fd, d, var, i in zip(filtered_dep1, data1[6], data1[4], good_inds_1)
]
filtered_S1 = [
    np.interp(fd,
              d.astype('float32')[i],
              var.astype('float32')[i])
    for fd, d, var, i in zip(filtered_dep1, data1[6], data1[5], good_inds_1)
]
filtered_dens1 = [
    sw.pden(S, T, sw.pres(z, lat=CENTRAL_LAT))
    for T, S, z in zip(filtered_T1, filtered_S1, filtered_dep1)
]

good_inds_2 = [
    np.isfinite(T.astype('float32')) & np.isfinite(S.astype('float32'))
    & np.isfinite(b.astype('float32'))
    for T, S, b in zip(data2[4], data2[5], data2[7])
]
if inst2 == 'BB2FLSG':  # Seaglider VSF data is already filtered
    filtered_dep2 = [var[i] for var, i in zip(data2[6], good_inds_2)]
    filtered_VSF2 = [var[i] for var, i in zip(data2[7], good_inds_2)]
else:
    filtered_dep2 = [
        get_data.median_filter(var.astype('float32')[i])
        for var, i in zip(data2[6], good_inds_2)
 fn = fn_list[tt]
 ds1 = nc.Dataset(fn)
 if np.mod(tt, 10) == 0:  # print update to console every 10th file
     print('tt = ' + str(tt) + '/' + str(NT) + ' ' + str(datetime.now()))
     sys.stdout.flush()
 if model_type == 'Kurapov':
     # Kurapov variable structure: [time,layer,lon,lat]
     import seawater
     zeta = ds1['zeta'][0, :, :].squeeze()
     if tt == 0:
         bp_arr = (0 * zeta) * np.ones((NT, 1, 1))
     salt = ds1['salt'][0, :, :, :].squeeze()
     ptemp = ds1['temp'][0, :, :, :].squeeze()  # potential temperature
     z_r = zrfun.get_z(G['h'][:, :], 0 * zeta, S, only_rho=True)
     z_w = zrfun.get_z(G['h'][:, :], zeta, S, only_w=True)
     p = seawater.pres(-z_r, G['lat_rho'][0, 0])
     temp = seawater.temp(salt, ptemp, p)  # in situ temperature
     # for some reason seawater.dens throws errors if we don't do this
     sd = salt.data
     td = temp.data
     prd = p.data
     sd[salt.mask] = np.nan
     td[salt.mask] = np.nan
     prd[salt.mask] = np.nan
     prho = seawater.pden(sd, td, prd)  # potential density
     prho = np.ma.masked_where(salt.mask, prho)
     rho = seawater.dens(
         sd, td,
         prd)  # in-situ density from salinity, temperature, and pressure
     rho = np.ma.masked_where(salt.mask, rho)
     DZ = np.diff(z_w, axis=0)
Esempio n. 28
0
def get_layer(fn, NZ=-1, aa=[], print_info=False):
    # function to extract and process fields from a history file
    # returning a dict of arrays that can be passed to CO2SYS.m
    
    # default is to get full surface field
    
    ds = nc.Dataset(fn)
    G, S, T = zrfun.get_basic_info(fn)
    if len(aa) == 4:
        # find indices that encompass region aa
        i0 = zfun.find_nearest_ind(G['lon_rho'][0,:], aa[0]) - 1
        i1 = zfun.find_nearest_ind(G['lon_rho'][0,:], aa[1]) + 2
        j0 = zfun.find_nearest_ind(G['lat_rho'][:,0], aa[2]) - 1
        j1 = zfun.find_nearest_ind(G['lat_rho'][:,0], aa[3]) + 2
    else:
        # full region
        i0 = 0; j0 = 0
        j1, i1 = G['lon_rho'].shape
        i1 += 1; j1 += 1
        
    plon = G['lon_psi'][j0:j1-1, i0:i1-1]
    plat = G['lat_psi'][j0:j1-1, i0:i1-1]

    # extract needed info from history file
    v_dict = dict()
    if print_info:
        print('\nINPUT Variable Info:')
    for vn in ['alkalinity', 'TIC', 'salt', 'temp','rho']:
        v = ds[vn][0,NZ, j0:j1, i0:i1]
        v = fillit(v)
        v_dict[vn] = v
        if print_info:
            name = ds[vn].long_name
            try:
                units = ds[vn].units
            except AttributeError:
                units = ''
            vmax = np.nanmax(v)
            vmin = np.nanmin(v)
            v_dict[vn] = v
            print('%25s (%25s) max = %6.1f min = %6.1f' %
                (name, units, vmax, vmin))
                
    # create depth, pressure, and in situ temperature
    h = ds['h'][j0:j1, i0:i1]
    h = fillit(h)
    lat = G['lat_rho'][j0:j1, i0:i1]
    z_rho = zrfun.get_z(h, 0*h, S, only_rho=True)
    depth = -z_rho[NZ, :, :].squeeze()
    pres = sw.pres(depth, lat)
    v_dict['pres'] = pres
    # assume potential temperature is close enough
    # temp = sw.ptmp(v_dict['salt'], v_dict['temp'], 0, v_dict['pres'])
    # v_dict['temp'] = temp
    
    # convert from umol/L to umol/kg using in situ dentity
    v_dict['alkalinity'] = 1000 * v_dict['alkalinity'] / (v_dict['rho'] + 1000)
    v_dict['TIC'] = 1000 * v_dict['TIC'] / (v_dict['rho'] + 1000)
    
    # clean up
    v_dict.pop('rho') # no longer needed, so don't pass to worker
    ds.close()
    
    return v_dict, plon, plat
Esempio n. 29
0
def do_load_mfdata(mesh, data, fname_list, var_list, sel_timeidx, sel_levidx, \
                   nsi, ndi, do_tmean, do_output,):    
    if ndi!=0:
        
        #_______________________________________________________________________
        # select time+depth range + compute time mean
        if do_tmean:
            data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx].mean(axis=0)
            if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx].mean(axis=0)
            if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx].mean(axis=0)
        else:
            data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:,sel_levidx]
            if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:,sel_levidx]
            if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:,sel_levidx]
        
        #_______________________________________________________________________
        # compute potential density & temperatur if selected
        if any(x in data.var for x in ['pdens','ptemp','sigma']):
            dep   = np.matlib.repmat(mesh.zmid[sel_levidx],nsi,1)
            lat   = np.matlib.repmat(mesh.nodes_2d_yg[0:mesh.n2dn],len(sel_levidx),1).transpose()
            press = sw.pres(dep,lat)
            press_ref = 0
            if   '0' in data.var : press_ref=0
            elif '1' in data.var : press_ref=1000
            elif '2' in data.var : press_ref=2000
            elif '3' in data.var : press_ref=3000
            elif '4' in data.var : press_ref=4000
            elif '5' in data.var : press_ref=5000
            if 'sigma' in data.var: data.lname = '$\sigma_{'+str(int(press_ref/1000))+'}$ '+data.lname
            del dep,lat
            if do_tmean:
                if 'ptemp' in data.var: data.value = sw.ptmp(data.value2,data.value,press,press_ref)
                if any(x in data.var for x in ['pdens','sigma']): data.value = sw.pden(data.value2,data.value,press,press_ref)-1000.025 
            else:
                for it in range(0,data.value.shape[0]):
                    if 'ptemp' in data.var: data.value[it,:,:] = sw.ptmp(data.value2[it,:,:],data.value[it,:,:],press,press_ref)
                    if any(x in data.var for x in ['pdens','sigma']): data.value[it,:,:] = sw.pden(data.value2[it,:,:],data.value[it,:,:],press,press_ref)-1000.025 
            fname_list[1]=[]
            
        #_______________________________________________________________________    
        # compute depth mean + linear interpolation to selected depth levels
        if do_tmean:
            data.value = do_zinterp(mesh, data.value, data.depth, ndi, data.value.shape[0], sel_levidx,do_output)
            if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, data.value2.shape[0], sel_levidx,do_output)
            if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, data.value3.shape[0], sel_levidx,do_output)
        else:
            data.value = do_zinterp(mesh, data.value, data.depth, ndi, data.value.shape[1], sel_levidx,do_output)
            if len(fname_list[1]): data.value2 = do_zinterp(mesh, data.value2, data.depth, ndi, data.value2.shape[1], sel_levidx,do_output)
            if len(fname_list[2]): data.value3 = do_zinterp(mesh, data.value3, data.depth, ndi, data.value3.shape[1], sel_levidx,do_output)
        
    # 2D data:
    else: 
        
        if do_tmean:
            data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:].mean(axis=0)
            if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:].mean(axis=0)
            if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:].mean(axis=0)
        else:
            data.value = MFDataset(fname_list[0],'r').variables[var_list[0]][sel_timeidx,:]
            if len(fname_list[1]): data.value2 = MFDataset(fname_list[1],'r').variables[var_list[1]][sel_timeidx,:]
            if len(fname_list[2]): data.value3 = MFDataset(fname_list[2],'r').variables[var_list[2]][sel_timeidx,:]
    
    # kickout single array dimension
    data.value = data.value.squeeze()
    if len(fname_list[1]): data.value2 = data.value2.squeeze()
    if len(fname_list[2]): data.value3 = data.value3.squeeze()
    
    return(data) 
def get_FLBB_SR(files,
                get_data=True,
                get_dives=None,
                remove_seawater=True,
                VSF_dark=0):
    SB_files = np.sort(glob.glob(files))
    if get_dives is not None:
        # first get all stations
        all_stations = np.empty(len(SB_files))
        for i in range(len(SB_files)):
            SB = readSB(SB_files[i], no_warn=True)
            # 'calibration_file' is more accurate than 'station' var
            all_stations[i] = int(SB.headers['calibration_files'][7:10])
        # now re-make SB_files list to be one for each station
        # (need to do it this way in case stations are duplicated)
        SB_files = np.array([
            SB_files[np.where(all_stations == station)[0][0]]
            for station in get_dives
        ])

    lat = ()
    lon = ()
    t = ()
    sta = ()
    if get_data:
        T = ()
        S = ()
        z = ()
        VSF = ()
    for i in range(len(SB_files)):
        SB = readSB(SB_files[i], no_warn=True)
        # 'calibration_file' is more accurate than 'station' var
        station = int(SB.headers['calibration_files'][7:10])
        lat += (get_startlat(SB), )
        lon += (get_startlon(SB), )
        t += (get_starttime(SB), )
        sta += (station, )

        if get_data:
            T += (np.array(SB.data['wt']), )
            S += (np.array(SB.data['sal']), )
            z += (np.array(SB.data['depth']), )
            if remove_seawater:
                #VSF_sw = betasw_HZP2019(700,142,T[-1],S[-1],sw.pres(z[-1],lat=50.5))[0].squeeze()
                VSF_sw = betasw_wetlabs(700, 20, 142, 42, T[-1], S[-1],
                                        sw.pres(z[-1], lat=50.5))
            else:
                VSF_sw = 0
            VSF += ((np.array(SB.data['bbp']) / (2 * np.pi * 1.17) - VSF_dark -
                     VSF_sw), )
            # convert using chi factor for 142deg angle used here (1.17)
            # (note this is different than that found in Zhang et al., 2021)

    t = np.array(t, dtype='object')
    lat = np.array(lat, dtype='object')
    lon = np.array(lon, dtype='object')
    sta = np.array(sta, dtype='object')
    if get_data:
        T = np.array(T, dtype='object')
        S = np.array(S, dtype='object')
        z = np.array(z, dtype='object')
        VSF = np.array(VSF, dtype='object')
    output = (t, lat, lon, sta)
    if get_data:
        output += (T, S, z, VSF)

    return output
Esempio n. 31
0
          z0  =(hc*s_r[k]+Cs_r[k]*h[i,j])/(hc+h[i,j]);
          z[k]=zeta+(zeta+h[i,j])*z0;

          z0   =(hc*s_w[k]+Cs_w[k]*h[i,j])/(hc+h[i,j]);
          zw[k]=zeta+(zeta+h[i,j])*z0;

        # Add last depth for zw
        z0   =(hc*s_w[N]+Cs_w[N]*h[i,j])/(hc+h[i,j]);
        zw[N]=zeta+(zeta+h[i,j])*z0;

        Hz = abs(zw[1:N+1]-zw[0:N])
  
        #------------------------------------------------------------------------
        # Calculate various seawater properties
        #------------------------------------------------------------------------
        pres=sw.pres(z*-1,lat[i,j])

        #-----------------------------------------------------------------
        # Calculate depth of the pycnocline
        #----------------------------------------------------------------
        dens=sw.dens(salt,temp,pres)-1000.
        drdZ = abs(dens[1:N]-dens[0:N-1])/abs(z[1:N]-z[0:N-1])
        drdZ_ind=np.argmax(drdZ)
        
        #-----------------------------------------------------------------
        # Average residence time above the pycnocline
        #----------------------------------------------------------------
        rtime02[tdim,i,j]=sum(   Hz[drdZ_ind::]*rtime[drdZ_ind::])/\
                              abs(z[drdZ_ind])
      else:
        rtime02[tdim,i,j]=np.nan
Esempio n. 32
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()
Esempio n. 33
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)

  #------------------------------------------------------------------------
  # Find layer with max dT/d(sigma)
  #------------------------------------------------------------------------
  dT=np.zeros(shape=(N-1))
  for i in range(0,M):
    for j in range(0,L):
      
      # Cell is over the water
      if mask[i,j]>0:
        #-----------------------------------------------------------------
        # Load in temp,salt, age, residence time
        #----------------------------------------------------------------
        temp  =input_data.variables['temp'       ][tdim,:,i,j]
        salt  =input_data.variables['salt'       ][tdim,:,i,j]
Esempio n. 34
0
def _plot_fvcomfile():

    if (w.config['fvcom']['shiftlonTF'] == 'True'
            and w.fvcom['shifted'] == False):
        w.fvcom['lon'] = w.fvcom['lon'] - 360.0
        w.fvcom['trigrid'] = mplt.Triangulation(w.fvcom['lon'], w.fvcom['lat'],
                                                w.fvcom['nv'])
        w.fvcom['shifted'] = True
    elif (w.config['fvcom']['shiftlonTF'] == 'False'
          and w.fvcom['shifted'] == True):
        w.fvcom['lon'] = w.fvcom['lon'] + 360.0
        w.fvcom['trigrid'] = mplt.Triangulation(w.fvcom['lon'], w.fvcom['lat'],
                                                w.fvcom['nv'])
        w.fvcom['shifted'] = False

    if 'fvcom' not in w.FIGS:
        w.FIGS['fvcom'] = {}
    if not hasattr(w, 'cb'):
        w.cb = {}
    #print(w.fvcom['lon'][0],w.fvcom['lat'][0])

    state = True
    try:
        if w.fvcomplot in w.FIGS['fvcom']:
            w.FIGS['fvcom'][w.fvcomplot].remove()
            state = w.TF['fvcom']
    except:
        w.fvcomplot = ''

    if w.overmenu.get() != '':
        if w.overmenu.get() in w.fvcom['pable']:
            w.fvcomplot = w.overmenu.get()
    else:
        w.fvcomplot = w.FVCOMMenuVar.get()

    if w.etime != '':
        w.timeTF = True
        w.time = int(w.etime.get())
    else:
        w.timeTF = False
    if w.elvl != '':
        w.lvlTF = True
        w.lvl = int(w.elvl.get())
    else:
        w.lvlTF = False

    #print(w.fvcomplot)

    if w.fvcomplot == 'dhh':
        dname = 'dhh'
        if w.fvcomplot not in w.fvcom:
            w.fvcom = ut.get_dhh(w.fvcom)
    elif w.fvcomplot == 'sidelength':
        dname = 'sl'
        if w.fvcomplot not in w.fvcom:
            w.fvcom = ut.get_sidelength(w.fvcom)
    elif (w.fvcomplot == 'speed_da' and w.timeTF):
        dname = 'speed_da'
        w.fvcom['speed_da'] = np.sqrt(w.fvcom['ua'][w.time, :]**2 +
                                      w.fvcom['va'][w.time, :]**2)
    elif (w.fvcomplot == 'speed' and w.timeTF and w.lvlTF):
        dname = 'speed'
        w.fvcom['speed'] = np.sqrt(w.fvcom['u'][w.time, w.lvl, :]**2 +
                                   w.fvcom['v'][w.time, w.lvl, :]**2)
    elif (w.fvcomplot == 'vorticity_da' and w.timeTF):
        dname = 'field'
        i = w.time
        dudy = w.fvcom['a2u'][0,:]*w.fvcom['ua'][i,:]+w.fvcom['a2u'][1,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,0]] +\
                w.fvcom['a2u'][2,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,1]]+w.fvcom['a2u'][3,:]*w.fvcom['ua'][i,w.fvcom['nbe'][:,2]]
        dvdx = w.fvcom['a1u'][0,:]*w.fvcom['va'][i,:]+w.fvcom['a1u'][1,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,0]] +\
               w.fvcom['a1u'][2,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,1]]+w.fvcom['a1u'][3,:]*w.fvcom['va'][i,w.fvcom['nbe'][:,2]]
        w.fvcom[dname] = dvdx - dudy
    elif (w.fvcomplot == 'vorticity' and w.timeTF and w.lvlTF):
        dname = 'field'
        i = w.time
        layer = w.lvl
        dudy = w.fvcom['a2u'][0,:]*w.fvcom['u'][i,layer,:]+w.fvcom['a2u'][1,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,0]] +\
               w.fvcom['a2u'][2,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,1]]+w.fvcom['a2u'][3,:]*w.fvcom['u'][i,layer,w.fvcom['nbe'][:,2]]
        dvdx = w.fvcom['a1u'][0,:]*w.fvcom['v'][i,layer,:]+w.fvcom['a1u'][1,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,0]] +\
               w.fvcom['a1u'][2,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,1]]+w.fvcom['a1u'][3,:]*w.fvcom['v'][i,layer,w.fvcom['nbe'][:,2]]
        w.fvcom[dname] = dvdx - dudy
    elif (w.fvcomplot == 'density' and w.timeTF and w.lvlTF):
        dname = 'field'
        i = w.time
        layer = w.lvl
        pres = sw.pres(w.fvcom['h'] + w.fvcom['zeta'][i, :], w.fvcom['lat'])
        w.fvcom[dname] = sw.dens(w.fvcom['salinity'][i, layer, :],
                                 w.fvcom['temp'][i, layer, :], pres)
    else:
        dname = 'field'
        shp = np.shape(w.fvcom[w.fvcomplot])
        tTF = (len(w.fvcom['time']) in shp)
        lTF = (w.fvcom['dims']['siglev'] in shp) or (w.fvcom['dims']['siglay']
                                                     in shp)
        if (tTF == False and lTF == False):
            w.fvcom[dname] = w.fvcom[w.fvcomplot]
        elif (tTF == True and lTF == False):
            w.fvcom[dname] = w.fvcom[w.fvcomplot][w.time, :]
        else:
            w.fvcom[dname] = w.fvcom[w.fvcomplot][w.time, w.lvl, :]

    cmin, cmax = getcb(w.fvcom[dname])
    w.FIGS['fvcom'][w.fvcomplot] = w.ax.tripcolor(
        w.fvcom['trigrid'],
        w.fvcom[dname],
        vmin=cmin,
        vmax=cmax,
        visible=state,
        cmap=w.config['fvcom']['colormap'],
        zorder=int(w.config['fvcom']['zorder']))
    w.cb[w.fvcomplot] = w.figure.colorbar(w.FIGS['fvcom'][w.fvcomplot],
                                          cax=w.cax)

    w.figure.canvas.draw()

    return