Commit Graph

5 Commits

Author SHA1 Message Date
Davide Scaini 6e92ea4fce segments: reject false efforts via geometric speed check
Long circuit rides were matching a segment START early and finding the
segment END hours later on a second pass, producing effort times of
~17000s on a 4.7km segment. The conformance check passed because the
full-circuit track covers all interior points within 50m over 5 hours.

Add a per-sport minimum geometric speed (segment_distance / elapsed_s):
cycling ≥ 1.0 m/s, running ≥ 0.5 m/s, default ≥ 0.2 m/s. When the
check fails, advance past the current start candidate and retry, so a
legitimate later match (e.g. a second lap done at real speed) is still
detected.
2026-05-13 16:31:00 +02:00
Davide Scaini 994f4287ef Dedup segment efforts by started_at to handle same activity stored under two IDs 2026-05-13 16:20:10 +02:00
Davide Scaini 2395a6e566 Fix segment effort duplicates; auto-scan on segment creation
- detect.py: truncate started_at to seconds so dedup key survives JSON round-trip
- store.py: dedup by (activity_id, iso-started_at) string key, not object equality
- server.py: extract _scan_segment_for_user helper; trigger background scan
  for the creating user's activities when a new segment is saved
2026-05-13 15:58:57 +02:00
Davide Scaini 4d2df860ce Segments Phase 3: detection algorithm, CLI, ingest hook, and efforts API
- detect.py: ActivityTrack + detect_one/detect_all (bbox pre-filter →
  start/end proximity 25m → path conformance 50m/30% → effort extraction
  with avg speed/HR/power and Coggan NP)
- cli.py: `bincio segments detect` for retroactive detection over stored
  timeseries JSONs, with optional --activity-id / --segment-id filters
- ingest.py: non-fatal hook at end of ingest_parsed runs detect_all
- server.py: GET /api/segments/{id}/efforts and POST /api/segments/{id}/detect
2026-05-13 00:50:39 +02:00
Davide Scaini 79cad29ff1 Segments phase 1: models, store, and API endpoints (GET/POST/DELETE /api/segments) 2026-05-13 00:19:15 +02:00