Skip to content

v0.4.0: sky above the skyline, centres to convergence, cross-night vouching - #3

Merged
rharnish merged 7 commits into
mainfrom
bright-stars
Oct 14, 2026
Merged

rharnish merged 7 commits into
mainfrom
bright-stars

Conversation

@rharnish

Copy link
Copy Markdown
Owner

v0.4.0: search the whole sky above the skyline, fit lens centres to convergence, and accept thin nights another night vouches for.

What changes

  • Two-pass sky search (calibrate solve). The first pass also allows big blobs, so the brightest stars (which bloom past the old 16 px limit) find a first pose. The second keeps the usual blob sizes and searches every pixel above the camera's skyline, which a terrain model places through that pose (new star_calibration.terrain, Copernicus DEM GLO-30). Before, only the top 35% of the frame was searched.
  • Centres to convergence (calibrate intrinsics --iterate): fit, re-solve, refit until no centre moves by more than 1 px. A night now leaves the centre fit only if its pose in the joint fit agrees with no other night, so two right nights solved through a wrong centre still correct it.
  • Vouching. A fit turned down only for having 5–7 stars is solved when the nearest night of the same camera within 30 days, solved on its own with 8+ stars, lands within 0.1°. Five nights qualify, the furthest off at 0.054°.
  • Ablation study (star_calibration.ablation, hpwren.ablate), and the solve's acceptance tests as parameters (defaults unchanged).
  • New intrinsics.json and pose_ledger.json. The detector-trial and centre-loop study modules are retired into these.

Results, same 308 cache blocks

v0.3.0 v0.4.0
solved 242 (85 cameras) 261 (89 cameras)
median residual 0.87 px 0.75 px
two nights < 30 d apart, median 0.022° 0.014°
… 90th percentile 0.065° 0.035°

One block is lost (starr-n-mobo-c 08-21, 6 tracks). Over all 316 blocks: 267 solves on 89 cameras, now the shipped ledger.

The solves cite 0.4.0+g0157053294, the commit that ships the converged centres.

Downstream

This changes which blocks solve, so plume-triangulation needs a coordinated re-run when it adopts v0.4.0. It still pins v0.2.1. No stable record field changed: result rows gain sky, vouched_by and reason_alone, and intrinsics rows gain dropped, all documented in docs/records.md.

Data: HPWREN (https://www.hpwren.ucsd.edu/). Terrain: Copernicus DEM GLO-30.

🤖 Generated with Claude Code

rharnish and others added 7 commits September 30, 2026 07:58
…s removed

ablation.py refits a solve's own star-to-track matches with subsets left out
(each star in turn, inner-only against outer-only by angle from the boresight,
random subsets of n stars, shortened tracks), with the optical centre held or
free. It also re-solves nights with tracks removed by radius or at random.
hpwren/ablate.py runs both over the cache's solved blocks into ablation/ and
rolls them up.

solve and solve_wide take the remaining acceptance tests as parameters
(max_median_px, k_window, min_tracks). The defaults are unchanged: re-solves
of sample blocks match the stored results field for field.
intrinsics.observations tags each point with its star.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e loop

tracks: detect= passes detector options through collect, and sky_mask= replaces the
top-35% band with an arbitrary sky region. detect_trial runs the big/low/sky variants
over the cache; centre_iter re-solves the sky tracks through iterated per-camera centres.
examples/terrain.py gains skyline and sky_mask; the San Miguel example uses the two-pass solve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…as parameters

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ergence

calibrate solve finds a block's tracks in two passes: big blobs in the top 35% for a seed
pose, then the shipped blob sizes over everything above the camera's skyline (new
star_calibration.terrain: Copernicus GLO-30 skyline and sky mask). calibrate intrinsics
--iterate fits centres, re-solves and refits until no centre moves by more than 1 px.
intrinsics.series drops a night only when its pose in the joint fit agrees with no other
night, so two right nights solved through a wrong centre still refit it. detect_trial and
centre_iter, the studies these came from, are retired. calibrate solve skips blocks with no
frames; weather skips rows it can't place in time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… agrees; v0.4.0

A fit turned down only for its star count (5 to 7 stars, median under 3 px, lens in its
window) is solved when its pose is within 0.1 deg of the nearest night of the same camera,
within 30 days, that solved on its own with 8 or more stars. calibrate.vouch decides it
again from the rows after every solve; a vouched row keeps its own reason in reason_alone
and names its witness in vouched_by. Version 0.4.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…solves

Fitted by calibrate intrinsics --iterate over 316 cache blocks (two-pass sky search),
converged in five rounds (last move 0.0 px).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lease

READMEs and records.md: the two-pass sky search, iterated centres, vouching, the
Copernicus DEM credit, and the v0.4.0 numbers against v0.3.0 on the same 308 blocks
(261 solved against 242; residual 0.87 -> 0.75 px; cross-night agreement 0.022 -> 0.014 deg).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rharnish
rharnish merged commit f02f929 into main Oct 14, 2026
1 check passed
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