TDRcalibrate object essential for subsequent summaries
of diving behaviour.calibrateDepth(x, dry.thr=70, wet.cond, wet.thr=3610, dive.thr=4, zoc.method=c("visual", "offset", "filter"), ..., interp.wet=FALSE, smooth.par=0.1, knot.factor=3, descent.crit.q=0, ascent.crit.q=0)TDR for
calibrateDepth or an object of class
TDRcalibrate for calibrateSpeed.filter
(k, probs, depth.bounds (defaults to range),
na.rm (defaults to TRUE)) and offset (offset).spar in smooth.spline. If it
is NULL, then the smoothing parameter is determined by Generalized
Cross-validation (GCV).plotTDR, which plots depth
and, optionally, speed vs. time with the ability of zooming in and out
on time, changing maximum depths displayed, and panning through time.
The button to zero-offset correct sections of the record allows for
the collection of x and y coordinates for two
points, obtained by clicking on the plot region. The first point
clicked represents the offset and beginning time of section to
correct, and the second one represents the ending time of the section
to correct. Multiple sections of the record can be corrected in this
manner, by panning through the time and repeating the procedure. In
case there's overlap between zero offset corrected windows, the last
one prevails. Method offset can be used when the offset is known in
advance, and this value is used to correct the entire time series.
Therefore, offset=0 specifies no correction. Method filter implements a smoothing/filtering mechanism
where running quantiles can be applied to depth measurements in a
recursive manner (Luque and Fried 2011), using
.depth.filter. It relies on function
runquantile from the caTools package.
The method calculates the first running quantile defined by
probs[1] on a moving window of size k[1]. The next
running quantile, defined by probs[2] and k[2], is
applied to the smoothed/filtered depth measurements from the previous
step, and so on. The corrected depth measurements (d) are calculated
as: $$d=d_{0} - d_{n}$$ where $d[0]$ is original depth and $d[n]$ is the
last smoothed/filtered depth. This method is under development, but
reasonable results can be achieved by applying two filters (see
Examples). The default na.rm=TRUE works well when
there are no level shifts between non-NA phases in the data, but
na.rm=FALSE is better in the presence of such shifts. In other
words, there is no reason to pollute the moving window with NAs when
non-NA phases can be regarded as a continuum, so splicing non-NA
phases makes sense. Conversely, if there are level shifts between
non-NA phases, then it is better to retain NA phases to help the
algorithm recognize the shifts while sliding the window(s). The
search for the surface can be limited to specified bounds during
smoothing/filtering, so that observations outside these bounds are
interpolated using the bounded smoothed/filtered series. Once the whole record has been zero-offset corrected, remaining depths
below zero, are set to zero, as these are assumed to indicate values
at the surface. smooth.spline), so the time series is linearly
interpolated at equally spaced time steps if this limit is not
achieved in the current dive. Wiggles at the beginning and end of the
dive are assumed to be zero offset correction errors, so depth
observations at these extremes are interpolated between zero and the
next observations when this occurs. A set of knots is established to fit the smoothing spline by using an
regular time sequence with beginning and end equal to the extremes of
the input sequence, and with length equal to $N * \code{knot.factor}$. The first derivate of the
spline is evaluated at the same set of knots to calculate the vertical
rate throughout the dive and determine the end of descent and
beginning of ascent. Equivalent procedures are used for detecting
descent and ascent phases. The quantile corresponding to (descent.crit.q) of all the
positive derivatives (rate of descent) at the beginning of the dive is
used as threshold for determining the end of descent. Descent is
deemed to have ended at the first minimum derivative, and the
nearest input time observation is considered to indicate the end of
descent. The sign of the comparisons is reversed for detecting the
ascent. If observed depth to the left and right of the derivative
defining the ascent are the same, the right takes precedence. The particular dive phase categories are subsequently defined using
simple set operations. .detPhase,
.detDive, and .zoc which perform the work on simplified
objects. It performs wet/dry phase detection, zero-offset correction
of depth, and detection of dives, as well as proper labelling of the
latter. The procedure starts by zero-offset correcting depth (see ZOC
below), and then a factor is created with value L (dry) for
rows with NAs for depth and value W (wet) otherwise.
This assumes that TDRs were programmed to turn off recording
of depth when instrument is dry (typically by means of a salt-water
switch). If this assumption cannot be made for any reason, then a
logical vector as long as the time series should be supplied as
argument wet.cond to indicate which observations should be
considered wet. This argument is directly analogous to the
subset argument in subset.data.frame, so it can
refer to any variable in the TDR object (see
Note section below). The duration of each of these phases of
activity is subsequently calculated. If the duration of a dry phase
(L) is less than dry.thr, then the values in the
factor for that phase are changed to W (wet). The duration
of phases is then recalculated, and if the duration of a phase of wet
activity is less than wet.thr, then the corresponding value for
the factor is changed to Z (trivial wet). The durations of
all phases are recalculated a third time to provide final phase
durations.
Some instruments produce a peculiar pattern of missing data near the
surface, at the beginning and/or end of dives. The argument
interp.wet may help to rectify this problem by using an
interpolating spline function to impute the missing data, constraining
the result to a minimum depth of zero. Please note that this optional
step is performed after ZOC and before identifying dives, so that
interpolation is performed through dry phases coded as wet because
their duration was briefer than dry.thr. Therefore,
dry.thr must be chosen carefully to avoid interpolation through
legitimate dry periods.
The next step is to detect dives whenever the zero-offset corrected
depth in an underwater phase is below the specified dive threshold. A
new factor with finer levels of activity is thus generated, including
U (underwater), and D (diving) in addition to the
ones described above.
Once dives have been detected and assigned to a period of wet activity, phases within dives are identified using the descent, ascent and wiggle criteria (see Detection of dive phases below). This procedure generates a factor with levels D, DB, B, BA, DA, A, and X, breaking the input into descent, descent/bottom, bottom, bottom/ascent, ascent, descent/ascent (ocurring when no bottom phase can be detected) and non-dive (surface), respectively.
Luque, S.P. and Fried, R. (2011) Recursive filtering for zero offset correction of diving depth time series. PLoS ONE 6:e15850
TDRcalibrate, .zoc,
.depthFilter, .detPhase,
.detDive, plotTDR, and
plotZOC to visually assess ZOC procedure.
data(divesTDR)
divesTDR
## Consider a 3 m offset, a dive threshold of 3 m, the 1% quantile for
## critical vertical rates, and a set of knots 20 times as long as the
## observed time steps.
(dcalib <- calibrateDepth(divesTDR, dive.thr=3, zoc.method="offset",
offset=3, descent.crit.q=0.01, ascent.crit.q=0,
knot.factor=20))
## Or ZOC algorithmically with method="filter":
## Not run: ## This can take a while due to large window needed for 2nd
# ## filter in this dataset
# (dcalib <- calibrateDepth(divesTDR, dive.thr=3, zoc.method="filter",
# k=c(3, 5760), probs=c(0.5, 0.02), na.rm=TRUE,
# descent.crit.q=0.01, ascent.crit.q=0,
# knot.factor=20))
# ## End(Not run)
Run the code above in your browser using DataLab