Diving behaviour analysis¶
Here is a bird’s-eye view of the functionality of scikit-diveMove, loosely following diveMove’s vignette.
Set up the environment. Consider loading the logging module and setting up a logger to monitor progress to this section.
# Set up
import os
import os.path as osp
import numpy as np
import pandas as pd
import skdiveMove as skdive
# For figure sizes
_FIG1X1 = (11, 5)
_FIG2X1 = (10, 8)
_FIG3X1 = (11, 11)
pd.set_option("display.precision", 3)
np.set_printoptions(precision=3, sign="+")
%matplotlib inline
Reading data files¶
Load diveMove’s example data, using TDR.__init__
method, and print:
here = osp.dirname(os.getcwd())
ifile = osp.join(here, "skdiveMove", "tests", "data", "ag_mk7_2002_022.nc")
tdrX = skdive.TDR(ifile, depth_name="depth", has_speed=True)
print(tdrX)
# Access measured data
tdrX.get_depth("measured")
# Or simply use function ``skdive.tests.diveMove2skd`` to do the
# same with this particular data set.
Time-Depth Recorder data -- Class TDR object
Source File /home/sluque/Scripts/R/src/diveMove/Scikit_diveMove/skdiveMove/tests/data/ag_mk7_2002_022.nc
Sampling interval 0 days 00:00:05
Number of Samples 34199
Sampling Begins 2002-01-05 11:32:00
Sampling Ends 2002-01-07 11:01:50
Total duration 1 days 23:29:50
Measured depth range [-4.0,91.0]
Other variables ['light', 'temperature', 'speed']
ZOC method : 'None'
Attributes:
animal_id: Ag_022
animal_species_common: Antarctic fur seal
animal_species_science: Arctocephalus gazella
data_creation_date: 2020-07-13 17:00:00
data_format: CSV
data_nfiles: 1
data_source: dives.csv
dep_device_regional_settings: YYYY-mm-dd HH:MM:SS
dep_device_tzone: +5
dep_id: ag_mk7_2002_022
deploy_device_time_on: 2002-01-05 11:32:00
deploy_lat: 51.9833294
deploy_locality: Iles Crozet, Southern Indian Ocean
deploy_lon: -46.416665
deploy_method: glued
device_make: Wildlife Computers
device_model: MK7
device_type: archival
project_date_beg: 2000-11-01
project_date_end: 2003-04-30
project_name: Antarctic and Subantarctic fur seal foraging/energetics
provider_affiliation: Centre d'Etudes Biologiques de Chize, France
provider_email: spluque@gmail.com
provider_license: AGPLv3
provider_name: Sebastian Luque
sensors_list: pressure,light,temperature,speed
<xarray.DataArray 'depth' (date_time: 34199)> array([+nan, +nan, +nan, ..., +nan, +nan, +nan]) Coordinates: * date_time (date_time) datetime64[ns] 2002-01-05T11:32:00 ... 2002-01-07T... Attributes: sampling: regular sampling_rate: 5 sampling_rate_unit: s name: P full_name: Depth description: dive depth units: m H2O units_name: meters H2O (salt) units_label: meters column_name: depth axes: D files: dives.csv
- date_time: 34199
- nan nan nan nan nan nan nan nan ... nan nan nan nan nan nan nan nan
array([+nan, +nan, +nan, ..., +nan, +nan, +nan])
- date_time(date_time)datetime64[ns]2002-01-05T11:32:00 ... 2002-01-...
array(['2002-01-05T11:32:00.000000000', '2002-01-05T11:32:05.000000000', '2002-01-05T11:32:10.000000000', ..., '2002-01-07T11:01:40.000000000', '2002-01-07T11:01:45.000000000', '2002-01-07T11:01:50.000000000'], dtype='datetime64[ns]')
- sampling :
- regular
- sampling_rate :
- 5
- sampling_rate_unit :
- s
- name :
- P
- full_name :
- Depth
- description :
- dive depth
- units :
- m H2O
- units_name :
- meters H2O (salt)
- units_label :
- meters
- column_name :
- depth
- axes :
- D
- files :
- dives.csv
Plotting measured data¶
tdrX.plot(xlim=["2002-01-05 21:00:00", "2002-01-06 04:10:00"],
depth_lim=[95, -1], figsize=_FIG1X1);

Plot concurrent data:
ccvars = ["light", "speed"]
tdrX.plot(xlim=["2002-01-05 21:00:00", "2002-01-06 04:10:00"],
depth_lim=[95, -1], concur_vars=ccvars, figsize=_FIG3X1);

Calibrate measurements¶
Depth measurements can be calibrated in a single step with the .calibrate method:
# Helper dict to set parameter values
pars = {"offset_zoc": 3,
"dry_thr": 70,
"wet_thr": 3610,
"dive_thr": 3,
"dive_model": "unimodal",
"smooth_par": 0.1,
"knot_factor": 3,
"descent_crit_q": 0,
"ascent_crit_q": 0}
# Apply zero-offset correction with the "offset" method, and set other
# parameters for detection of wet/dry phases and dive phases
tdrX.calibrate(zoc_method="offset", offset=pars["offset_zoc"],
dry_thr=pars["dry_thr"],
wet_thr=pars["wet_thr"],
dive_thr=pars["dive_thr"],
dive_model=pars["dive_model"],
smooth_par=pars["smooth_par"],
knot_factor=pars["knot_factor"],
descent_crit_q=pars["descent_crit_q"],
ascent_crit_q=pars["ascent_crit_q"])
# Plot ZOC job
tdrX.plot_zoc(xlim=["2002-01-05 21:00:00", "2002-01-06 04:10:00"],
figsize=(13, 6));

Alternatively, each of the steps of the calibration process performed by this method can be done in a stepwise manner, allowing finer control. Please see the TDR class API section.
Plot dive phases¶
tdrX.plot_phases(diveNo=list(range(250, 300)), surface=True, figsize=_FIG1X1);

# Plot dive model for a dive
tdrX.plot_dive_model(diveNo=20, figsize=(10, 10));

Access attributes of TDR instance¶
Following calibration, use the different accessor methods:
# Time series of the wet/dry phases
print(tdrX.get_wet_activity())
phase_id phase_label
date_time
2002-01-05 11:32:00 1 L
2002-01-05 11:32:05 1 L
2002-01-05 11:32:10 1 L
2002-01-05 11:32:15 1 L
2002-01-05 11:32:20 1 L
... ... ...
2002-01-07 11:01:30 7 L
2002-01-07 11:01:35 7 L
2002-01-07 11:01:40 7 L
2002-01-07 11:01:45 7 L
2002-01-07 11:01:50 7 L
[34199 rows x 2 columns]
print(tdrX.get_phases_params("wet_dry")["dry_thr"])
70
print(tdrX.get_phases_params("wet_dry")["wet_thr"])
3610
print(tdrX.get_dives_details("row_ids"))
dive_id postdive_id dive_phase
date_time
2002-01-05 11:32:00 0 0 X
2002-01-05 11:32:05 0 0 X
2002-01-05 11:32:10 0 0 X
2002-01-05 11:32:15 0 0 X
2002-01-05 11:32:20 0 0 X
... ... ... ...
2002-01-07 11:01:30 0 426 X
2002-01-07 11:01:35 0 426 X
2002-01-07 11:01:40 0 426 X
2002-01-07 11:01:45 0 426 X
2002-01-07 11:01:50 0 426 X
[34199 rows x 3 columns]
print(tdrX.get_dives_details("spline_derivs"))
y
1 00:00:00 1.449
00:00:01.363636 1.386
00:00:02.727272 1.223
00:00:04.090909 0.953
00:00:05.454545 0.594
... ...
426 00:02:38.465346 -0.935
00:02:40.099009 -0.967
00:02:41.732673 -0.992
00:02:43.366336 -1.011
00:02:45 NaN
[10920 rows x 1 columns]
print(tdrX.get_dives_details("crit_vals"))
descent_crit ascent_crit descent_crit_rate ascent_crit_rate
dive_id
1 1 2 1.989e-01 -1.989e-01
2 11 12 5.317e-02 -2.508e-03
3 15 21 7.406e-04 -1.047e-01
4 16 17 4.277e-03 -2.780e-02
5 3 4 1.012e-01 -2.485e-02
... ... ... ... ...
422 10 17 1.857e-03 -5.450e-04
423 9 16 8.120e-03 -1.982e-01
424 8 13 2.544e-01 -1.630e-01
425 11 15 3.591e-03 -7.462e-02
426 14 15 4.773e-02 -7.283e-02
[426 rows x 4 columns]
Calibrate speed measurements¶
# Consider only changes in depth larger than 2 m
qfit, fig, ax = tdrX.calibrate_speed(z=2, figsize=(8, 6))
print(qfit.summary())
QuantReg Regression Results
==============================================================================
Dep. Variable: y Pseudo R-squared: 0.07433
Model: QuantReg Bandwidth: 0.2129
Method: Least Squares Sparsity: 2.682
Date: Fri, 24 Jul 2020 No. Observations: 2108
Time: 12:47:42 Df Residuals: 2106
Df Model: 1
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 0.3163 0.049 6.405 0.000 0.219 0.413
x 0.6872 0.049 13.902 0.000 0.590 0.784
==============================================================================

Time budgets¶
print(tdrX.time_budget(ignore_z=True, ignore_du=False))
beg phase_label end
phase_id
1 2002-01-05 11:32:00 L 2002-01-05 11:39:40
2 2002-01-05 11:39:45 W 2002-01-05 11:42:05
3 2002-01-05 11:42:10 U 2002-01-05 11:42:10
4 2002-01-05 11:42:15 W 2002-01-05 11:46:10
5 2002-01-05 11:46:15 U 2002-01-05 11:46:15
... ... ... ...
2928 2002-01-07 09:06:25 U 2002-01-07 09:06:25
2929 2002-01-07 09:06:30 W 2002-01-07 09:06:55
2930 2002-01-07 09:07:00 U 2002-01-07 09:07:00
2931 2002-01-07 09:07:05 W 2002-01-07 11:00:05
2932 2002-01-07 11:00:10 L 2002-01-07 11:01:50
[2932 rows x 3 columns]
print(tdrX.time_budget(ignore_z=True, ignore_du=True))
beg phase_label end
phase_id
1 2002-01-05 11:32:00 L 2002-01-05 11:39:40
2 2002-01-05 11:39:45 W 2002-01-06 06:30:00
3 2002-01-06 06:30:05 L 2002-01-06 17:01:10
4 2002-01-06 17:01:15 W 2002-01-07 05:00:30
5 2002-01-07 05:00:35 L 2002-01-07 07:34:00
6 2002-01-07 07:34:05 W 2002-01-07 11:00:05
7 2002-01-07 11:00:10 L 2002-01-07 11:01:50
Dive statistics¶
print(tdrX.dive_stats())
begdesc enddesc begasc desctim \
1 2002-01-05 18:20:15 2002-01-05 18:20:15 2002-01-05 18:20:20 2.5
2 2002-01-06 03:19:45 2002-01-06 03:20:35 2002-01-06 03:20:40 52.5
3 2002-01-06 03:22:10 2002-01-06 03:23:20 2002-01-06 03:23:50 72.5
4 2002-01-06 03:26:25 2002-01-06 03:27:40 2002-01-06 03:27:45 77.5
5 2002-01-06 03:30:40 2002-01-06 03:30:50 2002-01-06 03:30:55 12.5
.. ... ... ... ...
422 2002-01-07 09:54:15 2002-01-07 09:55:00 2002-01-07 09:55:35 47.5
423 2002-01-07 09:57:35 2002-01-07 09:58:15 2002-01-07 09:58:50 42.5
424 2002-01-07 10:00:55 2002-01-07 10:01:30 2002-01-07 10:01:55 37.5
425 2002-01-07 10:04:50 2002-01-07 10:05:40 2002-01-07 10:06:00 52.5
426 2002-01-07 10:13:40 2002-01-07 10:14:45 2002-01-07 10:14:50 67.5
botttim asctim divetim descdist bottdist ascdist ... ascD_mean \
1 5.0 2.5 10.0 6.0 0.0 6.0 ... -1.253
2 5.0 42.5 100.0 29.0 0.0 29.0 ... -0.630
3 30.0 72.5 175.0 63.0 8.0 67.0 ... -0.849
4 5.0 82.5 165.0 67.0 1.0 66.0 ... -0.769
5 5.0 7.5 25.0 7.0 0.0 7.0 ... -0.716
.. ... ... ... ... ... ... ... ...
422 35.0 57.5 140.0 54.0 10.0 54.0 ... -0.851
423 35.0 52.5 130.0 54.0 9.0 59.0 ... -1.041
424 25.0 77.5 140.0 57.0 20.0 77.0 ... -0.917
425 20.0 67.5 140.0 77.0 12.0 70.0 ... -0.989
426 5.0 87.5 160.0 86.0 2.0 84.0 ... -0.930
ascD_std ascD_min ascD_25% ascD_50% ascD_75% ascD_max postdive_dur \
1 0.222 -1.449 -1.402 -1.305 -1.156 -0.953 08:59:15
2 0.175 -0.810 -0.740 -0.701 -0.572 -0.152 00:00:40
3 0.153 -1.172 -0.929 -0.807 -0.759 -0.482 00:01:15
4 0.216 -1.055 -0.949 -0.777 -0.654 -0.134 00:01:25
5 0.139 -0.810 -0.807 -0.786 -0.680 -0.438 00:00:25
.. ... ... ... ... ... ... ...
422 0.225 -1.140 -1.008 -0.887 -0.713 -0.213 00:00:55
423 0.387 -1.832 -1.255 -0.936 -0.729 -0.539 00:01:05
424 0.382 -1.822 -0.958 -0.745 -0.713 -0.163 00:01:30
425 0.359 -1.655 -1.224 -0.883 -0.766 -0.153 00:06:25
426 0.319 -1.619 -1.063 -0.827 -0.708 -0.315 06:45:30
postdive_tdist postdive_mean_speed
1 50785.609 1.575
2 27.279 0.682
3 63.263 0.844
4 161.248 1.897
5 39.568 1.583
.. ... ...
422 37.836 0.688
423 32.042 0.534
424 16.169 0.190
425 -107.598 -0.291
426 -4925.427 -0.329
[426 rows x 46 columns]
Dive stamps¶
print(tdrX.stamp_dives())
phase_id beg end
dive_id
1 2 2002-01-05 12:20:15 2002-01-06 03:50:40
2 2 2002-01-05 12:20:15 2002-01-06 03:50:40
3 2 2002-01-05 12:20:15 2002-01-06 03:50:40
4 2 2002-01-05 12:20:15 2002-01-06 03:50:40
5 2 2002-01-05 12:20:15 2002-01-06 03:50:40
... ... ... ...
422 4 2002-01-06 17:31:35 2002-01-07 04:16:15
423 4 2002-01-06 17:31:35 2002-01-07 04:16:15
424 4 2002-01-06 17:31:35 2002-01-07 04:16:15
425 4 2002-01-06 17:31:35 2002-01-07 04:16:15
426 4 2002-01-06 17:31:35 2002-01-07 04:16:15
[426 rows x 3 columns]
Feel free to download a copy of this demo (tdrdemo.py).