Remove fixes whose implied step speed exceeds a user-supplied cap,
iteratively recomputing step speeds on the survivors so that peeling
a single fix exposes its former neighbours' step speeds and the
process can continue into coherent multi-fix error clusters. Unlike
mt_flag_speed_cap, which applies the cap once to the
original distribution, mt_peel_speed keeps peeling until no
surviving fix has max(step_in, step_out) > v_max.
Usage
mt_peel_speed(
x,
v_max,
aux_scores = NULL,
max_iter = 1000L,
remove = FALSE,
silent = FALSE
)Arguments
- x
A
move2object (single-track or multi-track).- v_max
Numeric scalar, the physiological speed cap in m/s. Must be positive; no default.
- aux_scores
Optional numeric vector of auxiliary per-fix outlier scores aligned to
nrow(x). When supplied, the peel switches to asymmetric mode: instead of flagging both endpoints of every offending edge (step_speed > v_max), the function flags only the higher-scoring endpoint per edge. Higher score = more likely outlier. Typical sources:bridge_etafrommt_flag_outliers_bridge;detour_ratiofrommt_flag_outliers_detour;-log(prob)frommt_flag_outliers; or any user-defined combination. On a 1-fix spike with reliable auxiliary scores, asymmetric mode removes the spike and preserves both clean neighbours where the default symmetric mode would remove all three. DefaultNULL(symmetric mode). See Asymmetric peel below.- max_iter
Integer. Hard safety cap on peel iterations. Default 1000; in practice convergence is reached in tens of iterations for typical error clusters.
- remove
Logical. If
TRUE, return only surviving fixes (is_outlier == FALSE). DefaultFALSE.- silent
Logical. If
FALSE(default) the function prints a brief summary (cap used, fixes peeled, iterations). SetTRUEto suppress. Errors and warnings are always shown.
Value
The input x with added columns:
is_outlierLogical.
TRUEfor fixes peeled at any iteration.peel_iterationInteger. The iteration at which a fix was peeled, or
NAif it survived.step_speedNumeric, m/s. The outgoing step speed on the survivor sequence (
NAwhere the fix was peeled or is at a track boundary).
Attributes:
v_max_usedThe cap supplied.
n_peel_iterationsInteger, iterations performed.
convergedLogical.
TRUEif the peel finished before hittingmax_iter.
Details
This is the primitive that catches coherent multi-fix errors that per-fix detectors cannot resolve. A K02-style spoof of 175 fixes at a fake location has small step speeds internally (the fake trajectory is self-consistent) and only the jump-out / jump-back boundaries violate a physiological cap. Peeling those boundaries exposes the next interior fix as a new boundary (pre-spoof neighbour now connects to an interior spoof fix over the full jump distance), which also violates the cap and gets peeled. Iteration walks inward from both ends of the spoof until the clusters meet and the remaining track is clean.
v_max must be supplied by the user from species biology –
typically the maximum sustained flight speed or a clear
physiologically-impossible cap. A data-driven v_max is
intentionally not offered here; see mt_suggest_speed_cap
for a diagnostic helper that inspects the distribution and reports
candidate cuts without choosing for you.
Distances are computed in the input CRS when projected, or in metres
via per-track local AEQD projection when the input is longitude /
latitude. The step_speed returned is always in m/s.
Asymmetric peel
The default symmetric peel labels every fix whose
max(step_in, step_out) > v_max as an outlier in the current
iteration. On a 1-fix spike both incident edges violate, so the
spike fix plus its two clean neighbours all carry an
edge-violation flag and are removed in the same pass. Only the
spike is structurally implausible; the two neighbours are clean
fixes whose only crime is being adjacent to the spike.
When aux_scores is supplied, the function instead iterates
over the offending edges and flags only the higher-scoring
endpoint per edge. A genuine spike (with two violating edges) gets
flagged via either edge by virtue of its higher score and ends up in
the is_outlier set exactly once; its neighbours, with lower
scores, are spared. Convergence is still guaranteed (the offending
edge is broken once one endpoint is removed) but may take more
iterations than the symmetric variant on dense error clusters.
Tie-breaking: when score_left == score_right, the right
(later-in-time) endpoint is flagged. This is arbitrary; users with
frequent ties should pre-jitter their scores.
aux_scores are not modified or re-aligned during peel; the
user supplies a vector aligned to the original input rows and the
function indexes into it. Score reliability is the user's
responsibility – supplying noisy or anti-correlated scores can
produce worse results than the symmetric default.
Cluster-outlier caveat. Asymmetric peel is designed for
1-fix spikes where one endpoint of an offending edge is the
true outlier and the other is a clean neighbour. On
coherent multi-fix clusters (e.g. a long spoof segment that
is locally self-consistent and only violates v_max at the
jump-out / jump-back boundaries), the auxiliary score may not
discriminate between the spoof-interior boundary fix and the
clean-track boundary fix. The peel may then walk inward from one
side only, or oscillate. For known cluster-outlier datasets
(Argos PTT spoof, K02-style), the symmetric default is the
robust choice.
See also
mt_suggest_speed_cap for diagnostic inspection of
the speed distribution before choosing v_max.
mt_flag_speed_cap for one-shot flagging without
iteration.
mt_clean_track for the full per-fix + speed pipeline,
which uses mt_peel_speed internally when v_max is
supplied.