Skip to content

Thread the altitude layer set through the associator - #31

Merged
jehanazad merged 1 commit into
mainfrom
feat/altitude-layers
Sep 7, 2026
Merged

jehanazad merged 1 commit into
mainfrom
feat/altitude-layers

Conversation

@jehanazad

@jehanazad jehanazad commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Why

An n=2 solve is exactly determined in (x, y) once altitude is pinned, so its position error is its altitude error. On a 20-minute capture against ground truth (dark lane), n=2 solves had a median altitude error of 1.46 km (p90 5.25) and a position error of 1.61 km when the altitude was within 1 km of truth vs 2.71 km when it was not (n=3, for contrast: 0.36 vs 2.54 km).

That altitude comes from this library: compute_overlap_zone precomputes each node pair's overlap on a horizontal lattice at a fixed set of altitude layers, and detection_association picks the best grid point plus a delay-residual-weighted mean altitude across them. The horizontal step is not the limiter — the LM solve converges from a 3 km start. The altitude ladder is, and it was hardcoded at six layers whose widest gap (1.5 → 3.0 → 5.0 km) is 2 km.

What

  • altitudes_km is now a parameter of InterNodeAssociator, threaded into compute_overlap_zone on both zone-build paths (register_node and the rebuild), exactly the way grid_step_km already is.
  • DEFAULT_ALTITUDES_KM keeps the historic (1.5, 3.0, 5.0, 7.0, 9.0, 11.0) as the library default, so every existing caller, unit test and the offline bench see the identical grid they saw before. The deployment overrides it.
  • Comments that named the specific six layers (5, 7, 9, 11, "six altitudes") now describe the configurable ladder instead of a frozen one.

Cost

Linear, and nothing else moves: the columns are altitude-independent (the property the both-beams restructure rests on), so a twelve-layer ladder emits exactly the grid points of a six-layer one over the same geometry and pays 2× the precompute. Measured on the test fixture pair: at grid_step_km=5.0, 66 → 132 grid points (4.2 → 4.7 ms); at the production grid_step_km=3.0, 180 → 360 grid points (9.3 → 13.3 ms). The per-zone build is dominated by the once-per-column both-beams test, so the wall cost grows well under 2×.

Tests

108 passed across test_association.py, test_detection_association.py, test_coverage_prior.py, test_bistatic_footprint.py. Two new ones pin the 2× ratio and that the associator's configured ladder actually reaches the zones register_node builds — a layer set that took effect on only one of the two build paths would be worse than none. ruff check / ruff format --check clean.

Consumed by the retina-server PR "Finer altitude layers and altitude continuity for n=2 solves".

🤖 Generated with Claude Code

An n=2 solve is exactly determined in (x, y) once the altitude is pinned, so
its position error IS its altitude error.  On a 20-minute test capture against
ground truth, n=2 solves had a median altitude error of 1.46 km (p90 5.25) and
a position error of 1.61 km when the altitude landed within 1 km of truth
against 2.71 km when it did not (n=3, for contrast: 0.36 vs 2.54 km).  That
altitude comes from here — compute_overlap_zone precomputes each node pair's
overlap on a horizontal lattice at a handful of altitude layers, and
detection_association picks the best grid point and a delay-residual-weighted
mean altitude across them.  The horizontal step is not the limiter (the LM
solve converges happily from a 3 km start); the altitude ladder is, and it was
frozen at six layers whose widest gap (1.5 -> 3.0 -> 5.0) is 2 km.

So make the ladder a parameter rather than a hardcode: altitudes_km on
InterNodeAssociator, threaded into compute_overlap_zone on both zone-build
paths (register_node and the rebuild), exactly the way grid_step_km already
is.  The library default is unchanged — DEFAULT_ALTITUDES_KM is the historic
(1.5, 3.0, 5.0, 7.0, 9.0, 11.0), so every existing caller, unit test and
offline bench sees the identical grid it saw before.  The deployment is what
overrides it.

Cost is linear and nothing else moves: the columns are altitude-independent
(that is the property the both-beams restructure rests on), so a twelve-layer
ladder emits exactly twice the grid points of a six-layer one over the same
geometry and pays twice the precompute.  A test pins that ratio, and another
pins that the associator's configured ladder actually reaches the zones
register_node builds — a layer set that only takes effect on one of the two
build paths would be worse than none.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@jehanazad
jehanazad merged commit 76dfb45 into main Sep 7, 2026
1 check passed
@jehanazad
jehanazad deleted the feat/altitude-layers branch September 7, 2026 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant