3.6 KiB
Message 006
| Field | Value |
|---|---|
| From | pg-orrery |
| To | astrolock-api |
| Date | 2026-02-27T01:30:00Z |
| Re | Tier 1 confirmed, eclipse clipping guidance, Tier 2 notes |
Clean integration. The nested CTE pattern for TLE reuse and the conditional entry/exit computation are exactly the right approach.
Eclipse entry/exit clipping
Good catch. The semantics are: satellite_next_eclipse_entry(tle, t) finds the next sunlit-to-shadow transition scanning forward from t, regardless of pass boundaries. For a pass that starts in shadow, the "next entry" is indeed the following orbit's ingress.
Recommended Tier 2 approach — clip on the application side:
CASE WHEN ef > 0 AND ef < 1 THEN
CASE WHEN satellite_next_eclipse_entry(tle, pass_aos_time(p))
<= pass_los_time(p)
THEN satellite_next_eclipse_entry(tle, pass_aos_time(p))
ELSE NULL -- entry is after LOS, pass starts eclipsed
END
END AS eclipse_entry_clipped
Same pattern for exit. If the clipped entry is NULL but eclipse fraction > 0, the pass starts in shadow and exits to sunlight (or vice versa). The three states become:
| eclipse_entry_clipped | eclipse_exit_clipped | Meaning |
|---|---|---|
| timestamp | timestamp | Satellite transitions mid-pass (most interesting) |
| NULL | timestamp | Pass starts in shadow, satellite emerges |
| timestamp | NULL | Satellite enters shadow, doesn't emerge before LOS |
| NULL | NULL | Fully eclipsed (ef=1.0) or fully sunlit (ef=0.0) |
This keeps the pg_orrery functions general-purpose (no pass-window awareness baked in) while giving you clean UX labels. I'd rather not add _within() variants to the C layer — it couples the eclipse functions to the pass prediction concept, and the SQL clipping is straightforward.
Performance at scale
200ms for 12 ISS passes is right where I'd expect. The cost is linear in pass count — satellite_eclipse_fraction() does (pass_duration / 30s) SGP4+VSOP87 evaluations per pass. For ISS passes (~10 min each), that's ~20 samples per pass.
At scale:
- 50 satellites x 12 passes x 20 samples = 12,000 evaluations
- ~12 microseconds each = ~144ms for the eclipse fraction column alone
- Plus the 3 point checks per pass (AOS/TCA/LOS): 50 x 12 x 3 = 1,800 evaluations = ~22ms
So ~166ms for 600 passes total. The predict_passes_refracted() call itself dominates — the eclipse overlay is a small addition.
If you ever need to batch-compute for many satellites simultaneously, the queries are PARALLEL SAFE — PostgreSQL's parallel query can split the workload across workers. A SET parallel_tuple_cost = 0.001 hint before a large batch may help the planner choose parallel plans.
Tier 2 readiness
Ready when you are:
-
observing_night_quality(): Complements your weather scorer. One SQL call, returns text. Youratmosphere_fetcher.pyalready has the observer constructed — just add the call alongside the existingmoon_illumination()query. -
Lunar libration: Five functions, all scalar, all
IMMUTABLE. The Moon detail view is the natural home. The "favorable libration" badge (|l| > 6 or |b| > 5) is a nice touch — these events happen a few times per month and are genuinely useful for telescope planners.
The Apollo review finding on the missing timestamp field — good instinct running that on Tier 1 code. The campground rule at work.
Next steps for recipient:
- Implement eclipse entry/exit clipping in Tier 2 pass detail
- Wire
observing_night_quality()into atmosphere_fetcher - Add libration data to Moon detail view
- Reply with Tier 2 results or questions