Calculate glide ascent and descent summary data

    Args
    ----
    SGL: numpy.ndarray, shape (n,2)
        start and end index positions for sub-glides

    Returns
    -------
    sgls: pandas.DataFrame
        Sub-glide summary information defined by `SGL` start/stop indices

        *Columns*:

        * dive_phase
        * dive_id
        * dive_min_depth
        * dive_max_depth
        * dive_duration
        * start_idx
        * stop_idx
        * duration
        * mean_depth
        * total_depth_change
        * abs_depth_change
        * mean_speed
        * total_speed_change
        * mean_pitch
        * mean_sin_pitch
        * SD_pitch
        * mean_temp
        * mean_swdensity
        * mean_a
        * R2_speed_vs_time
        * SE_speed_vs_time
        * mean_pitch_circ
        * pitch_concentration
        * mean_roll_circ
        * roll_concentration
        * mean_heading_circ
        * heading_concentration

def calc_glide_des_asc(depths, pitch_lf, roll_lf, heading_lf, swim_speed,
        dives, SGL, pitch_lf_deg, temperature, Dsw):
    '''Calculate glide ascent and descent summary data

    Args
    ----
    SGL: numpy.ndarray, shape (n,2)
        start and end index positions for sub-glides

    Returns
    -------
    sgls: pandas.DataFrame
        Sub-glide summary information defined by `SGL` start/stop indices

        *Columns*:

        * dive_phase
        * dive_id
        * dive_min_depth
        * dive_max_depth
        * dive_duration
        * start_idx
        * stop_idx
        * duration
        * mean_depth
        * total_depth_change
        * abs_depth_change
        * mean_speed
        * total_speed_change
        * mean_pitch
        * mean_sin_pitch
        * SD_pitch
        * mean_temp
        * mean_swdensity
        * mean_a
        * R2_speed_vs_time
        * SE_speed_vs_time
        * mean_pitch_circ
        * pitch_concentration
        * mean_roll_circ
        * roll_concentration
        * mean_heading_circ
        * heading_concentration

    '''
    import scipy.stats
    import numpy
    import pandas

    keys = [
            'dive_phase',
            'dive_id',
            'dive_min_depth',
            'dive_max_depth',
            'dive_duration',
            'start_idx',
            'stop_idx',
            'duration',
            'mean_depth',
            'total_depth_change',
            'abs_depth_change',
            'mean_speed',
            'total_speed_change',
            'mean_pitch',
            'mean_sin_pitch',
            'SD_pitch',
            'mean_temp',
            'mean_swdensity',
            'mean_a',
            'R2_speed_vs_time',
            'SE_speed_vs_time',
            'mean_pitch_circ',
            'pitch_concentration',
            'mean_roll_circ',
            'roll_concentration',
            'mean_heading_circ',
            'heading_concentration',
            ]

    # Create empty pandas dataframe for summary values
    sgls = pandas.DataFrame(index=range(len(SGL)), columns=keys)

    for i in range(len(SGL)):
        start_idx = SGL[i,0]
        stop_idx = SGL[i,1]

        # sub-glide start point in seconds
        sgls['start_idx'][i] = start_idx

        # sub-glide end point in seconds
        sgls['stop_idx'][i] = stop_idx

        # sub-glide duration
        sgls['duration'][i] = SGL[i,1] - SGL[i,0]

        # mean depth(m)during sub-glide
        sgls['mean_depth'][i] = numpy.mean(depths[start_idx:stop_idx])

        # total depth(m)change during sub-glide
        sgl_depth_diffs = numpy.diff(depths[start_idx:stop_idx])
        sgls['total_depth_change'][i] = numpy.sum(abs(sgl_depth_diffs))

        # depth(m)change from start to end of sub-glide
        sgls['abs_depth_change'][i] = abs(depths[start_idx] - depths[stop_idx])

        # mean swim speed during the sub-glide, only given if pitch>30 degrees
        sgls['mean_speed'][i] = numpy.nanmean(swim_speed[start_idx:stop_idx])

        # total speed change during sub-glide
        sgl_speed_diffs = numpy.diff(swim_speed[start_idx:stop_idx])
        sgls['total_speed_change'][i] = numpy.nansum(abs(sgl_speed_diffs))

        # mean pitch during the sub-glide
        sgls['mean_pitch'][i] = numpy.mean(pitch_lf_deg[start_idx:stop_idx])

        # mean sin pitch during the sub-glide
        sin_pitch = numpy.sin(numpy.mean(pitch_lf_deg[start_idx:stop_idx]))
        sgls['mean_sin_pitch'][i] = sin_pitch

        # SD of pitch during the sub-glide
        # TODO just use original radian array, not deg
        #      make sure "original" is radians ;)
        sd_pitch = numpy.std(pitch_lf_deg[start_idx:stop_idx]) * 180 / numpy.pi
        sgls['SD_pitch'][i] = sd_pitch

        # mean temperature during the sub-glide
        sgls['mean_temp'][i] = numpy.mean(temperature[start_idx:stop_idx])

        # mean seawater density (kg/m^3) during the sub-glide
        sgls['mean_swdensity'][i] = numpy.mean(Dsw[start_idx:stop_idx])

        try:
            # Perform linear regression on sub-glide data subset
            xpoly = numpy.arange(start_idx, stop_idx).astype(int)
            ypoly = swim_speed[start_idx:stop_idx]

            # slope, intercept, r-value, p-value, standard error
            m, c, r, p, std_err = scipy.stats.linregress(xpoly, ypoly)

            # mean acceleration during the sub-glide
            sgls['mean_a'][i] = m

            # R2-value for the regression swim speed vs. time during the
            # sub-glide
            sgls['R2_speed_vs_time'][i] = r**2

            # SE of the gradient for the regression swim speed vs. time during
            # the sub-glide
            sgls['SE_speed_vs_time'][i] = std_err

        except:
            # mean acceleration during the sub-glide
            sgls['mean_a'][i] = numpy.nan

            # R2-value for the regression swim speed vs. time during the
            # sub-glide
            sgls['R2_speed_vs_time'][i] = numpy.nan

            # SE of the gradient for the regression swim speed vs. time during
            # the sub-glide
            sgls['SE_speed_vs_time'][i] = numpy.nan


        # TODO this does not take into account the positive depths, flipping
        # descents to ascents
        sgl_signs = numpy.sign(sgl_depth_diffs)
        if all(sgl_signs == -1):
            sgls['dive_phase'][i] = 'descent'
        elif all(sgl_signs == 1):
            sgls['dive_phase'][i] = 'ascent'
        elif any(sgl_signs == -1) & any(sgl_signs == 1):
            sgls['dive_phase'][i] = 'mixed'

        # Get indices of dive in which glide occurred
        dive_ind = numpy.where((dives['start_idx'] < start_idx) & \
                               (dives['stop_idx'] > stop_idx))[0]

        # TODO Hack way of pulling the information from first column of dives
        if dive_ind.size == 0:
            dive_inf = pandas.DataFrame.copy(dives.iloc[0])
            dive_inf[:] = numpy.nan
        else:
            dive_inf = dives.iloc[dive_ind].iloc[0]

        # Dive number in which the sub-glide recorded
        sgls['dive_id'][i] = dive_inf['dive_id']

        # Minimum dive depth (m) of the dive
        sgls['dive_min_depth'][i] = dive_inf['depth_min']

        # Maximum dive depth (m) of the dive
        sgls['dive_max_depth'][i] = dive_inf['depth_max']

        # Dive duration (s) of the dive
        sgls['dive_duration'][i] = dive_inf['dive_dur']

        # Mean pitch(deg) calculated using circular statistics
        pitch_circmean = scipy.stats.circmean(pitch_lf[start_idx:stop_idx])
        sgls['mean_pitch_circ'][i] = pitch_circmean

        # Measure of concentration (r) of pitch during the sub-glide (i.e. 0
        # for random direction, 1 for unidirectional)
        pitch_circvar = scipy.stats.circvar(pitch_lf[start_idx:stop_idx])
        sgls['pitch_concentration'][i] = 1 - pitch_circvar

        # Mean roll (deg) calculated using circular statistics
        roll_circmean = scipy.stats.circmean(roll_lf[start_idx:stop_idx])
        sgls['mean_roll_circ'][i] = roll_circmean

        # Measure of concentration (r) of roll during the sub-glide
        roll_circvar = scipy.stats.circvar(roll_lf[start_idx:stop_idx])
        sgls['roll_concentration'][i] = 1 - roll_circvar

        # Mean heading (deg) calculated using circular statistics
        heading_circmean = scipy.stats.circmean(heading_lf[start_idx:stop_idx])
        sgls['mean_heading_circ'][i] = heading_circmean

        # Measure of concentration (r) of heading during the sub-glide
        heading_circvar = scipy.stats.circvar(heading_lf[start_idx:stop_idx])
        sgls['heading_concentration'][i] = 1 - heading_circvar

    return sgls