예제 #1
0
def compute_potdens(ds, saltname='SALT', tempname='THETA'):
    import gsw
    """ compute the potential density
    """
    # compute the Conservative Temperature from the model's potential temperature
    temp = ds[tempname].transpose(*('time', 'k', 'face', 'j', 'i'))
    salt = ds[tempname].transpose(*('time', 'k', 'face', 'j', 'i'))
    CT = gsw.CT_from_pt(salt, temp)
    z, lat = xr.broadcast(ds['Z'], ds['YC'])
    z = z.transpose(*('k', 'face', 'j', 'i'))
    lat = lat.transpose(*('k', 'face', 'j', 'i'))
    # compute pressure from depth
    p = gsw.p_from_z(z, lat)
    # compute in-situ temperature
    T = gsw.t_from_CT(salt, CT, p)
    # compute potential density
    rho = gsw.pot_rho_t_exact(salt, T, p, 0.)
    # create new dataarray
    darho = xr.full_like(temp, 0.)
    darho = darho.load().chunk({'time': 1, 'face': 1})
    darho.name = 'RHO'
    darho.attrs['long_name'] = 'Potential Density ref at 0m'
    darho.attrs['standard_name'] = 'RHO'
    darho.attrs['units'] = 'kg/m3'
    darho.values = rho
    # filter special value
    darho = darho.where(darho > 1000)
    darho = darho.assign_coords(XC=ds['XC'], YC=ds['YC'], Z=ds['Z'])
    return darho
예제 #2
0
def _convert_TS_to_TEOS10(var_meta, sal, temp):
    """Convert Practical Salinity and potential temperature to Reference
       Salinity and Conservative Temperature using gsw functions.

    :arg var_meta: dictionary of metadata for salinity and temperature.
                   Must have keys vosaline and votemper, each with a sub
                   dictionary with keys long_name and units
    :type var_meta: dictionary of dictionaries

    :arg sal: salinity data
    :type sal: numpy array

    :arg temp: temperature daya
    :type temp: numpy array

    :returns: updated meta data, salinity and temperature"""
    # modify metadata
    new_meta = var_meta.copy()
    new_meta['vosaline']['long_name'] = 'Reference Salinity'
    new_meta['vosaline']['units'] = 'g/kg'
    new_meta['votemper']['long_name'] = 'Conservative Temperature'
    # Convert salinity from practical to reference salinity
    sal_ref = gsw.SR_from_SP(sal[:])
    # Convert temperature from potential to conservative
    temp_cons = gsw.CT_from_pt(sal_ref[:], temp[:])

    return new_meta, sal_ref, temp_cons
예제 #3
0
def tsdiagram(
    salt,
    temp,
    color=None,
    size=None,
    lon=None,
    lat=None,
    pressure=None,
    convert_teos10=True,
    ts_kwargs={},
    ax=None,
    fig=None,
    draw_density_contours=True,
    draw_cbar=True,
    add_labels=True,
    **kwargs,
):
    if ax is None:
        ax = plt.gca()

    if fig is None:
        fig = plt.gcf()

    if convert_teos10:
        temp_label = "Conservative Temperature [$^{\circ}C$]"
        salt_label = "Absolute Salinity [$g/kg$]"
        if any([a is None for a in [lon, lat, pressure]]):
            raise ValueError(
                "when converting to teos10 variables, \
                             input for lon, lat and pressure is needed"
            )
        else:
            salt = gsw.SA_from_SP(salt, pressure, lon, lat)
            temp = gsw.CT_from_pt(salt, temp)
    else:
        temp_label = "Potential Temperature [$^{\circ}C$]"
        salt_label = "Practical Salinity [$g/kg$]"

    if add_labels:
        ax.set_xlabel(salt_label)
        ax.set_ylabel(temp_label)

    scatter_kw_defaults = dict(s=size, c=color)
    scatter_kw_defaults.update(kwargs)
    s = ax.scatter(salt, temp, **scatter_kw_defaults)
    if draw_density_contours:
        draw_dens_contours_teos10(ax=ax, **ts_kwargs)
    if draw_cbar and color is not None:
        if isinstance(color, str) or isinstance(color, tuple):
            pass
        elif (
            isinstance(color, list)
            or isinstance(color, np.ndarray)
            or isinstance(color, xr.DataArray)
        ):
            fig.colorbar(s, ax=ax)
        else:
            raise RuntimeError("`color` not recognized. %s" % type(color))
    return s
예제 #4
0
def potential_to_in_situ_temperature(dsPotTemp, dsSalin):
    z = dsPotTemp.z.values
    lat = numpy.maximum(dsPotTemp.lat.values, -80.)
    lon = dsPotTemp.lon.values

    if len(lat.shape) == 1:
        lon, lat = numpy.meshgrid(lon, lat)

    nz = len(z)
    ny, nx = lat.shape

    if 'time' in dsPotTemp.dims:
        nt = dsPotTemp.sizes['time']
        T = numpy.nan * numpy.ones((nt, nz, ny, nx))
        for zIndex in range(nz):
            pressure = gsw.p_from_z(z[zIndex], lat)
            for tIndex in range(nt):
                pt = dsPotTemp.temperature[tIndex, zIndex, :, :].values
                salin = dsSalin.salinity[tIndex, zIndex, :, :].values
                mask = numpy.logical_and(numpy.isfinite(pt),
                                         numpy.isfinite(salin))
                SA = gsw.SA_from_SP(salin[mask], pressure[mask], lon[mask],
                                    lat[mask])
                TSlice = T[tIndex, zIndex, :, :]
                CT = gsw.CT_from_pt(SA, pt[mask])
                TSlice[mask] = gsw.t_from_CT(SA, CT, pressure[mask])
                T[tIndex, zIndex, :, :] = TSlice
    else:
        T = numpy.nan * numpy.ones((nz, ny, nx))
        for zIndex in range(nz):
            pressure = gsw.p_from_z(z[zIndex], lat)
            pt = dsPotTemp.temperature[zIndex, :, :].values
            salin = dsSalin.salinity[zIndex, :, :].values
            mask = numpy.logical_and(numpy.isfinite(pt), numpy.isfinite(salin))
            SA = gsw.SA_from_SP(salin[mask], pressure[mask], lon[mask],
                                lat[mask])
            TSlice = T[zIndex, :, :]
            CT = gsw.CT_from_pt(SA, pt[mask])
            TSlice[mask] = gsw.t_from_CT(SA, CT, pressure[mask])
            T[zIndex, :, :] = TSlice

    dsTemp = dsPotTemp.drop('temperature')
    dsTemp['temperature'] = (dsPotTemp.temperature.dims, T)
    dsTemp['temperature'].attrs = dsPotTemp.temperature.attrs

    return dsTemp
def compute_pot_density(prefix, inGridName, inDir):
    config = MpasAnalysisConfigParser()
    config.read('mpas_analysis/config.default')

    outDescriptor = get_comparison_descriptor(config, 'antarctic')
    outGridName = outDescriptor.meshName
    description = 'Monthly potential density climatologies from ' \
                  '2005-2010 average of the Southern Ocean State ' \
                  'Estimate (SOSE)'
    botDescription = 'Monthly potential density climatologies at sea ' \
                     'floor from 2005-2010 average from SOSE'

    for gridName in [inGridName, outGridName]:
        outFileName = '{}_pot_den_{}.nc'.format(prefix, gridName)
        TFileName = '{}_pot_temp_{}.nc'.format(prefix, gridName)
        SFileName = '{}_salinity_{}.nc'.format(prefix, gridName)
        if not os.path.exists(outFileName):
            with xarray.open_dataset(TFileName) as dsT:
                with xarray.open_dataset(SFileName) as dsS:
                    dsPotDensity = dsT.drop(['theta', 'botTheta'])

                    lat, lon, z = xarray.broadcast(dsS.lat, dsS.lon, dsS.z)
                    pressure = gsw.p_from_z(z.values, lat.values)
                    SA = gsw.SA_from_SP(dsS.salinity.values, pressure,
                                        lon.values, lat.values)
                    CT = gsw.CT_from_pt(SA, dsT.theta.values)
                    dsPotDensity['potentialDensity'] = (dsS.salinity.dims,
                                                        gsw.rho(SA, CT, 0.))
                    dsPotDensity.potentialDensity.attrs['units'] = \
                        'kg m$^{-3}$'
                    dsPotDensity.potentialDensity.attrs['description'] = \
                        description

                    lat, lon, z = xarray.broadcast(dsS.lat, dsS.lon, dsS.zBot)
                    pressure = gsw.p_from_z(z.values, lat.values)
                    SA = gsw.SA_from_SP(dsS.botSalinity.values, pressure,
                                        lon.values, lat.values)
                    CT = gsw.CT_from_pt(SA, dsT.botTheta.values)
                    dsPotDensity['botPotentialDensity'] = \
                        (dsS.botSalinity.dims, gsw.rho(SA, CT, 0.))
                    dsPotDensity.botPotentialDensity.attrs['units'] = \
                        'kg m$^{-3}$'
                    dsPotDensity.botPotentialDensity.attrs['description'] = \
                        botDescription

                    write_netcdf(dsPotDensity, outFileName)
예제 #6
0
파일: utils.py 프로젝트: ponchama/COGNAC
def get_soundc(t, s, z, lon, lat):
    ''' compute sound velocity
    '''
    import gsw
    p = gsw.p_from_z(z, lat.mean())
    SA = gsw.SA_from_SP(s, p, lon, lat)
    CT = gsw.CT_from_pt(SA, t)
    c = gsw.sound_speed(s, t, p)
    # inputs are: SA (absolute salinity) and CT (conservative temperature)
    return c
def _main(args):
    """Run the command line program."""

    temperature_cube, temperature_history = gio.combine_files(args.temperature_file, args.temperature_var, checks=True)
    salinity_cube, salinity_history = gio.combine_files(args.salinity_file, 'sea_water_salinity', checks=True)
   
    assert 'c' in str(temperature_cube.units).lower(), "Input temperature units must be in celsius"
#    if not 'C' in str(bigthetao_cube.units):
#        bigthetao_cube.data = bigthetao_cube.data - 273.15
#        data_median = np.ma.median(bigthetao_cube.data)
#        assert data_median < 100
#        assert data_median > -10
#        bigthetao_cube.units = 'C'

    target_shape = temperature_cube.shape[1:]
    depth = temperature_cube.coord('depth').points * -1
    broadcast_depth = uconv.broadcast_array(depth, 0, target_shape)
    broadcast_longitude = uconv.broadcast_array(temperature_cube.coord('longitude').points, [1, 2], target_shape)
    broadcast_latitude = uconv.broadcast_array(temperature_cube.coord('latitude').points, [1, 2], target_shape)
    pressure = gsw.p_from_z(broadcast_depth, broadcast_latitude)

    absolute_salinity = gsw.SA_from_SP(salinity_cube.data, pressure, broadcast_longitude, broadcast_latitude)
    if args.temperature_var == 'sea_water_conservative_temperature':
        conservative_temperature = temperature_cube.data
    elif args.temperature_var == 'sea_water_potential_temperature':  
        conservative_temperature = gsw.CT_from_pt(absolute_salinity, temperature_cube.data)
    else:
        raise ValueError('Invalid temperature variable')

    if args.coefficient == 'alpha':
        coefficient_data = gsw.alpha(absolute_salinity, conservative_temperature, pressure)
        var_name = 'alpha'
        standard_name = 'thermal_expansion_coefficient'
        long_name = 'thermal expansion coefficient'
        units = '1/K'
    elif args.coefficient == 'beta':
        coefficient_data = gsw.beta(absolute_salinity, conservative_temperature, pressure)
        var_name = 'beta'
        standard_name = 'saline_contraction_coefficient'
        long_name = 'saline contraction coefficient'
        units = 'kg/g'
    else:
        raise ValueError('Coefficient must be alpha or beta')

    iris.std_names.STD_NAMES[standard_name] = {'canonical_units': units}
    coefficient_cube = temperature_cube.copy()
    coefficient_cube.data = coefficient_data
    coefficient_cube.standard_name = standard_name    
    coefficient_cube.long_name = long_name
    coefficient_cube.var_name = var_name
    coefficient_cube.units = units

    coefficient_cube.attributes['history'] = cmdprov.new_log(git_repo=repo_dir)
    iris.save(coefficient_cube, args.outfile)
예제 #8
0
def add_SA_CT_PT(xray):
    if 'PRES' in list(xray.data_vars):
        PRES_out = xray['PRES']
    else:
        PRES_out = -gsw.p_from_z(xray['DEPTH'])
    SA_out = gsw.SA_from_SP(xray['PSAL'], PRES_out, xray.LONGITUDE,
                            xray.LATITUDE)
    if 'PTMP' in list(xray.data_vars):
        PT_out = xray['PTMP']
    else:
        PT_out = gsw.pt0_from_t(SA_out, xray['TEMP'], PRES_out)
    CT_out = gsw.CT_from_pt(SA_out, PT_out)
    PD_out = gsw.sigma0(SA_out, CT_out)
    xray['ASAL'] = (('TIME', 'DEPTH'), SA_out)
    xray['PTMP'] = (('TIME', 'DEPTH'), PT_out)
    xray['CTMP'] = (('TIME', 'DEPTH'), CT_out)
    xray['PDEN'] = (('TIME', 'DEPTH'), PD_out)
예제 #9
0
    def __init__(self, sals, temps, pres, gamma, lat, lon):
        ##id of profiles plus info
        tempunit = "insitu"
        salunit = "practical"
        if tempunit not in ["insitu", "conservative", "potential"]:
            raise ValueError("This temperature unit is not supported")
        if salunit not in ["practical", "absolute", "insitu"]:
            raise ValueError("This salinity unit is not supported")
        self.lat = lat
        self.lon = lon
        nanmask = ~np.isnan(temps)
        nanmask = np.logical_and(~np.isnan(sals), nanmask)
        nanmask = np.logical_and(~np.isnan(pres), nanmask)
        nanmask = np.logical_and(~np.isnan(gamma), nanmask)

        #Temerature Salinity and Pressure
        self.temps = np.asarray(temps)[nanmask]
        self.sals = np.asarray(sals)[nanmask]
        self.pres = np.asarray(np.abs(pres))[nanmask]
        self.gamma = np.asarray(gamma)[nanmask]

        if salunit == "practical":
            self.sals = gsw.SA_from_SP(self.sals, self.pres, self.lon,
                                       self.lat)

        if tempunit == "potential":
            self.temps = gsw.CT_from_pt(self.sals, self.temps)

        if tempunit == "insitu":
            self.temps = gsw.CT_from_t(self.sals, self.temps,
                                       np.abs(self.pres))

        s = np.argsort(self.pres)
        self.temps = self.temps[s]
        self.sals = self.sals[s]
        self.pres = self.pres[s]
        self.gamma = self.gamma[s]
        ##Interpolated Temperature, Salinity, and Pressure
        self.itemps = []
        self.isals = []
        self.ipres = []
        self.igamma = []
        self.idensities = []
        self.neutraldepth = {}
        self.interpolate()
예제 #10
0
파일: geostrophy.py 프로젝트: NCAR/metric
def teos10_insitu_dens(t, s, z, lat, lon):
    """
    Computes the insitu density from potential temperature and salinity using the
    Thermodynamic Equation of Seawater 2010 (TEOS-10; IOC, SCOR and IAPSO, 2010).
    http://www.teos-10.org/pubs/TEOS-10_Manual.pdf

    """

    depth = np.ones_like(t) * z[None, :, None]
    lat = np.ones_like(t) * lat[None, None, :]
    lon = np.ones_like(t) * lon[None, None, :]

    p = gsw.p_from_z(-depth, lat)
    SA = gsw.SA_from_SP(s, p, lon, lat)
    CT = gsw.CT_from_pt(SA, t)
    rho = gsw.rho(SA, CT, p)

    return rho
#GODAS SAL
df = EcoFOCI_netCDF(godas_sal)
global_atts = df.get_global_atts()
vars_dic = df.get_vars()
gd_sal = df.ncreadfile_dic()
df.close()

#ABS Sal f(sal, pres, lat, lon)
#pressure needs to be determined from depth

ABS_SA = np.ones_like(gd_sal['salt'])
CONS_T = np.ones_like(gd_sal['salt'])
for time_ind, month in enumerate(gd_sal['time']):
    print time_ind
    for level_ind, level in enumerate(gd_sal['level']):
        print level
        for lat_ind, lat in enumerate(gd_sal['lat']):
            if lat_ind % 100 == 0:
                print "{0} of {1}".format(lat_ind, ABS_SA.shape[2])
            press = gsw.p_from_z(-1.0 * level, lat)
            for lon_ind, lon in enumerate(gd_sal['lon']):
                if lon_ind % 100 == 0:
                    print "{0} of {1}".format(lon_ind, ABS_SA.shape[3])
                ABS_SA[time_ind, level_ind, lat_ind, lon_ind] = \
                 gsw.SA_from_SP(gd_sal['salt'][time_ind,level_ind,
                     lat_ind,lon_ind], press,lat,lon)
                CONS_T[time_ind, level_ind, lat_ind, lon_ind] = \
                 gsw.CT_from_pt(ABS_SA[time_ind, level_ind, lat_ind, lon_ind],
                     gd_ptmp['pottmp'][time_ind,level_ind,
                     lat_ind,lon_ind])
    def construct_density(self, EOS='EOS10'):
        '''
            Constructs the in-situ density using the salinity, temperture and 
            depth_0 fields and adds a density attribute to the t-grid dataset 
            
            Requirements: The supplied t-grid dataset must contain the 
            Practical Salinity and the Potential Temperature variables. The depth_0
            field must also be supplied. The GSW package is used to calculate
            The Absolute Pressure, Absolute Salinity and Conservate Temperature.
            
            Note that currently density can only be constructed using the EOS10
            equation of state.

        Parameters
        ----------
        EOS : equation of state, optional
            DESCRIPTION. The default is 'EOS10'.


        Returns
        -------
        None.
        adds attribute NEMO.dataset.density

        '''
        debug(
            f"Constructing in-situ density for {get_slug(self)} with EOS \"{EOS}\""
        )
        try:
            if EOS != 'EOS10':
                raise ValueError(
                    str(self) + ': Density calculation for ' + EOS +
                    ' not implemented.')
            if self.grid_ref != 't-grid':
                raise ValueError(
                    str(self) +
                    ': Density calculation can only be performed for a t-grid object,\
                                 the tracer grid for NEMO.')

            try:
                shape_ds = (self.dataset.t_dim.size, self.dataset.z_dim.size,
                            self.dataset.y_dim.size, self.dataset.x_dim.size)
                sal = self.dataset.salinity.to_masked_array()
                temp = self.dataset.temperature.to_masked_array()
            except AttributeError:
                shape_ds = (1, self.dataset.z_dim.size,
                            self.dataset.y_dim.size, self.dataset.x_dim.size)
                sal = self.dataset.salinity.to_masked_array()[np.newaxis, ...]
                temp = self.dataset.temperature.to_masked_array()[np.newaxis,
                                                                  ...]

            density = np.ma.zeros(shape_ds)

            s_levels = self.dataset.depth_0.to_masked_array()
            lat = self.dataset.latitude.values
            lon = self.dataset.longitude.values
            # Absolute Pressure
            pressure_absolute = np.ma.masked_invalid(
                gsw.p_from_z(-s_levels, lat))  # depth must be negative
            # Absolute Salinity
            sal_absolute = np.ma.masked_invalid(
                gsw.SA_from_SP(sal, pressure_absolute, lon, lat))
            sal_absolute = np.ma.masked_less(sal_absolute, 0)
            # Conservative Temperature
            temp_conservative = np.ma.masked_invalid(
                gsw.CT_from_pt(sal_absolute, temp))
            # In-situ density
            density = np.ma.masked_invalid(
                gsw.rho(sal_absolute, temp_conservative, pressure_absolute))

            coords = {
                'depth_0':
                (('z_dim', 'y_dim', 'x_dim'), self.dataset.depth_0.values),
                'latitude': (('y_dim', 'x_dim'), self.dataset.latitude.values),
                'longitude':
                (('y_dim', 'x_dim'), self.dataset.longitude.values)
            }
            dims = ['z_dim', 'y_dim', 'x_dim']
            attributes = {
                'units': 'kg / m^3',
                'standard name': 'In-situ density'
            }

            if shape_ds[0] != 1:
                coords['time'] = (('t_dim'), self.dataset.time.values)
                dims.insert(0, 't_dim')

            self.dataset['density'] = xr.DataArray(np.squeeze(density),
                                                   coords=coords,
                                                   dims=dims,
                                                   attrs=attributes)

        except AttributeError as err:
            error(err)
예제 #13
0
    mat = loadmat(infile)  # load mat-file
    print(mat['date'])

    P = mat['P_slow']
    JAC_C = mat['JAC_C']
    JAC_T = mat['JAC_T']
    W = mat['W_slow']
    Turb = mat['Turbidity']
    Chla = mat['Chlorophyll']
    lat = 54
    lon = -60

    SP = gsw.SP_from_C(JAC_C, JAC_T, P)
    SA = gsw.SA_from_SP(SP, P, lon, lat)
    CT = gsw.CT_from_pt(SA, JAC_T)
    sig0 = gsw.sigma0(SA, CT)

    # Bring Chla / Turb to resolution of CTD
    bin_size = len(Turb) / len(P)
    Turb = Turb.reshape(-1, int(bin_size)).mean(axis=1)
    Chla = Chla.reshape(-1, int(bin_size)).mean(axis=1)
    Turb = Turb.reshape(len(Turb), 1)
    Chla = Chla.reshape(len(Chla), 1)

    df = pd.DataFrame(np.concatenate((P, CT, SP, sig0, W, Turb, Chla), axis=1),
                      columns=[
                          'pressure', 'conserv_temp', 'abs_salinity',
                          'sigma_0', 'vert_vel', 'Turbidity', 'Chlorophyll'
                      ])
예제 #14
0
# =======================================================================================
#  TRANSFORMATIONS ON DIFFERENT GRIDS (Density, Spatial auxiliary grid)
# =======================================================================================
# ---------------------------------------------------------------------------------------
# - Spatial auxiliary grid
auxgrd_name = [
    'lat395model', 'lat198model', 'lat170eq80S90N', 'lat340eq80S90N'
][0]  # choose aux grid
lat_auxgrd, zT_auxgrd, z_w_auxgrd = utils_mask.gen_auxgrd(ncdat, auxgrd_name)
lat_mgrd = ncdat.TLAT.isel(
    nlon=0)  # mean of LAT for each j #! very inappropriate
# ---------------------------------------------------------------------------------------
# - Potential density and binning
SA = ncdat.SALT[0, :, :, :].values  # absolute salinity
PT = ncdat.TEMP[0, :, :, :].values  # potential temperature
CT = gsw.CT_from_pt(SA, PT)  # conservative temperature
sig2 = gsw.sigma2(SA, CT)  # potential density anomaly referenced to 2000dbar
RHO = ncdat.RHO[
    0, :, :, :].values * 1000 - 1000  # in-situ density anomaly [SI]
PD_bins = np.linspace(27, 38, 200)  # PD_bins = np.linspace(1.004,1.036,65)
# ---------------------------------------------------------------------------------------
# - Paths
path_auxgrd = paths.get_path2var(auxgrd_name)
utils_misc.checkdir(path_auxgrd)
path_mgrd = 'vars_mgrd/'
path_dens = 'vars_dens/'
varname_binning = 'eqbins_{}to{}in{}steps'.format(int(PD_bins.min()),
                                                  int(PD_bins.max()),
                                                  int(len(PD_bins)))

# =======================================================================================
예제 #15
0
# Compute climatologies for temperature and salinity
tempJFM = np.nanmean(np.squeeze(temp[indJFM, :, :]), axis=0)
tempJAS = np.nanmean(np.squeeze(temp[indJAS, :, :]), axis=0)
tempANN = np.nanmean(temp, axis=0)
saltJFM = np.nanmean(np.squeeze(salt[indJFM, :, :]), axis=0)
saltJAS = np.nanmean(np.squeeze(salt[indJAS, :, :]), axis=0)
saltANN = np.nanmean(salt, axis=0)

# Compute sigma's
lonmean = np.nanmean(lon)
latmean = np.nanmean(lat)
pressure = gsw.p_from_z(-depth, latmean)

SA = gsw.SA_from_SP(saltJFM, pressure[:, np.newaxis], lonmean, latmean)
CT = gsw.CT_from_pt(SA, tempJFM)
sigma2JFM = gsw.density.sigma2(SA, CT)
sigma0JFM = gsw.density.sigma0(SA, CT)

SA = gsw.SA_from_SP(saltJAS, pressure[:, np.newaxis], lonmean, latmean)
CT = gsw.CT_from_pt(SA, tempJAS)
sigma2JAS = gsw.density.sigma2(SA, CT)
sigma0JAS = gsw.density.sigma0(SA, CT)

SA = gsw.SA_from_SP(saltANN, pressure[:, np.newaxis], lonmean, latmean)
CT = gsw.CT_from_pt(SA, tempANN)
sigma2ANN = gsw.density.sigma2(SA, CT)
sigma0ANN = gsw.density.sigma0(SA, CT)

# Plot OSNAP section West
k0 = 0
예제 #16
0
os.chdir('/home/hourstonh/Documents/OCADS/todo')

ocads_data = pd.read_csv('./amended_2015-09Carbon.csv',
                         header=[0, 1],
                         skiprows=0,
                         na_values=-999)
print(ocads_data.iloc[0, :])
print(ocads_data.OXYGEN)

# 1 ml/l = 103/22.391 = 44.661 μmol/l
print(ocads_data.CTDSAL)
print(ocads_data.CTDPRS)
sa = gsw.SA_from_SP(ocads_data.CTDSAL, ocads_data.CTDPRS, ocads_data.LONGITUDE,
                    ocads_data.LATITUDE)
pt = gsw.pt_from_t(sa, ocads_data.CTDTMP, ocads_data.CTDPRS, 0)
ct = gsw.CT_from_pt(sa, pt)
print(sa)
print(ct)
print(ocads_data.CTDPRS)
density = gsw.rho(sa, ct, ocads_data.CTDPRS)
print(density)

# 44.661 to convert to umol/l then convert to umol/kg
if ocads_data.CTDOXY.columns[0].upper() == '(ML/L)':
    ocads_data['CTDOXY_2'] = ocads_data.CTDOXY * 44.661 / density * 1000.
    ctdoxy_digits = mode_decimals(ocads_data['CTDOXY'])
    ocads_data['CTDOXY_2'] = ocads_data['CTDOXY_2'].round(
        decimals=ctdoxy_digits)
if ocads_data.OXYGEN.columns[0].upper() == '(ML/L)':
    ocads_data['OXYGEN_2'] = ocads_data.OXYGEN * 44.661 / density * 1000.
    oxygen_digits = mode_decimals(ocads_data['OXYGEN'])
예제 #17
0
    def construct_pressure( self, ref_density=None, z_levels=None, extrapolate=False ):   
        '''
            This method is for calculating the hydrostatic and surface pressure fields
            on horizontal levels in the vertical (z-levels). The motivation 
            is to enable the calculation of horizontal gradients; however, 
            the variables can quite easily be interpolated onto the original 
            vertical grid.
             
            Requirements: The object's t-grid dataset must contain the sea surface height,
            Practical Salinity and the Potential Temperature variables.
            The GSW package is used to calculate the Absolute Pressure, 
            Absolute Salinity and Conservate Temperature.
            
            Three new variables (density, hydrostatic pressure, surface pressure)
            are created and added to the Contour_t.data_contour dataset:
                density_zlevels       (t_dim, depth_z_levels, r_dim)
                pressure_h_zlevels    (t_dim, depth_z_levels, r_dim)
                pressure_s            (t_dim, r_dim)
            
            Note that density is constructed using the EOS10
            equation of state.

        Parameters
        ----------
        ref_density: float
            reference density value, if None, then the Contour mean across time, 
            depth and along contour will be used.
        z_levels : (optional) numpy array
            1d array that defines the depths to interpolate the density and pressure
            on to.
        extrapolate : boolean, default False
            If true the variables are extrapolated to the deepest z_level, if false,
            values below the bathymetry are set to NaN
        Returns
        -------
        None.

        '''        
        
        # If there is no time dimension, add one, this is so
        # indexing can assume a time dimension exists
        if 't_dim' not in self.data_contour.dims:
            self.data_contour = self.data_contour.expand_dims(dim={'t_dim':1},axis=0)

        # Generate vertical levels if not supplied
        if z_levels is None:   
            z_levels = self.gen_z_levels( self.data_contour.bathymetry.max().item() )
        
        shape_ds = ( self.data_contour.t_dim.size, len(z_levels), self.data_contour.r_dim.size )
        salinity_z = np.ma.zeros( shape_ds )
        temperature_z = np.ma.zeros( shape_ds ) 
        salinity_s = self.data_contour.salinity.to_masked_array()
        temperature_s = self.data_contour.temperature.to_masked_array()
        s_levels = self.data_contour.depth_0.values
        
        # Interpolate salinity and temperature onto z-levels
        # Note. At the current time there does not appear to be a good algorithm for 
        # performing this type of interpolation without loops, which can be a bottleneck.
        # Griddata is an option but does not support extrapolation and did not 
        # have noticable performance benefit.
        for it in self.data_contour.t_dim:
            for ir in self.data_contour.r_dim:
                if not np.all(np.isnan(salinity_s[it,:,ir].data)):  
                    # Need to remove the levels below the (envelope) bathymetry which are NaN
                    salinity_s_r = salinity_s[it,:,ir].compressed()
                    temperature_s_r = temperature_s[it,:,ir].compressed()
                    s_levels_r = s_levels[:len(salinity_s_r),ir]
                    
                    sal_func = interpolate.interp1d( s_levels_r, salinity_s_r, 
                                 kind='linear', fill_value="extrapolate")
                    temp_func = interpolate.interp1d( s_levels_r, temperature_s_r, 
                                 kind='linear', fill_value="extrapolate")
                    
                    if extrapolate is True:
                        salinity_z[it,:,ir] = sal_func(z_levels)
                        temperature_z[it,:,ir] = temp_func(z_levels)                        
                    else:
                        # set levels below the bathymetry to nan
                        salinity_z[it,:,ir] = np.where( z_levels <= self.data_contour.bathymetry.values[ir], 
                                sal_func(z_levels), np.nan )
                        temperature_z[it,:,ir] = np.where( z_levels <= self.data_contour.bathymetry.values[ir], 
                                temp_func(z_levels), np.nan ) 
                    
        if extrapolate is False:
            # remove redundent levels    
            active_z_levels = np.count_nonzero(~np.isnan(salinity_z),axis=1).max() 
            salinity_z = salinity_z[:,:active_z_levels,:]
            temperature_z = temperature_z[:,:active_z_levels,:]
            z_levels = z_levels[:active_z_levels]
        
        # Absolute Pressure (depth must be negative)   
        pressure_absolute = np.ma.masked_invalid(
            gsw.p_from_z( -z_levels[:,np.newaxis], self.data_contour.latitude ) )         
        # Absolute Salinity           
        salinity_absolute = np.ma.masked_invalid(
            gsw.SA_from_SP( salinity_z, pressure_absolute, self.data_contour.longitude, 
            self.data_contour.latitude ) )
        salinity_absolute = np.ma.masked_less(salinity_absolute,0)
        # Conservative Temperature
        temp_conservative = np.ma.masked_invalid(
            gsw.CT_from_pt( salinity_absolute, temperature_z ) )
        # In-situ density
        density_z = np.ma.masked_invalid( gsw.rho( 
            salinity_absolute, temp_conservative, pressure_absolute ) )
        
        coords={'depth_z_levels': (('depth_z_levels'), z_levels),
                'latitude': (('r_dim'), self.data_contour.latitude),
                'longitude': (('r_dim'), self.data_contour.longitude)}
        dims=['depth_z_levels', 'r_dim']
        attributes = {'units': 'kg / m^3', 'standard name': 'In-situ density on the z-level vertical grid'}
        
        if shape_ds[0] != 1:
            coords['time'] = (('t_dim'), self.data_contour.time.values)
            dims.insert(0, 't_dim')
         
        if ref_density is None:    
            ref_density = np.mean( density_z )
        self.data_contour['density_zlevels'] = xr.DataArray( np.squeeze(density_z), 
                coords=coords, dims=dims, attrs=attributes )
    
        # Cumulative integral of perturbation density on z levels
        density_cumulative = -cumtrapz( density_z - ref_density, x=-z_levels, axis=1, initial=0)
        hydrostatic_pressure = density_cumulative * self.GRAVITY
        
        attributes = {'units': 'kg m^{-1} s^{-2}', 'standard name': 'Hydrostatic perturbation pressure on the z-level vertical grid'}
        self.data_contour['pressure_h_zlevels'] = xr.DataArray( np.squeeze(hydrostatic_pressure), 
                coords=coords, dims=dims, attrs=attributes )        
        self.data_contour['pressure_s'] = ref_density * self.GRAVITY * self.data_contour.ssh.squeeze()
        self.data_contour.pressure_s.attrs = {'units': 'kg m^{-1} s^{-2}', 
                                  'standard_name': 'Surface perturbation pressure'}
예제 #18
0
def BV2(S,T,depth,lon,lat):
    p1=gsw.p_from_z(depth,np.array(lat))
    sa=gsw.SA_from_SP(S,p1,lon,lat)
    ct=gsw.CT_from_pt(sa,T)
    N2,pOut=gsw.Nsquared(sa,ct,p1,lat)
    return N2,pOut
예제 #19
0
os.system('rm -f ' + cf_out)
os.system('cp ' + cf_temp + ' ' + cf_out)

print '\n'

f_sal = Dataset(cf_sal)  # r+ => can read and write in the file... )
xsal = f_sal.variables[cv_sal][:, :, :, :]
f_sal.close()

print '\n'

# Opening the Netcdf file:
f_out = Dataset(cf_out, 'r+')  # r+ => can read and write in the file... )
print 'File ', cf_out, 'is open...\n'

# Extracting tmask at surface level:
xtemp = f_out.variables[cv_temp][:, :, :, :]

#xtemp[:,:,:,:] = xtemp[:,:,:,:]*2.

#gsw.CT_from_pt(SA, pt)

f_out.variables[cv_temp][:, :, :, :] = gsw.CT_from_pt(xsal, xtemp)

f_out.variables[
    cv_temp].long_name = 'Conservative Temperature (TEOS10) built from potential temperature'

f_out.close()

print cf_out + ' sucessfully created!'
            dsOut['zonalAvgTemp'].attrs[
                'description'] = 'Zonal average of regional potential temperature'
            dsOut['zonalAvgSalt'][ilat - 1, :] = binSalt
            dsOut['zonalAvgSalt'].attrs['units'] = 'psu'
            dsOut['zonalAvgSalt'].attrs[
                'description'] = 'Zonal average of regional salinity'

        x = latbincenters
        y = -refBottomDepth
        fldtemp = dsOut.zonalAvgTemp.values.T
        fldsalt = dsOut.zonalAvgSalt.values.T
        # Compute sigma0 and sigma2
        [lat, z] = np.meshgrid(x, y)
        pressure = gsw.p_from_z(z, lat)
        SA = gsw.SA_from_SP(fldsalt, pressure, 0., lat)
        CT = gsw.CT_from_pt(SA, fldtemp)
        sigma2 = gsw.density.sigma2(SA, CT)
        sigma0 = gsw.density.sigma0(SA, CT)

        ax1[iregion].set_facecolor('darkgrey')
        cfS = ax1[iregion].contourf(x,
                                    y,
                                    fldsalt,
                                    cmap=colormapS,
                                    norm=cnormS,
                                    levels=clevelsS,
                                    extend='both')
        #cfS = ax1[iregion].pcolor(x, y, fldsalt, cmap=colormapS, vmin=clevelsS[0], vmax=clevelsS[-1])
        if sigma2contours is not None:
            cs1 = ax1[iregion].contour(x,
                                       y,
예제 #21
0
    def __init__(self,eyed, data,tempunit,salunit):
        ##id of profiles plus info
        if tempunit not in ["insitu","conservative","potential"]:
            raise ValueError("This temperature unit is not supported")
        if salunit not in ["practical","absolute","insitu"]:
            raise ValueError("This salinity unit is not supported")
        if not {"sal","temp","pres","lat","lon"}.issubset(data.keys()):
            raise ValueError("This does not contain the required information")
        if abs(max(data["pres"])-min(data["pres"])) <50:
            print(data["pres"])
            raise ValueError("This does not contain enough pressure information ")
        self.eyed = eyed
        self.lat = np.abs(data["lat"])
        self.maplat = data["lat"]
        self.lon = data["lon"]
        self.f = gsw.f(self.lat)
        self.gamma = (9.8)/(self.f*1025.0)
        if "time" in data.keys():
            self.time = data["time"]
        if "cruise" in data.keys():
            self.cruise = data["cruise"]#+str(self.time.year)
        if "station" in data.keys():
            self.station = data["station"]#+str(self.time.year)
        if "knownns" in data.keys():
            self.knownns = data["knownns"]
        else:
            self.knownns = {}
        if "relcoord" in data.keys():
            self.relcoord = data["relcoord"]
        if "knownu" in data.keys():
            self.knownu = data["knownu"]
            self.knownv = data["knownv"]
        if "knownpsi" in data.keys():
            self.knownpsi = data["knownpsi"]
        if "kapredi" in data.keys():
            self.kapredi = data["kapredi"]
            self.kapgm = data["kapgm"]
            self.diffkr = data["diffkr"]
        #Temerature Salinity and Pressure
        self.temps = np.asarray(data["temp"])
        self.sals = np.asarray(data["sal"])
        self.pres = np.abs(np.asarray(data["pres"]))
        if hasattr(self.temps,"mask"):
            print("mask")
            flter = np.logical_or(~self.temps.mask,~self.sals.mask)
            self.temps = self.temps[flter]
            self.sals = self.sals[flter]
            self.pres = self.pres[flter]
        if np.isnan(self.temps).any() or np.isnan(self.sals).any():
            print("huh")
        if salunit == "practical":
            self.sals = gsw.SA_from_SP(self.sals,self.pres,self.lon,self.maplat)

        if tempunit == "potential":
            self.temps = gsw.CT_from_pt(self.sals,self.temps)

        if tempunit == "insitu":
            self.temps = gsw.CT_from_t(self.sals,self.temps,np.abs(self.pres))

        s = np.argsort(self.pres)
        self.temps = self.temps[s]
        self.sals = self.sals[s]
        self.pres = self.pres[s]
        ##Interpolated Temperature, Salinity, and Pressure
        self.itemps = []
        self.isals = []
        self.ipres = []
        theta = np.deg2rad(self.lat)
        r = (90-self.lon) *111*1000
        x = (r*np.cos(theta))
        y = (r*np.sin(theta))
        self.x = x
        self.y = y
        self.idensities = []
        self.neutraldepth = {}
        self.interpolate()
예제 #22
0
파일: AR45_funcs.py 프로젝트: ilebras/OSNAP
uni['den']['cmap']=pden_cmap
uni['den']['vmin']=24.5
uni['den']['vmax']=28

uni['o2']={}
uni['o2']['vmin']=270
uni['o2']['vmax']=325
uni['o2']['cmap']=cm.rainbow

uni['odiff']={}
uni['odiff']['vmin']=-20
uni['odiff']['vmax']=20
uni['odiff']['cmap']=cm.RdBu_r

salvec=linspace(31,36,103)
tmpvec=linspace(-3,16,103)
salmat,tmpmat=meshgrid(salvec,tmpvec)

SA_vec=gsw.SA_from_SP(salvec,zeros(len(salvec)),-44,59.5)
SA_vec_1000=gsw.SA_from_SP(salvec,1e3*ones(len(salvec)),-44,59.5)

CT_vec=gsw.CT_from_pt(SA_vec,tmpvec)
pdenmat=zeros((shape(salmat)))
pdenmat2=zeros((shape(salmat)))
sigma1mat=zeros((shape(salmat)))
for ii in range(len(salvec)):
    for jj in range(len(tmpvec)):
        pdenmat[jj,ii]=gsw.sigma0(SA_vec[ii],CT_vec[jj])
        pdenmat2[jj,ii]=gsw.pot_rho_t_exact(SA_vec[ii],tmpvec[jj],750,0)-1e3
        sigma1mat[jj,ii]=gsw.sigma1(SA_vec[ii],CT_vec[jj])
    def spectral_PE(self, water_path, harbour_path, name, str_date):

        dt = datetime.datetime.strptime(str_date[0], "%y/%m/%d %H:%M:%S")
        start_num = dates.date2num(dt)
        dt = datetime.datetime.strptime(str_date[1], "%y/%m/%d %H:%M:%S")
        end_num = dates.date2num(dt)

        #sorted from surface to bottom
        [dateTimeArr, resultsArr, tempArr, TH_dateTimeArr, TH_resultsArr, TH_tempArr] = \
                    upwelling.read_lake_and_harbour_data(str_date, [start_num,end_num], water_path, harbour_path)

        if name == "Lake Ontario":
            time = dateTimeArr
            z = list(range(3, len(time) + 3, 1))
            t = resultsArr
        elif name == "Toronto Harbour":
            time = TH_dateTimeArr
            z = list(range(1, len(time) + 1, 1))
            t = TH_resultsArr

        g = 9.81
        #calculate temperature spectrum based on Potential energy

        #SA  =   Absolute Salinity                  [ g/kg ]
        #t   =   in-situ temperature (ITS-90)       [ deg C ]
        #p   =   sea pressure                       [ dbar ]( i.e. absolute pressure - 10.1325 dbar )
        #OPTIONAL:
        #p_ref = reference pressure                 [ dbar ]   ( i.e. absolute reference pressure - 10.1325 dbar )
        #(If reference pressure is not given then it is assumed that reference pressure is zero).
        #pt   =  potential temperature with                             [ deg C ]
        pt = np.zeros(len(z), dtype=np.ndarray)
        parr = np.zeros(len(time[0]))
        p_ref = 0
        SA = np.zeros(len(time[0]))
        for i in range(0, len(z)):
            pt[i] = np.zeros(len(time[i]))
            #p  =  sea pressure [ dbar ] ( i.e. absolute pressure - 10.1325 dbar )
            depth = -z[i]
            p = gsw.p_from_z(depth, [43.4])
            #parr.empty(len(time[i]))
            #parr.fill(p[0])
            #for j in range(0, len(time[i])):
            #    pt[i][j] = gsw.pt_from_t(SA,t[i],p,p_ref)[0]
            pt[i] = gsw.pt_from_t(SA, t[i], p[0], p_ref)

        #SA  =  Absolute Salinity                               [ g/kg ]
        #pt  =  potential temperature (ITS-90)                  [ deg C ]
        #SA & pt need to have the same dimensions.
        #CT  =  Conservative Temperature                        [ deg C ]

        CT = np.zeros(len(z), dtype=np.ndarray)
        for i in range(0, len(z)):
            CT[i] = np.zeros(len(time[i]))
            #for j in range(0, len(time[i])):
            #    CT[i][j] = gsw.CT_from_pt(SA,pt[i][j])[0]
            CT[i] = gsw.CT_from_pt(SA, pt[i])

        #SA  =  Absolute Salinity          [ g/kg ]
        #CT  =  Conservative Temperature   [ deg C ]
        #p   =  sea pressure               [ dbar ](i.e. absolute pressure - 10.1325 dbar)
        # rho  =  in-situ density     [ kg m^-3 ]
        rho = np.zeros(len(z), dtype=np.ndarray)
        for i in range(0, len(z)):
            rho[i] = np.zeros(len(time[i]))
            #for j in range(0, len(time[i])):
            #    rho[i][j] = gsw.rho(SA,CT[i][j],p)[0]
            rho[i] = gsw.rho(SA, CT[i], p)

        #integrate the PE
        PE = np.zeros(len(time[0]))
        for j in range(0, len(time[0])):
            for i in range(0, len(z) - 1):
                PE[j] = rho[i][j] * g * z[i] * (z[i + 1] - z[i])

        draw = False
        type = 'amplitude'
        # type = 'power'
        label = "PSD Potential Energy [($J m^{-2})^2cph^{-1}$]"
        title = ""
        ufft.spectral_analysis.doSpectralAnalysis([time[0],PE], name, label, title, draw, window = "hanning", num_segments=6,\
                                                  tunits = "day", funits = "cph", log = 'loglog', b_wavelets = False)
예제 #24
0
da_sal = ds['salinity']
df_sal = da_sal.to_pandas()

## Un-comment for fall only
df_sal = df_sal[(df_sal.index.month >= 5) & (df_sal.index.month >= 9)]
df_temp = df_temp[(df_temp.index.month >= 5) & (df_temp.index.month >= 9)]

sal_prof = df_sal.mean(axis=0)
temp_prof = df_temp.mean(axis=0)

Z = ds.level.values
SP = sal_prof.values
PT = temp_prof.values

SA = gsw.SA_from_SP(SP, Z, -50, 50)
CT = gsw.CT_from_pt(SA, PT)
RHO = gsw.rho(SA, CT, Z)

fig = plt.figure(1)
plt.clf()

plt.plot(RHO, Z)
plt.xlabel(r'$\rm \rho (kg m^{-3})$', fontsize=14, fontweight='bold')
plt.ylabel('Z (m)', fontsize=14, fontweight='bold')
plt.gca().invert_yaxis()
fig.set_size_inches(w=8, h=8)
fig_name = 'BB_section_rho.png'
fig.set_dpi(300)
fig.savefig(fig_name)

fig = plt.figure(2)
예제 #25
0
        saltOnCell1 = ncid.variables['timeMonthly_avg_activeTracers_salinity'][0, cellsOnEdge1-1, :]
        saltOnCell2 = ncid.variables['timeMonthly_avg_activeTracers_salinity'][0, cellsOnEdge2-1, :]
        ncid.close()

        # Mask T,S values that fall on land and topography
        tempOnCell1 = np.ma.masked_array(tempOnCell1, ~cellMask1)
        tempOnCell2 = np.ma.masked_array(tempOnCell2, ~cellMask2)
        saltOnCell1 = np.ma.masked_array(saltOnCell1, ~cellMask1)
        saltOnCell2 = np.ma.masked_array(saltOnCell2, ~cellMask2)
        # Interpolate T,S values onto edges
        temp = np.nanmean(np.array([tempOnCell1, tempOnCell2]), axis=0)
        salt = np.nanmean(np.array([saltOnCell1, saltOnCell2]), axis=0)

        # Compute sigma's
        SA = gsw.SA_from_SP(salt, pressure[np.newaxis, :], lonmean, latmean)
        CT = gsw.CT_from_pt(SA, temp)
        sigma2 = gsw.density.sigma2(SA, CT)
        sigma0 = gsw.density.sigma0(SA, CT)

        zmax = z[np.max(maxLevelEdge)]

        # Plot sections
        #  T first
        figtitle = 'Temperature ({}), {} ({}, years={}-{})'.format(
                   transectName, s, casename, climoyearStart, climoyearEnd)
        figfile = '{}/Temp_{}_{}_{}_years{:04d}-{:04d}.png'.format(
                  figdir, transectName.replace(' ', ''), casename, s, climoyearStart, climoyearEnd)
        fig = plt.figure(figsize=figsize, dpi=figdpi)
        ax = fig.add_subplot()
        ax.set_facecolor('darkgrey')
        cf = ax.contourf(x, y, temp, cmap=colormapT, norm=cnormT, levels=clevelsT, extend='max')