Example #1
0
def test_xarray_with_coords():
    pytest.importorskip('dask')
    SA_chunk = SA.chunk(chunks={'y': 1, 't': 1})
    CT_chunk = CT.chunk(chunks={'y': 1, 't': 1})
    lat_chunk = lat.chunk(chunks={'y': 1})

    # Dimensions and cordinates match:
    expected = gsw.sigma0(SA_vals, CT_vals)
    xarray = gsw.sigma0(SA, CT)
    chunked = gsw.sigma0(SA_chunk, CT_chunk)
    assert_allclose(xarray, expected)
    assert_allclose(chunked, expected)

    # Broadcasting along dimension required (dimensions known)
    expected = gsw.alpha(SA_vals, CT_vals, p_vals[np.newaxis, :, np.newaxis])
    xarray = gsw.alpha(SA, CT, p)
    chunked = gsw.alpha(SA_chunk, CT_chunk, p)
    assert_allclose(xarray, expected)
    assert_allclose(chunked, expected)

    # Broadcasting along dimension required (dimensions unknown/exclusive)
    expected = gsw.z_from_p(p_vals[:, np.newaxis], lat_vals[np.newaxis, :])
    xarray = gsw.z_from_p(p, lat)
    chunked = gsw.z_from_p(p, lat_chunk)
    assert_allclose(xarray, expected)
    assert_allclose(chunked, expected)
def plot_TS(K, T, S, labels, tit, plotdir):
    col = ['r', 'c', 'pink', 'g', 'b']
    ss = np.linspace(32.5, 35.5, 16)
    tt = np.linspace(-3, 3, 15)
    ss2, tt2 = np.meshgrid(ss, tt)
    s0 = gsw.sigma0(ss2, tt2)
    vd = np.arange(23, 30, 0.3)
    plt.figure(figsize=(15, 10))
    for ii in range(5):
        ax = plt.subplot(2, 3, ii + 1)
        idx = np.where(labels == ii)[0][:]
        ax.scatter(S[idx, :], T[idx, :], color=col[ii], alpha=0.5, s=10)
        ax.set_xlim(32.5, 35.5)
        ax.set_ylim(-2.2, 2)
        cs = ax.contour(ss,
                        tt,
                        s0,
                        vd,
                        colors='k',
                        linestyles='dashed',
                        linewidths=0.5,
                        alpha=0.8)
        plt.clabel(cs, inline=0, fontsize=10)
        ax.set_xlabel('SA')
        ax.set_ylabel('CT')
    outfile = os.path.join(plotdir, 'gmm_TS_K%i_%s.png' % (K, tit))
    plt.savefig(outfile, bbox_inches='tight', dpi=200)
    plt.show()
Example #3
0
    def gambar_TS(self, ax, S, T, cores, labels, jumlah_garis_TS,
                  posisi_judul):
        # T-S Diagram.
        s = ma.masked_invalid(S).mean(axis=1)
        t = ma.masked_invalid(T).mean(axis=1)
        Te = np.linspace(t.min(), t.max(), jumlah_garis_TS)
        Se = np.linspace(s.min(), s.max(), jumlah_garis_TS)

        Tg, Sg = np.meshgrid(Te, Se)
        sigma_theta = gsw.sigma0(Sg, Tg)
        cnt = np.linspace(sigma_theta.min(), sigma_theta.max(),
                          jumlah_garis_TS)
        divider = make_axes_locatable(ax)
        axTS = divider.append_axes("right", 2, pad=1)
        #axTS.set(xlim=(33.2,35), ylim=(6,33))
        cs = axTS.contour(Sg,
                          Tg,
                          sigma_theta,
                          colors='grey',
                          levels=cnt,
                          zorder=1)
        kw = dict(color='r', fontsize=14, fontweight='black')
        for i in range(cores.shape[1]):
            axTS.text(cores[1, i], cores[0, i], labels[i], **kw)

        axTS.plot(s, t, 'k')
        axTS.yaxis.set_label_position(posisi_judul)
        axTS.yaxis.set_ticks_position(posisi_judul)
        axTS.set_xlabel("Salinity [g kg$^{-1}$]")
        axTS.set_ylabel("Temperature [$^\circ$C]", rotation=-90, labelpad=20)
        axTS.set_title("T-S Diagram")
        axTS.xaxis.set_major_locator(MaxNLocator(nbins=4))
def o2pl2pkg(p_col, t_col, sal_col, dopl_col, dopkg_col, lat_col, lon_col,
             inMat):
    """o2pl2pkg convert ml/l dissolved oxygen to umol/kg

    Input:
        - t_col, temperature column header deg c.
        - sal_col, salinity column header psu.
        - dopl_col, dissolved column header ml/l.
        - dopkg_col, dissolved column header umol/kg
        - lat_col, latitude for entire cast deg.
        - lon_col, longitude for entire cast deg.
        - inMat, dtype ndarray processed ctd time data.
    Output:
        - Converted Oxygen column umol/kg
    Example:
        >>> # linear interpolation of NaNs
        >>> outArray = o2pl2kg(inArr)
    """
    pkg = np.ndarray(shape=len(inMat), dtype=[(dopkg_col, np.float)])
    # Absolute sailinity from Practical salinity.
    SA = gsw.SA_from_SP(inMat[sal_col], inMat[p_col], inMat[lat_col],
                        inMat[lon_col])

    # Conservative temperature from insitu temperature.
    CT = gsw.CT_from_t(SA, inMat[t_col], inMat[p_col])
    s0 = gsw.sigma0(
        SA, CT
    )  # Potential density from Absolute Salinity g/Kg Conservative temperature deg C.

    # Convert DO ml/l to umol/kg
    for i in range(0, len(inMat[dopl_col])):
        pkg[i] = inMat[dopl_col][i] * 44660 / (s0[i] + 1000)
    return pkg
Example #5
0
def convert_ctddata(ctd_dir):
    '''
    Reads raw CTD profile data and converts it to xarray
    '''

    from epsilontools.tools import load_matfile

    dat = load_matfile(ctd_dir)
    time = pd.to_datetime(dat['UXT'], unit='s')

    dat = xr.Dataset(
        {
            'T': ('time', dat['T']),
            'S': ('time', dat['S']),
            'p': ('time', dat['P'])
        },
        coords={
            'time': time,
        })

    # TODO: need to check units when integrating!
    dat['sigma'] = ('time', gsw.sigma0(dat['S'], dat['T']) + 1000)
    dat['z'] = -dat.p
    dat['w'] = dat.z.differentiate('time', datetime_unit='s')
    temp = dat.swap_dims({'time': 'z'})
    temp['N2'] = -9.81 * temp.sigma.differentiate('z') / 1025
    temp['dTdz'] = temp.T.differentiate('z')

    return temp.swap_dims({'z': 'time'})
Example #6
0
def calc_mld(SA, CT, P, crit=.125, sd=5.):
    psi = find_nearest(P, sd)[1]
    rho = gsw.sigma0(SA, CT)
    rho_surf = rho[:psi + 1].mean()
    idx = np.where(rho >= rho_surf + crit)[0][0]
    mld = P[idx]
    return mld
Example #7
0
def aaoptode_sternvolmer(foil_coef, optode_phase, tempc, salin, press):
    # %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    # %% AAOPTODE_STERNVOLMER: For Aanderaa optode 4XXX series, to interpret
    # % calphase measurements based on the Stern Volmer equation. To be used in
    # % combination with aaoptode_salpresscorr, which handles salinity and
    # % pressure corrections.
    #
    # %% INPUTS
    # % foil_coef:    Struct of calibration coefficients
    # % optode_phase: vector of optode phase measurements (calphase or dphase)
    # % tempc:        temperature in deg C
    # % salin:        Salinity
    # % press:        pressure (db) for pressure correction
    #
    # %% OUTPUTS
    # % optode_uM: Oxygen concentration in uM
    # % optode_umolkg: Oxygen concentration in umol/kg
    # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    # % H. Palevsky, 8/6/2019, based on sg_aaoptode.m


    # % Uchida et al. 2008 Stern-Volmer based calbration mode
    C = foil_coef;
    Ksv = C[0] + C[1]*tempc+C[2]*tempc**2;
    P0 = C[3] + C[4]*tempc;
    PC = C[5] + C[6]*optode_phase;
    optode_uM = ((P0/PC)-1)/Ksv;
    # % note - this uses SR, reference salinity
    SA = 35.16504/35*salin;
    CT = gsw.CT_from_t(SA,tempc,press);
    optode_umolkg = 1000*optode_uM/(1000+ gsw.sigma0(SA,CT));
    return optode_uM, optode_umolkg
Example #8
0
def add_ctd_params(df_in: MutableMapping[str, Sequence],
                   cfg: Mapping[str, Any],
                   lon=16.7,
                   lat=55.2):
    """
    Calculate all parameters from 'sigma0', 'depth', 'soundV', 'SA' that is specified in cfg['out']['data_columns']
    :param df_in: DataFrame with columns:
     'Pres', 'Temp90' or 'Temp', and may be others:
     'Lat', 'Lon': to use instead cfg['in']['lat'] and lat and -//- lon
    :param cfg: dict with fields:
        ['out']['data_columns'] - list of columns in output dataframe
        ['in'].['b_temp_on_its90'] - optional
    :param lon:  # 54.8707   # least priority values
    :param lon:  # 19.3212
    :return: DataFrame with only columns specified in cfg['out']['data_columns']
    """
    ctd = df_in
    params_to_calc = set(cfg['out']['data_columns']).difference(ctd.columns)
    params_coord_needed_for = params_to_calc.intersection(
        ('depth', 'sigma0', 'SA', 'soundV'))  # need for all cols?
    if any(params_coord_needed_for):
        # todo: load from nav:
        if np.any(ctd.get('Lat')):
            lat = ctd['Lat']
            lon = ctd['Lon']
        else:
            if 'lat' in cfg['in']:
                lat = cfg['in']['lat']
                lon = cfg['in']['lon']
            else:
                print(
                    'Calc', '/'.join(params_coord_needed_for),
                    f'using MANUAL INPUTTED coordinates: lat={lat}, lon={lon}')

    if 'Temp90' not in ctd.columns:
        if cfg['in'].get('b_temp_on_its90'):
            ctd['Temp90'] = ctd['Temp']
        else:
            ctd['Temp90'] = gsw.conversions.t90_from_t68(df_in['Temp'])

    ctd['SA'] = gsw.SA_from_SP(
        ctd['Sal'], ctd['Pres'], lat=lat,
        lon=lon)  # or Sstar_from_SP() for Baltic where SA=S*
    # Val['Sal'] = gsw.SP_from_C(Val['Cond'], Val['Temp'], Val['P'])
    if 'soundV' in params_to_calc:
        ctd['soundV'] = gsw.sound_speed_t_exact(ctd['SA'], ctd['Temp90'],
                                                ctd['Pres'])

    if 'depth' in params_to_calc:
        ctd['depth'] = np.abs(gsw.z_from_p(np.abs(ctd['Pres']), lat))
    if 'sigma0' in params_to_calc:
        CT = gsw.CT_from_t(ctd['SA'], ctd['Temp90'], ctd['Pres'])
        ctd['sigma0'] = gsw.sigma0(ctd['SA'], CT)
        # ctd = pd.DataFrame(ctd, columns=cfg['out']['data_columns'], index=df_in.index)
    if 'Lat' in params_to_calc and not 'Lat' in ctd.columns:
        ctd['Lat'] = lat
        ctd['Lon'] = lon

    return ctd[cfg['out']['data_columns']]
Example #9
0
def derive_csv(data):
    density = gsw.z_from_p(cast[6].values,lat)
    absolute_sal=gsw.SA_from_SP(cast[10].values,density,lon,lat)
    reference_sal=gsw.SR_from_SP(absolute_sal)
    conservative_temp=gsw.CT_from_t(absolute_sal,cast[8],density)
    potential_density=gsw.sigma0(absolute_sal,conservative_temp)

    return density,absolute_sal,reference_sal,conservative_temp,potential_density
Example #10
0
def barrier_layer_thickness(SA, CT):
    """
    Compute the thickness of water separating the mixed surface layer from the
    thermocline.  A more precise definition would be the difference between
    mixed layer depth (MLD) calculated from temperature minus the mixed layer
    depth calculated using density.

    """
    import gsw
    sigma_theta = gsw.sigma0(SA, CT)
    mask = mixed_layer_depth(CT)
    mld = np.where(mask)[0][-1]
    sig_surface = sigma_theta[0]
    sig_bottom_mld = gsw.sigma0(SA[0], CT[mld])
    d_sig_t = sig_surface - sig_bottom_mld
    d_sig = sigma_theta - sig_bottom_mld
    mask = d_sig < d_sig_t  # Barrier layer.
    return Series(mask, index=SA.index, name='BLT')
Example #11
0
def barrier_layer_thickness(SA, CT):
    """
    Compute the thickness of water separating the mixed surface layer from the
    thermocline.  A more precise definition would be the difference between
    mixed layer depth (MLD) calculated from temperature minus the mixed layer
    depth calculated using density.

    """
    import gsw

    sigma_theta = gsw.sigma0(SA, CT)
    mask = mixed_layer_depth(CT)
    mld = np.where(mask)[0][-1]
    sig_surface = sigma_theta[0]
    sig_bottom_mld = gsw.sigma0(SA[0], CT[mld])
    d_sig_t = sig_surface - sig_bottom_mld
    d_sig = sigma_theta - sig_bottom_mld
    mask = d_sig < d_sig_t  # Barrier layer.
    return Series(mask, index=SA.index, name="BLT")
Example #12
0
def dens0(S, T, P):
    # ctd file contain in situ temperature and practical salinity
    # CT= conservative temperature
    # SA= absolute salinity
    # p is sea pressure (dbar)
    SA = gsw.SA_from_SP(S, P, 6., 42.)
    CT = gsw.CT_from_t(SA, T, P)
    # sound speed
    #C = gsw.sound_speed(SA, CT, P)
    return gsw.sigma0(SA, CT) + 1000.
Example #13
0
def sigma0(S, T, p, lat=None, lon=None):
    ones = xr.ones_like(S)
    p = ones * S['p']
    if lat is None:
        lat = ones * S['lat']
    if lon is None:
        lon = ones * S['lon']
    SA = gsw.SA_from_SP(S, p, lon, lat)
    CT = gsw.CT_from_t(SA, T, p)
    rho = gsw.sigma0(SA, CT)
    return rho
def oxy_to_umolkg(df_sal, df_pressure, df_lat, df_lon, df_temp, df_oxy):
    '''Rewritten from Courtney's method to use array-likes (aka use dataframes and ndarrays).
    '''
    # Absolute salinity from Practical salinity.
    SA = gsw.SA_from_SP(df_sal, df_pressure, df_lat, df_lon)

    # Conservative temperature from insitu temperature.
    CT = gsw.CT_from_t(SA, df_temp, df_pressure)
    s0 = gsw.sigma0(
        SA, CT
    )  # Potential density from Absolute Salinity g/Kg Conservative temperature deg C.
    series = df_oxy * 44660 / (s0 + 1000)
    return series
Example #15
0
def derive_cnv(self):
    """Compute SP, SA, CT, z, and GP from a cnv pre-processed cast."""
    import gsw
    cast = self.copy()
    p = cast.index.values.astype(float)
    cast['SP'] = gsw.SP_from_C(cast['c0S/m'].values * 10.,
                               cast['t090C'].values, p)
    cast['SA'] = gsw.SA_from_SP(cast['SP'].values, p, self.lon, self.lat)
    cast['SR'] = gsw.SR_from_SP(cast['SP'].values)
    cast['CT'] = gsw.CT_from_t(cast['SA'].values, cast['t090C'].values, p)
    cast['z'] = -gsw.z_from_p(p, self.lat)
    cast['sigma0_CT'] = gsw.sigma0(cast['SA'].values, cast['CT'].values)
    return cast
Example #16
0
def sbe43(volts, p, t, c, coefs, lat=0.0, lon=0.0):
    # NOTE: lat/lon = 0 is not "acceptable" for GSW, come up with something else?
    """
    SBE equation for converting SBE43 engineering units to oxygen (ml/l).
    SensorID: 38

    Parameters
    ----------
    volts : array-like
        Raw voltage
    p : array-like
        Converted pressure (dbar)
    t : array-like
        Converted temperature (Celsius)
    c : array-like
        Converted conductivity (mS/cm)
    coefs : dict
        Dictionary of calibration coefficients (Soc, Voffset, Tau20, A, B, C, E)
    lat : array-like, optional
        Latitude (decimal degrees north)
    lon : array-like, optional
        Longitude (decimal degrees)

    Returns
    -------
    oxy_ml_l : array-like
        Converted oxygen (mL/L)
    """
    # TODO: is there any reason for this to output mL/L? if oxygen eq uses o2sol
    # in umol/kg, result is in umol/kg... which is what we use at the end anyway?
    t_Kelvin = t + 273.15

    SP = gsw.SP_from_C(c, t, p)
    SA = gsw.SA_from_SP(SP, p, lon, lat)
    CT = gsw.CT_from_t(SA, t, p)
    sigma0 = gsw.sigma0(SA, CT)
    o2sol = gsw.O2sol(SA, CT, p, lon, lat)  # umol/kg
    o2sol_ml_l = oxy_umolkg_to_ml(o2sol,
                                  sigma0)  # equation expects mL/L (see TODO)

    # NOTE: lat/lon always required to get o2sol (and need SA/CT for sigma0 anyway)
    # the above is equivalent to:
    # pt = gsw.pt0_from_t(SA, t, p)
    # o2sol = gsw.O2sol_SP_pt(s, pt)

    oxy_ml_l = (coefs["Soc"] * (volts + coefs["offset"]) *
                (1.0 + coefs["A"] * t + coefs["B"] * np.power(t, 2) +
                 coefs["C"] * np.power(t, 3)) * o2sol_ml_l *
                np.exp(coefs["E"] * p / t_Kelvin))
    return np.around(oxy_ml_l, 4)
Example #17
0
def sigma_from_CTD(sal, temp, press, lon, lat, ref=0):
    """
    Calculates potential density from CTD parameters at various reference pressures

    Parameters
    ----------

    sal :array-like
         Salinity in PSU (PSS-78)

    temp :array_like
          In-situ temperature in deg C

    press :array_like
           Pressure in dbar

    lon :array_like
         longitude in decimal degrees

    lat :array_like
         latitute in decimal degrees

    ref :int
         reference pressure point for caluclateing sigma0 (in ref * 1000 dBar ref[0-4])

    Returns
    -------

    simga :array-like
           Potential density calculated at a reference pressure of ref * 1000 dBar

    """

    CT = gsw.CT_from_t(sal, temp, press)

    SA = gsw.SA_from_SP(sal, press, lon, lat)

    # Reference pressure in ref*1000 dBars
    if ref == 0:
        sigma = gsw.sigma0(SA, CT)
    elif ref == 1:
        sigma = gsw.sigma1(SA, CT)
    elif ref == 2:
        sigma = gsw.sigma2(SA, CT)
    elif ref == 3:
        sigma = gsw.sigma3(SA, CT)
    elif ref == 4:
        sigma = gsw.sigma4(SA, CT)

    return sigma
Example #18
0
    def calc_teos10_columns(self, lat, lng):
        # Practical Salinity
        SP = gsw.SP_from_C(self.data['Cond'], self.data['Temp'], self.data['Pres'])
        # Absolute Salinity
        SA = gsw.SA_from_SP_Baltic(SP, lng, lat)
        # Conservative Temperature
        CT = gsw.CT_from_t(SA, self.data['Temp'], self.data['Pres'])
        # Sigma(density) with reference pressure of 0 dbar
        sigma = gsw.sigma0(SA, CT)
        # Depth 
        depth = list(map(abs, gsw.z_from_p(self.data['Pres'], lat)))

        return {'PracticalSalinity' : SP,
                'AbsoluteSalinity' : SA,
                'ConservativeTemperature' : CT,
                'Sigma(density)' : sigma,
                'Depth' : depth}
Example #19
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)
Example #20
0
    def __Density(self):
        temp = ArgoData(Type='Temperature', Month=self.Month)
        temp.AllData()
        sal = ArgoData(Type='Salinity', Month=self.Month)
        sal.AllData()

        self.lons = temp.lons
        self.lats = temp.lats
        self.press = temp.press
        self.press_units = temp.press_units
        self.t_units = 'kg/m^3'
        self.t_title = temp.t_title
        press = np.zeros(temp.t_all.shape)
        for i in range(len(self.press)):
            press[i].fill(self.press[i])
        self.t_all = gsw.sigma0(
            sal.t_all, temp.t_all)  #potential density (rho for density)
Example #21
0
def TSdiagram(df, salt='sal00', temp='t090C', figsize=(10,10)):
    """Plot a TS diagram with parametric isopycnals based on the limits given in the df

    Parameters
    ----------
    df : pandas.DataFrame
        dataframe containing the T/S pair to plot
    salt : str, optional
        salt variable column name, by default 'sal00'
    temp : str, optional
        temp variable column name, by default 't090C'
    """
    
    # create parametric isopycnals
    T = np.linspace(df[temp].min() - 1, 
                    df[temp].max() + 1,
                    100)
    S = np.linspace(df[salt].min() - 0.1,
                    df[salt].max() + 0.1,
                    100)
    
    T,S = np.meshgrid(T,S)
    
    # compute density
    rho = gsw.sigma0(S,T)
    
    ##-- dataviz --##
    fig,ax = plt.subplots(figsize=figsize)
    
    # plot isopycnals as background
    cr_bground = ax.contour(S, T, rho, colors='grey', 
                            zorder=1, 
                            linewidths=(0.5), 
                            linestyles=('dashed'))
    
    # identification of some isopycnals
    cl_bground = ax.clabel(cr_bground, fontsize=10, inline=True, fmt="%0.1f")
    
    # adding TS pairs
    ts_cr = ax.scatter(df[salt], df[temp], s=10, alpha=1, color='k')
    
    ax.set_xlabel('Salinity [psu]', fontsize=14)
    ax.set_ylabel(r'Temperature [$^o$C]', fontsize=14)
    
    return fig,ax
def loadArgoRunsFromFile(partialUrl):
    pressuresOut = []
    densitiesOut = []
    tempsOut = []
    if downloadRun(partialUrl) != -1:
        runId = runIdFromPartial(partialUrl)
        dataset = Dataset("runs/" + runId + ".nc")
        pressures = dataset.variables["pres_adjusted"][:][0]
        salts = dataset.variables["psal"][:][0]
        temps = dataset.variables["temp"][:][0]
        for index in range(len(pressures)):
            if pressures[index] != "_":
                pres = pressures[index]
                psal = salts[index]
                temp = temps[index]
                temp = gsw.conversions.CT_from_t(psal, temp, pres)
                tempsOut.append(temp)
                pressuresOut.append(float(pres))
                densitiesOut.append(float(gsw.sigma0(psal, temp)))
    return pressuresOut, densitiesOut, tempsOut
Example #23
0
def buoyancy_freq(data):
    #Get buoyancy frequency
    dp = np.diff(data['c_pres'].values, axis=0)
    data['dp'] = np.append(dp, dp[-1])
    data['dp'] = data['dp'].mask(
        ((data['dp'] - data['dp'].mean()).abs() > data['dp'].std()))
    data['dp'] = data['dp'].interpolate().rolling(5).mean()
    CT = gsw.CT_from_t(data['c_sal'], data['c_temp'], data['c_pres'])
    SA = gsw.SA_from_SP(data['c_sal'], data['c_pres'], 174, -43)
    pdens = gsw.sigma0(SA, CT)
    data['pdens'] = pdens
    dpdens = np.diff(data['pdens'].values, axis=0)
    data['dpdens'] = np.append(dpdens, dpdens[-1])
    data['dpdens'] = data['dpdens'].mask(
        ((data['dpdens'] - data['dpdens'].mean()).abs() >
         data['dpdens'].std()))
    data['dpdens'] = data['dpdens'].interpolate().rolling(5).mean()
    data['N2'] = (9.7963 * data['dpdens']) / (data['pdens'] * data['dp'])

    #filter buoyancy frequency by removing outliers
    #data['N2'] = data['N2'].mask(data['N2']< 0.000005)
    data['N2'] = data["N2"].replace([np.inf, -np.inf], np.nan)
    data['N2'] = data['N2'].mask(
        ((data['N2'] - data['N2'].mean()).abs() > data['N2'].std()))
    data['N2'] = data['N2'].interpolate().rolling(10).mean()
    #data['N2'] = data['N2'].mask(((data['N2']-data['N2'].mean()).abs() > 3*data['N2'].std()))
    #data['N2'] = data['N2'].interpolate()

    #Sorted
    data['pdens_sort'] = np.sort(pdens)
    dpdens_sort = np.diff(data['pdens_sort'].values, axis=0)
    data['dpdens_sort'] = np.append(dpdens_sort, dpdens_sort[-1])
    data['dpdens_sort'] = data['dpdens_sort'].mask(
        ((data['dpdens_sort'] - data['dpdens_sort'].mean()).abs() >
         data['dpdens_sort'].std()))
    data['dpdens_sort'] = data['dpdens_sort'].interpolate().rolling(5).mean()
    data['N2_sort'] = (9.7963 * data['dpdens_sort']) / (data['pdens_sort'] *
                                                        data['dp'])

    return data
Example #24
0
def density_contours4TS(ax):
    """This function puts lines of constant density 
    into a given T-S-asxis"""

    Tl = ax.get_ylim()
    Sl = ax.get_xlim()

    DS = (Sl[1] - Sl[0]) / 10
    DT = (Tl[1] - Tl[0]) / 10
    s = np.arange(Sl[0], Sl[1] + DS, DS)
    t = np.arange(Tl[0], Tl[1] + DT, DT)

    S, T = np.meshgrid(s, t)
    R = gsw.sigma0(S, T)

    minR = np.min(R)
    maxR = np.max(R)
    DR = maxR - minR

    Rlevels = np.arange(minR, maxR, DR / 7)

    conts = ax.contour(S, T, R, levels=Rlevels, colors='.7', Linewidth=1)
Example #25
0
    def gambar_utama(self, S, T, depth, latitude, hasil_mixing):
        s = ma.masked_invalid(self.S).mean(axis=1)
        t = ma.masked_invalid(self.T).mean(axis=1)
        Te = np.linspace(t.min(), t.max(), 10)
        Se = np.linspace(s.min(), s.max(), 10)

        Tg, Sg = np.meshgrid(Te, Se)
        sigma_theta = gsw.sigma0(Sg, Tg)
        cnt = np.linspace(sigma_theta.min(), sigma_theta.max(), 15)

        Reds = brewer2mpl.get_map('Reds', 'Sequential', 9).mpl_colormap
        Blues = brewer2mpl.get_map('Blues', 'Sequential', 9).mpl_colormap
        Greens = brewer2mpl.get_map('Greens', 'Sequential', 9).mpl_colormap

        warna = [Reds, Blues, Greens]

        # Grid for contouring.
        zg, xg = np.meshgrid(self.depth, self.latitude)
        self.fig, self.ax = plt.subplots(nrows=1,
                                         ncols=1,
                                         figsize=(14, 6),
                                         facecolor='w')
        self.ax.invert_yaxis()
        kl = []
        percent = [50, 60, 70, 80, 90, 100]
        # m = np.zeros(hasil_mixing.shape)
        for i in range(hasil_mixing.shape[2]):
            k = self.ax.contourf(xg,
                                 zg,
                                 hasil_mixing[0:, 0:, i].transpose(),
                                 percent,
                                 cmap=warna[i],
                                 zorder=3)
            k.set_clim(percent[0], percent[-1])
            kl.append(k)

        return self.fig, kl, self.ax
Example #26
0
def calc_preind_co2_AOU_method(arrowdate, obs_year, target_year, scen):
    import numpy as np
    import netCDF4 as nc
    import gsw

    test_LO = hm.load_nc(arrowdate)

    tdate = arrowdate
    yy = tdate.format('YYYY')
    mm = tdate.format('MM')
    dd = tdate.format('DD')
    ymd = f'y{yy}m{mm}d{dd}'
    #open dataset & retrieve relevant variables, calculate potential density

    zlevels = (test_LO['deptht'][:])
    sal = test_LO['vosaline'][0, :, 0, :]
    temp = test_LO['votemper'][0, :, 0, :]
    sigma0 = gsw.sigma0(sal, temp)
    DIC = test_LO['DIC'][0, :, 0, :]
    TA = test_LO['TA'][0, :, 0, :]
    O2 = test_LO['OXY'][0, :, 0, :]
    depth_this = np.zeros_like(TA)
    zeros = np.zeros_like(TA)
    #depth_this - array of depths of same shape as DIC
    for i in range(0, 950):
        depth_this[:, i] = zlevels

### GET AGE AND WATERMASS WITNESSED CO2
#calculate pycnal's last surfacing, according to exp function
#found using cfc ages
    params0 = 0.1301889490932413
    params1 = 3.8509914822057825
    params2 = 8.301166081413104  #change to 2015 since model year is 2015

    water_age = (params0 * np.exp(-params1 * (25.15 - sigma0)) + params2)
    # year_watermass_at_surface = int(targetyear - age)
    # watermass_witnessed_co2_obs = int(hm.co2_from_year(scen,year_watermass_at_surface))

    #get witnessed co2 both of the present day water parcel and the target year water parcel
    obs_year_ar = np.zeros_like(water_age)
    obs_year_ar[:] = obs_year

    target_year_ar = np.zeros_like(water_age)
    target_year_ar[:] = target_year

    year_watermass_at_surface = (obs_year_ar - water_age).astype(int)
    watermass_witnessed_co2_obs = hm.co2_from_year(scen,
                                                   year_watermass_at_surface)
    print(np.min(watermass_witnessed_co2_obs))
    print(np.shape(watermass_witnessed_co2_obs))

    if target_year < 1905:
        watermass_witnessed_co2_target = 284
    else:
        watermass_witnessed_co2_target = \
    hm.co2_from_year(scen,year_watermass_at_surface+(target_year_ar-obs_year_ar))

###GET AOU
#(1) estimate AOU on 26 (assoc with water parcel with DIC_{w,2019,26,jdf})
# = f(O2_{w,2019,26,jdf},S_{w,2019,26,jdf},T_{w,2019,26,jdf}, P_{w,2019,26,jdf})
#(P is there to determine T when last at surface - I'll call it preT next)
    AOU_stoich = hm.get_AOU_stoich(sal, temp, O2, sigma0, water_age)

    ### GET PREFORMED DIC
    obs_preformed_dic = DIC - AOU_stoich

    #### get preformed pco2 and target year preformed pco2
    pHr, OmAr, pco2r = hm.oned_moxy(sal, temp, obs_preformed_dic, TA, 1,
                                    np.zeros_like(sal))
    obsyear_pref_pco2 = pco2r
    diseqPCO2 = obsyear_pref_pco2 - watermass_witnessed_co2_obs
    targetyear_pref_pco2 = watermass_witnessed_co2_target + diseqPCO2

    print('calculating target year preformed DIC')
    target_preformed_dic = np.zeros_like(DIC)
    target_preformed_dic_r = np.ravel(target_preformed_dic)
    targetyear_pref_pco2_r = np.ravel(targetyear_pref_pco2)
    depth_r = np.ravel(depth_this)
    sal_r = np.ravel(sal)
    temp_r = np.ravel(temp)
    TA_r = np.ravel(TA)
    zeros_r = np.zeros_like(TA_r)
    sigma0_r = np.ravel(sigma0)

    start = time.time()

    for i in range(0, len(TA_r)):
        if i % (950 * 5) == 0:
            print(f'level: {i/(950*5)}')
        ### the surface needs better handling
        if sigma0_r[i] < 25.0:
            target_preformed_dic_r[i] = 9999
        #### the bottom can be actually taken from the cell right above it, no need to do this painful calculation
        if depth_r[i] > 330:
            target_preformed_dic_r[i] = 6666
        else:
            t_dic = hm.find_DIC_corresp_to_pco2(sal_r[i], temp_r[i],
                                                targetyear_pref_pco2_r[i],
                                                TA_r[i], 1, 0)
            target_preformed_dic_r[i] = t_dic

    print('seconds taken at the hard part')
    print(time.time() - start)

    #     deltaDIC = obs_preformed_dic - target_preformed_dic

    #     print('max deltaDIC: '+str(np.max(deltaDIC)) + ', min deltaDIC: '+ str(np.min(deltaDIC)))

    #     final_target_DIC = DIC - deltaDIC

    ## the top and bottom can be dealt with differently

    DIC_r = np.ravel(DIC)
    obs_preformed_dic_r = np.ravel(obs_preformed_dic)
    deltaDIC_r = obs_preformed_dic_r - target_preformed_dic_r
    final_target_DIC_r = DIC_r - deltaDIC_r

    for i in range(0, len(TA_r)):
        if sigma0_r[i] < 25.0:
            deltaDIC_r[i] = 9999
            obs_preformed_dic_r[i] = 9999
            target_preformed_dic_r[i] = 9999
            final_target_DIC_r[i] = 9999

        if depth_r[i] > 330:
            deltaDIC_r[i] = 6666
            obs_preformed_dic_r[i] = 6666
            target_preformed_dic_r[i] = 6666
            final_target_DIC_r[i] = 6666

    deltaDIC = deltaDIC_r.reshape(40, 950)
    obs_preformed_dic = obs_preformed_dic_r.reshape(40, 950)
    target_preformed_dic = target_preformed_dic_r.reshape(40, 950)
    final_target_DIC = final_target_DIC_r.reshape(40, 950)
    #target_preformed_dic = target_preformed_dic_r.reshape(40,950)

    #     target_year_ar = np.zeros_like(final_target_DIC)
    #     target_year_ar[:] = target_year

    f = nc.Dataset(
        f'./JdF_future_DIC/LO_TY_{target_year}_scen_{scen}_{ymd}_DIC_nosurfnodeep.nc',
        'w',
        format='NETCDF4')  #'w' stands for write
    g = f.createGroup('preindustrial_DIC')
    g.createDimension('xval', 950)
    g.createDimension('depth', 40)
    g.createDimension('single', 1)

    ts = g.createVariable('sigma0', 'f4', ('depth', 'xval'))
    ts[:] = sigma0

    ts2 = g.createVariable('water_age', 'f4', ('depth', 'xval'))
    ts2[:] = water_age

    ts2a = g.createVariable('target_year', 'f4', ('single'))
    ts2a[:] = target_year

    #     ts3 = g.createVariable('watermass_witnessed_co2_obs','f4',('depth','xval'))
    #     ts3[:] = watermass_witnessed_co2_obs

    #     ts3a = g.createVariable('watermass_witnessed_co2_target','f4',('depth','xval'))
    #     ts3a[:] = watermass_witnessed_co2_target

    ts4 = g.createVariable('AOU_stoich', 'f4', ('depth', 'xval'))
    ts4[:] = AOU_stoich

    ts5 = g.createVariable('obsyear_pref_pco2', 'f4', ('depth', 'xval'))
    ts5[:] = obsyear_pref_pco2
    ts5a = g.createVariable('targetyear_pref_pco2', 'f4', ('depth', 'xval'))
    ts5a[:] = targetyear_pref_pco2

    ts5b = g.createVariable('obsyear_pref_dic', 'f4', ('depth', 'xval'))
    ts5b[:] = obs_preformed_dic
    ts5c = g.createVariable('targetyear_pref_dic', 'f4', ('depth', 'xval'))
    ts5c[:] = target_preformed_dic

    ts6 = g.createVariable('final_target_DIC', 'f4', ('depth', 'xval'))
    ts6[:] = final_target_DIC

    f.close()
Example #27
0
def save_as_xr(input, output):
    '''Read float files, compose xarray dataset, convert variables,
        and save as netcdf last updated: june 11, 2019
        '''
    a = load_matfile(str(input))
    output = str(output)
    # u = 0.5 * (a['A']['u1'].flatten()[0] + a['A']['u2'].flatten()[0])
    # v = 0.5 * (a['A']['v1'].flatten()[0] + a['A']['v2'].flatten()[0])
    # dudz = 0.5 * (a['A']['du1dz'].flatten()[0] + a['A']['du2dz'].flatten()[0])
    # dvdz = 0.5 * (a['A']['dv1dz'].flatten()[0] + a['A']['dv2dz'].flatten()[0])
    # eps = np.nanmedian(np.dstack((a['A']['eps1'].flatten()[0],
    #                               a['A']['eps2'].flatten()[0])), axis=2)
    # chi = np.nanmedian(np.dstack((a['A']['chi1'].flatten()[0],
    #                               a['A']['chi2'].flatten()[0])), axis=2)

    # compose dataset object
    ds = xr.Dataset(
        {  # define wanted variables here!
            'sigma': (['z', 'time'], a['A']['Sigma'].flatten()[0]),
            'u1': (['z', 'time'], a['A']['u1'].flatten()[0]),
            'u2': (['z', 'time'], a['A']['u2'].flatten()[0]),
            'v1': (['z', 'time'], a['A']['v1'].flatten()[0]),
            'v2': (['z', 'time'], a['A']['v2'].flatten()[0]),
            'du1dz': (['z', 'time'], a['A']['du1dz'].flatten()[0]),
            'du2dz': (['z', 'time'], a['A']['du2dz'].flatten()[0]),
            'dv1dz': (['z', 'time'], a['A']['dv1dz'].flatten()[0]),
            'dv2dz': (['z', 'time'], a['A']['dv2dz'].flatten()[0]),
            'eps1': (['z', 'time'], a['A']['eps1'].flatten()[0]),
            'eps2': (['z', 'time'], a['A']['eps2'].flatten()[0]),
            'chi1': (['z', 'time'], a['A']['chi1'].flatten()[0]),
            'chi2': (['z', 'time'], a['A']['chi2'].flatten()[0]),

            # variables needed for QC
            'RotP': (['z', 'time'], a['A']['RotP'].flatten()[0]),
            'W': (['z', 'time'], a['A']['W'].flatten()[0]),
            'verr1': (['z', 'time'], a['A']['verr1'].flatten()[0]),
            'verr2': (['z', 'time'], a['A']['verr2'].flatten()[0]),
            'kT1': (['z', 'time'], a['A']['kT1'].flatten()[0]),
            'kT2': (['z', 'time'], a['A']['kT2'].flatten()[0]),
            'T': (['z', 'time'], a['A']['T'].flatten()[0]),
            'S': (['z', 'time'], a['A']['S'].flatten()[0]),
            'n2': (['z', 'time'], a['A']['N2'].flatten()[0])
        },
        coords={
            'pressure': (['z'], a['A']['Pr'].flatten()[0].astype(float)),
            'z': a['A']['Pr'].flatten()[0].astype(float),
            'lat': (['time'], a['A']['lat'].flatten()[0]),
            'lon': (['time'], a['A']['lon'].flatten()[0]),
            'time': a['A']['Jday_gmt'].flatten()[0].astype(float)
        },
        attrs={'floatid': output.split('_')[1].split('.')[0]})
    # remove nans
    ds = ds.dropna(dim='time', how='all')
    # convert to datetime
    ds = ds.assign_coords(time=(dn2dt_vec(ds.time)))

    # comvert pressure to depth
    ds = ds.assign_coords(z=(gsw.z_from_p(ds.z, ds.lat.mean()).astype(float)))
    # ds = ds.assign_coords(z=-ds.z)

    _, index = np.unique(ds.time, return_index=True)
    ds = ds.isel(time=index)

    # convert variables
    p, lon, lat = xr.broadcast(ds.pressure, ds.lon, ds.lat)
    ds['S'] = xr.DataArray(gsw.SA_from_SP(ds.S, p, lon, lat),
                           dims=['z', 'time'])
    ds['T'] = xr.DataArray(gsw.CT_from_t(ds.S, ds.T, p), dims=['z', 'time'])
    ds['rho0'] = xr.DataArray(gsw.sigma0(ds.S, ds.T) + 1000,
                              dims=['z', 'time'])

    # save as netcdf
    ds.to_netcdf(str(output))
Example #28
0
CT = gsw.CT_from_t(SA, temp_s, depth_s)

#CT_5mean=np.mean(CT)
#SA_5mean=np.mean(SA)

# plot T/S diagram - altered from example from https://medium.com@hafezahmad/making-#temperature-salinity-diagrams-called-the-t-s-diagram-with-python-and-r-#programming-5deec6378a29

mint = np.min(CT)
maxt = np.max(CT)
mins = np.min(SA)
maxs = np.max(SA)
tempL = np.linspace(mint - 1, maxt + 1, len(SA))
salL = np.linspace(mins - 1, maxs + 1, len(SA))

Tg, Sg = np.meshgrid(tempL, salL)
sigma_theta = gsw.sigma0(Sg, Tg)
cnt = np.linspace(sigma_theta.min(), sigma_theta.max(), len(SA))
fig, ax = plt.subplots(figsize=(10, 10))
cs = ax.contour(Sg, Tg, sigma_theta, colors='grey', zorder=1)
cl = plt.clabel(cs, fontsize=10)
#sc=plt.scatter(SA_5_day_mean,CT_5_day_mean,c=cnt)
sc = plt.scatter(SA, CT, c=cnt)
cb = plt.colorbar(sc)
cb.set_label('Density')
plt.xlabel('Salinity A')
plt.ylabel('Conservative Temperature')
plt.title('T-S at BATS at T= ' + str(year) + ' - ' + str(month) + ' - ' +
          str(day) + '')
cb.set_label('Density')
plt.show()
Example #29
0
                for l in np.arange(len(new_dates_num)):
                    P_PD[:, l] = depth_range

                SA = gsw.SA_from_SP(S_PD, P_PD, lon_array_pd, lat_array_pd)
                CT = gsw.CT_from_t(SA, T_PD, P_PD)
                oxy_eq = gsw.O2sol(SA, CT, P_PD, lon_array_pd, lat_array_pd)
                OS_PD = O_PD / oxy_eq * 100

                D_PD = np.zeros(T_PD.shape)
                D_PD[:] = np.NaN

                for r in np.arange(D_PD.shape[0]):
                    for c in np.arange(D_PD.shape[1]):
                        if np.isnan(SA[r, c]) == False and np.isnan(
                                CT[r, c]) == False:
                            D_PD[r, c] = gsw.sigma0(SA[r, c], CT[r, c])

                plt.figure(figsize=(figx, figy))
                plt.pcolormesh(X,
                               Y,
                               OS_PD,
                               vmin=minOsat,
                               vmax=maxOsat,
                               cmap=cmo.haline)
                plt.gca().invert_yaxis()
                plt.colorbar()
                plt.xticks(rotation=45)
                plt.title('Oxygen Saturation Float: ' + str(WMO))
                plt.savefig(SectionFigDir + 'Pres_' + str(interp_pres) + '_' +
                            str(WMO) + '_Interp_OxygenSaturation.jpg')
                plt.clf()
Example #30
0
from ocean_tools import TKED
import gsw

directory = '../../Data/deployment_raw/'
outdir = '../../plots/ctd/LT_Lo_R/'
deployment_name = 'deploy1_'
measurement_type = 'ctd_'
file_type = 'raw_'

for i in range(58):
    c_file = 'C' + ("%07d" % (i, ))
    c_data = pd.read_pickle(directory + deployment_name + file_type + c_file)

    CT = gsw.CT_from_t(c_data['c_sal'], c_data['c_temp'], c_data['c_pres'])
    SA = gsw.SA_from_SP(c_data['c_sal'], c_data['c_pres'], 174, -43)
    pdens = gsw.sigma0(SA, CT)
    c_data["pdens"] = pdens
    [LT, Td, Nsqu, Lo, R, x_sorted,
     idxs] = TKED.thorpe_scales1(c_data["c_depth"].values * -1,
                                 c_data['pdens'].values,
                                 full_output=True)

    #plt.show()
    fig2, (ax2, ax3, ax4) = plt.subplots(1, 3, sharey=True)
    # Temperature
    ax2.plot(LT, c_data["c_depth"].values, c='k')
    ax2.set_ylabel('Depth (m)')
    #ax2.set_ylim(ax2.get_ylim()[::-1]) #this reverses the yaxis (i.e. deep at the bottom)
    ax2.set_xlabel('LT (m)')
    ax2.xaxis.set_label_position('top')  # this moves the label to the top
    ax2.xaxis.set_ticks_position('top')  # this moves the ticks to the top
Example #31
0
ppitch = sx_pitch.mean(axis=1) # <0: downcast | >0: upcast
print('Fill NaNs in matrices  - SeaExplorer')
for var in list(ds.var()):
    if var != 'profile_index':
        exec('sx_' + var + '[ppitch<0] = sx_' + var + '[ppitch<0].fillna(method="ffill", limit=10, axis=1)')
        exec('sx_' + var + '[ppitch>0] = sx_' + var + '[ppitch>0].fillna(method="bfill", limit=10, axis=1)')
        exec('sx_' + var + ' = sx_' + var + '[~pd.isna(sx_' + var + '.iloc[:,0:50].mean(axis=1))]') # correction specific for this deployment
print('  Done!')

         
# TEOS-10 conversion SeaExplorer
P = sx_pressure.values
lon0, lat0 = ds['longitude'].values.mean(), ds['latitude'].values.mean()
SA = gsw.SA_from_SP(sx_salinity.values, P, lon0, lat0)
CT = gsw.CT_from_t(SA, sx_temperature.values, P)
sigma0 = gsw.sigma0(SA, CT)
SA_sort = np.array(list(map(lambda x, y: y[x], np.argsort(sigma0, axis=1), SA)))
CT_sort = np.array(list(map(lambda x, y: y[x], np.argsort(sigma0, axis=1), CT)))
P_sort = np.array(list(map(lambda x, y: y[x], np.argsort(sigma0, axis=1), P)))
N2, p_mid = gsw.Nsquared(SA_sort, CT_sort, P_sort, lat=lat0, axis=1)

# Oxygen conversion
Ofreq = sx_oxygen_frequency.values
Soc = float(dpl['calibration.SBE43F.soc'])
Foffset = float(dpl['calibration.SBE43F.foffset'])
A = float(dpl['calibration.SBE43F.a'])
B = float(dpl['calibration.SBE43F.b'])
C = float(dpl['calibration.SBE43F.c'])
E = float(dpl['calibration.SBE43F.e'])

K = CT + 273.15 # Temp in Kelvin