CTD profiles

In [1]:
import os
import gsw
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA

from mpl_toolkits.axes_grid1 import host_subplot
from ctd import DataFrame, Series, lp_filter, movingaverage


def derive_cnv(self):
    """Compute SP, SA, CT, z, and GP from a cnv pre-processed cast."""
    cast = self.copy()  # FIXME: Use MetaDataFrame to propagate lon, lat.
    p = cast.index.values.astype(float)
    cast['SP'] = gsw.SP_from_C(cast['c0S/m'] * 10., cast['t090C'], p)
    cast['SA'] = gsw.SA_from_SP(cast['SP'], p, self.lon, self.lat)
    cast['SR'] = gsw.SR_from_SP(cast['SP'])
    cast['CT'] = gsw.CT_from_t(cast['SA'], cast['t090C'], p)
    cast['z'] = -gsw.z_from_p(p, self.lat)
    cast['SG'] = gsw.sigma0(cast['SA'], cast['CT'])
    return cast


def proc_ctd(fname, compression='gzip', below_water=True):
    # 00-Split, clean 'bad pump' data, and apply flag.
    cast = DataFrame.from_cnv(fname, compression=compression,
                              below_water=below_water).split()[0]
    cast = cast[cast['pumps']]
    cast = cast[~cast['flag']]  # True for bad values.
    name = os.path.basename(fname).split('.')[0]

    # Removed unwanted columns.
    keep = set(['c0S/m', 'dz/dtM', 'latitude', 'longitude', 'sbeox0Mm/Kg',
                't090C'])

    null = map(cast.pop, keep.symmetric_difference(cast.columns))
    del null

    # Smooth velocity with a 2 seconds windows.
    cast['dz/dtM'] = movingaverage(cast['dz/dtM'], window_size=48)

    # 01-Filter pressure.
    kw = dict(sample_rate=24.0, time_constant=0.15)
    cast.index = lp_filter(cast.index, **kw)

    # 02-Remove pressure reversals.
    cast = cast.press_check()
    cast = cast.dropna()

    # 03-Loop Edit.
    cast = cast[cast['dz/dtM'] >= 0.25]  # Threshold velocity.

    # 04-Remove spikes.
    kw = dict(n1=2, n2=20, block=100)
    cast = cast.apply(Series.despike, **kw)

    # 05-Bin-average.
    cast = cast.apply(Series.bindata, **dict(delta=1.))

    # 06-interpolate.
    cast = cast.apply(Series.interpolate)

    if True:  # 07-Smooth.
        pmax = max(cast.index)
        if pmax >= 500.:
            window_len = 21
        elif pmax >= 100.:
            window_len = 11
        else:
            window_len = 5
        kw = dict(window_len=window_len, window='hanning')
        cast = cast.apply(Series.smooth, **kw)

    # Add metadata to the DataFrame.
    cast.lat = cast['latitude'].mean()
    cast.lon = cast['longitude'].mean()
    cast.name = name

    # 08-Derive.
    cast = derive_cnv(cast)
    return cast


def plot_vars(self, figsize=(9, 9)):
    """Plot CTD temperature, salinity, and density."""
    fig = plt.figure(figsize=figsize)
    fig.subplots_adjust(bottom=0.1, top=0.85)
    ax0 = host_subplot(111, axes_class=AA.Axes)
    ax0.invert_yaxis()

    ax1, ax2 = ax0.twiny(), ax0.twiny()

    new_axis0 = ax0.get_grid_helper().new_fixed_axis
    new_axis1 = ax1.get_grid_helper().new_fixed_axis
    new_axis2 = ax2.get_grid_helper().new_fixed_axis

    ax0.axis["bottom"] = new_axis0(loc="bottom", axes=ax0, offset=(0, 0))
    ax1.axis["bottom"] = new_axis1(loc="bottom", axes=ax1, offset=(0, -40))
    ax2.axis["top"] = new_axis2(loc="top", axes=ax2, offset=(0, 0))

    ax0.axis["top"].toggle(all=False)
    ax1.axis["top"].toggle(all=False)
    ax2.axis["bottom"].toggle(all=False)

    ax0.set_ylabel('Pressure')
    ax0.set_xlabel(r'$\sigma_{\theta}$ [kg m$^{-3}$]')
    ax1.set_xlabel(r'Reference Salinity [g kg$^{-1}$]')
    ax2.set_xlabel(u'Conservative Temperature [\xb0C]')

    l0, = ax0.plot(self['SG'], self.index)
    l1, = ax1.plot(self['SA'], self.index)
    l2, = ax2.plot(self['CT'], self.index)

    ax0.axis["bottom"].label.set_color(l0.get_color())
    ax1.axis["bottom"].label.set_color(l1.get_color())
    ax2.axis["top"].label.set_color(l2.get_color())

    return fig, (ax0, ax1, ax2), (l0, l1, l2)
In [2]:
cast = proc_ctd(
    'data/CTD.cnv.bz2',
    compression='bz2',
    below_water=True
)
In [3]:
%matplotlib inline
from matplotlib import style


style.use('dark_background')

fig, ax, l = plot_vars(cast)

png