Skip to main content

Anomaly Detection

Automatic detection and optional correction of GPS and sensor data quality issues. Detection is always enabled with negligible performance overhead (O(n) on track points).

Quality Score

Each trace receives a quality score from 0 to 100, deducting per anomaly:

SeverityDeduction
Critical-15
Warning-5
Info-1

Detected Anomalies (14 types in 6 categories)

CategoryTypeSeverityDescription
PositionGPS FrozenCriticalConsecutive points at identical coordinates while biometrics indicate movement
PositionGPS TeleportationPoint-to-point speed exceeds threshold; removed by GPS filter before analysis
PositionSignal LossWarningTime gaps between consecutive points (> 30s)
PositionGPS DriftWarningPosition oscillation during stops
SpeedSpeed SpikeWarningPoints exceeding max speed threshold (already clamped)
SpeedSpeed/Biometric MismatchWarningActive cadence with zero movement
ElevationElevation SpikeWarningSudden elevation changes (pre-smoothing)
ElevationImpossible GradeWarningGrade exceeding 80%
TemporalBackward TimeCriticalTimestamps going backwards
TemporalDuplicate TimestampInfoConsecutive identical timestamps
BiometricHR SpikeWarningHeart rate changes > 30 bpm between points
BiometricHR Out of RangeWarningHeart rate outside 30–230 bpm
Data QualityLow Point DensityWarningLess than 5 points per km
Data QualityConstant ElevationWarning/CriticalNo elevation variation (barometer failure)

Correction (opt-in)

Use --fix-anomalies to apply automatic corrections for correctable anomalies. Corrections recalculate affected stats automatically.

TypeCorrectableStrategy
GPS FrozenYesInterpolate lat/lon linearly between last good point and first good point after
GPS TeleportationNoAlready removed by GPS filter
GPS DriftYesCollapse all points to centroid during stops
Signal LossNoCannot reconstruct missing data
Speed SpikeNoAlready clamped by speed filter
Speed/Biometric MismatchNoInformational
Elevation SpikeYesInterpolate elevation linearly between healthy neighbors
Impossible GradeNoOften legitimate terrain
Backward TimeYesSet timestamp = previous + 1s
Duplicate TimestampYesInterpolate timestamps between surrounding unique timestamps
HR SpikeNoMay be legitimate
HR Out of RangeYesExclude from HR stats (set to null)
Low Point DensityNoCannot add points
Constant ElevationNoWould require DEM (separate feature)

Examples

Default analysis (detection always enabled):

gpx-analyzer analyze my-hike.gpx --preset trail

Apply automatic corrections:

gpx-analyzer analyze my-hike.gpx --preset trail --fix-anomalies

Check data quality in JSON format:

gpx-analyzer analyze my-hike.gpx --format json | jq '.anomalies'

Text Output

When anomalies are detected, a "Data Quality" section appears after biometrics:

Data Quality (Score: 78/100)
+---------------------------+----------+
| Total Anomalies | 5 |
| Critical | 1 |
| Warnings | 3 |
| Info | 1 |
| Distance Impact | -2134 m |
| Time Impact | 16m 6s |
| Corrections Applied | No |
+---------------------------+----------+

[CRITICAL] GPS Frozen (07:05:01 - 07:21:07, points 0-966)
GPS position frozen for 967 points (16m06s) while biometrics
indicate movement (cadence=88rpm, HR 61→139bpm)
Estimated distance lost: -2134 m

[WARNING] GPS Drift (08:02:30 - 08:04:15, points 3421-3480)
Position oscillation during stop: max drift 25m from centroid
Inflated distance: +12 m

JSON Output

In JSON format, the anomalies object contains all details:

{
"anomalies": {
"quality_score": 78,
"total_count": 5,
"info_count": 1,
"warning_count": 3,
"critical_count": 1,
"distance_impact_m": -2134,
"time_impact_s": 966,
"correction_applied": false,
"anomalies": [
{
"type": "gps_frozen",
"category": "position",
"severity": "critical",
"start_index": 0,
"end_index": 966,
"start_time": "2026-02-28T07:05:01Z",
"end_time": "2026-02-28T07:21:07Z",
"distance_impact_m": -2134,
"time_impact_s": 966,
"description": "GPS position frozen for 967 points...",
"was_corrected": false
}
]
}
}

Configuration Thresholds

All detection thresholds have sensible defaults and are not exposed as CLI flags. They can be adjusted programmatically via AnomalyConfig:

ParameterDefaultDescription
GpsFrozenMinPoints5Min consecutive identical points
GpsFrozenEpsilon0.000001Coordinate match tolerance (~0.1m)
SignalLossThresholdS30Gap threshold (seconds)
GpsDriftThresholdM20Max drift from centroid during stop
ElevationSpikeThresholdM50Sudden elevation change threshold
ImpossibleGradePercent80Grade threshold (%)
HrSpikeThresholdBpm30Max HR change between points
HrMinBpm / HrMaxBpm30 / 230Valid HR range
MinPointsPerKm5Point density threshold
ConstantElevationRangeM2Max elevation range for "constant"
ActiveCadenceThreshold30RPM threshold for "moving"

GPS Signal Quality

Standard GPX 1.1 quality fields (<fix>, <sat>, <hdop>, <vdop>, <pdop>) are parsed from the source file when present. They provide additional context for anomaly detection:

  • hdop > 5: Horizontal accuracy is poor — position errors correlate with speed spikes and GPS drift
  • sat < 4: Fewer than 4 satellites — signal is unreliable, common in canyons, urban canyons, under dense canopy
  • fix = "none" or "2d": No 3D fix — elevation readings will be unreliable

These fields are stored per track point and used internally to reinforce anomaly detection signals. They are not directly surfaced in the JSON output summary.

Web UI Integration

When viewing an activity in the web dashboard, a quality banner appears below the header when anomalies are detected. The banner shows the quality score, severity counts, and an expandable list of individual anomalies with their impact.

AI Analysis Integration

The anomaly report is included in the AI analysis prompt context, allowing the AI to comment on data quality issues in its report. Only warning and critical anomalies are forwarded (top 5).