Skip to content

perf(triangulation): vectorize cones and index spatial overlap - #706

Open
frgfm wants to merge 2 commits into
mainfrom
codex/perf-triangulation
Open

frgfm wants to merge 2 commits into
mainfrom
codex/perf-triangulation

Conversation

@frgfm

@frgfm frgfm commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

This PR finds where camera views overlap with less repeated work. A camera view forms a cone on the map. The code uses those cones to group detections and estimate the smoke location.

For 300 views spread across the map, the full calculation took 119 ms instead of 2,451 ms. That is about 95% less time, or 20.6x faster than baseline.

The code calculates cone points in batches. It keeps the coordinate converters ready for reuse. A spatial index helps it skip cones that cannot overlap. It also reuses pair locations within one calculation.

flowchart TB
    A["Camera directions and times"] --> B["Calculate cone points in batches<br/>Use the same coordinate converters"]
    B --> C["Use a map index<br/>Skip cones that cannot overlap"]
    C --> D["Reuse locations for pairs<br/>Keep up to 4,096 entries for this call"]
    D --> E["Return event groups<br/>and estimated smoke locations"]
Loading
Workload Baseline Earlier version of this PR This PR Faster than baseline
300 views spread across the map 2,451 ms 216 ms 119 ms 20.6x
300 views in clusters 2,575 ms 247 ms 142 ms 18.1x
30 views with many overlaps 551 ms 175 ms 60 ms 9.2x
100 views from one mast 696 ms 112 ms 81 ms 8.6x
300 views at separate times 1,983 ms 215 ms 115 ms 17.2x

This version is 1.4–2.9x faster than the earlier PR version on these workloads.

The saved pair locations have a limit of 4,096 entries and are discarded after each call. Peak Python allocations for the first workload fell from 378 to 303 KiB versus baseline. For the workload with many overlaps, they fell from 376 to 318 KiB. Those allocations are about 5–9% higher than in the earlier PR version. Total process memory was about the same after warmup.

Benchmark method, implementation, and checks

Python 3.11.15. Baseline: 25f3d2ed10bd. Earlier PR version: ff2f9fe9. Inputs are deterministic and synthetic. Each condition uses a fresh process and seven timed calls after warmup. Case order is random. Timing excludes imports and input construction. Python allocation tracing runs separately from timing. Allocation peaks are not total process memory, and these results are not full API latency measurements.

Use the existing pyproj and Shapely libraries to calculate WGS84 arcs and map projection in arrays. Reuse the two CRS transformers. Use an STRtree to find intersecting cones. Read dataframe tuples, reuse pair centroids within each call, and stop locality checks after a pair exceeds the distance limit.

Keep pair order, time boundaries, cone resolution, inner-radius repair, grouping, and localization rules. Groups with many overlaps still have the existing worst-case cost for clique enumeration.

All 80 comparisons with baseline passed. Groups match exactly; locations differ by less than 1e-8 degrees; cone geometry differs by less than 1e-9 degrees. Cases include shuffled IDs, exact time boundaries, failed cones, polar/dateline coordinates, and different inner radii. All 12 overlap/cone tests pass, including a check that one call cannot reuse stale locations from another. CI, lint, formatting, type checks, and coverage checks pass.

Net diff: +15 production lines; +42 including tests. No dependency changes or benchmark files in the diff. #664 contains database changes only.

@codecov

codecov Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.07692% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.97%. Comparing base (25f3d2e) to head (7560634).

Files with missing lines Patch % Lines
src/app/services/overlap.py 98.07% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #706      +/-   ##
==========================================
+ Coverage   93.87%   93.97%   +0.10%     
==========================================
  Files          59       59              
  Lines        3218     3222       +4     
==========================================
+ Hits         3021     3028       +7     
+ Misses        197      194       -3     
Flag Coverage Δ
backend 94.09% <98.07%> (+0.10%) ⬆️
client 91.30% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@frgfm frgfm self-assigned this Oct 3, 2026
@frgfm frgfm added the type: improvement New feature or request label Oct 3, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant