Add observation functions for 19 planetary moons across four systems: - Galilean moons (Io, Europa, Ganymede, Callisto) via clean-room L1.2 theory - Saturn moons (Mimas through Hyperion) via TASS 1.7 - Uranus moons (Miranda through Oberon) via GUST86 - Mars moons (Phobos, Deimos) via MarsSat Add Jupiter decametric radio burst prediction for Radio JOVE operators: - io_phase_angle() — Io orbital phase from superior conjunction - jupiter_cml() — System III Central Meridian Longitude with light-time correction - jupiter_burst_probability() — Carr et al. (1983) source regions A, B, C, D L1.2 Galilean theory is a clean-room MIT implementation from the published IMCCE FORTRAN coefficients. All other ephemeris libraries are MIT-licensed extractions from Stellarium with static caching removed for PARALLEL SAFE. All 10 regression tests pass. Extension .so grows from 2.4MB to 2.5MB.
227 lines
9.9 KiB
Plaintext
227 lines
9.9 KiB
Plaintext
-- moon_observe regression tests
|
|
--
|
|
-- Tests planetary moon observation (Galilean, Saturn, Uranus, Mars)
|
|
-- and Jupiter decametric radio burst prediction functions.
|
|
-- Reference distances from JPL/NASA fact sheets.
|
|
\set boulder '''40.015N 105.270W 1655m'''::observer
|
|
-- ============================================================
|
|
-- Test 1: Galilean moon observation - all four from Boulder
|
|
-- Io, Europa, Ganymede, Callisto should return valid topocentric.
|
|
-- ============================================================
|
|
SELECT 'galilean_io' AS test,
|
|
round(topo_azimuth(galilean_observe(0, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(galilean_observe(0, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-------------+--------+--------
|
|
galilean_io | 270 | 24
|
|
(1 row)
|
|
|
|
SELECT 'galilean_europa' AS test,
|
|
round(topo_azimuth(galilean_observe(1, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(galilean_observe(1, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-----------------+--------+--------
|
|
galilean_europa | 270 | 24
|
|
(1 row)
|
|
|
|
SELECT 'galilean_ganymede' AS test,
|
|
round(topo_azimuth(galilean_observe(2, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(galilean_observe(2, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-------------------+--------+--------
|
|
galilean_ganymede | 270 | 24
|
|
(1 row)
|
|
|
|
SELECT 'galilean_callisto' AS test,
|
|
round(topo_azimuth(galilean_observe(3, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(galilean_observe(3, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-------------------+--------+--------
|
|
galilean_callisto | 270 | 24
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 2: Galilean moons should be very close to Jupiter
|
|
-- All four should have ranges within ~0.05 AU of Jupiter's range.
|
|
-- Jupiter is ~4-6 AU from Earth; moons orbit within 0.013 AU.
|
|
-- ============================================================
|
|
SELECT 'galilean_near_jupiter' AS test,
|
|
round(topo_range(planet_observe(5, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, -4) AS jupiter_km,
|
|
round(topo_range(galilean_observe(0, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, -4) AS io_km,
|
|
round(topo_range(galilean_observe(3, :boulder,
|
|
'2024-03-15 03:00:00+00'))::numeric, -4) AS callisto_km;
|
|
test | jupiter_km | io_km | callisto_km
|
|
-----------------------+------------+-----------+-------------
|
|
galilean_near_jupiter | 837420000 | 837000000 | 837600000
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 3: Saturn moon observation - Titan (body_id=5)
|
|
-- Titan is Saturn's largest moon, should be near Saturn.
|
|
-- ============================================================
|
|
SELECT 'saturn_titan' AS test,
|
|
round(topo_azimuth(saturn_moon_observe(5, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(saturn_moon_observe(5, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
--------------+--------+--------
|
|
saturn_titan | 50 | -45
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 4: Saturn moons - Mimas through Iapetus all return results
|
|
-- ============================================================
|
|
SELECT 'saturn_moons' AS test,
|
|
body_id,
|
|
round(topo_range(saturn_moon_observe(body_id, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, -4) AS range_km
|
|
FROM generate_series(0, 7) AS body_id;
|
|
test | body_id | range_km
|
|
--------------+---------+------------
|
|
saturn_moons | 0 | 1427920000
|
|
saturn_moons | 1 | 1427670000
|
|
saturn_moons | 2 | 1427910000
|
|
saturn_moons | 3 | 1427680000
|
|
saturn_moons | 4 | 1427420000
|
|
saturn_moons | 5 | 1426520000
|
|
saturn_moons | 6 | 1428150000
|
|
saturn_moons | 7 | 1429140000
|
|
(8 rows)
|
|
|
|
-- ============================================================
|
|
-- Test 5: Uranus moon observation - Titania (body_id=3)
|
|
-- ============================================================
|
|
SELECT 'uranus_titania' AS test,
|
|
round(topo_azimuth(uranus_moon_observe(3, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(uranus_moon_observe(3, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
----------------+--------+--------
|
|
uranus_titania | 329 | -25
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 6: All Uranus moons return valid results
|
|
-- ============================================================
|
|
SELECT 'uranus_moons' AS test,
|
|
body_id,
|
|
round(topo_range(uranus_moon_observe(body_id, :boulder,
|
|
'2024-06-15 03:00:00+00'))::numeric, -4) AS range_km
|
|
FROM generate_series(0, 4) AS body_id;
|
|
test | body_id | range_km
|
|
--------------+---------+------------
|
|
uranus_moons | 0 | 3061280000
|
|
uranus_moons | 1 | 3061360000
|
|
uranus_moons | 2 | 3061200000
|
|
uranus_moons | 3 | 3061310000
|
|
uranus_moons | 4 | 3061520000
|
|
(5 rows)
|
|
|
|
-- ============================================================
|
|
-- Test 7: Mars moons - Phobos and Deimos
|
|
-- ============================================================
|
|
SELECT 'mars_phobos' AS test,
|
|
round(topo_azimuth(mars_moon_observe(0, :boulder,
|
|
'2024-01-15 06:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(mars_moon_observe(0, :boulder,
|
|
'2024-01-15 06:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-------------+--------+--------
|
|
mars_phobos | 1 | -74
|
|
(1 row)
|
|
|
|
SELECT 'mars_deimos' AS test,
|
|
round(topo_azimuth(mars_moon_observe(1, :boulder,
|
|
'2024-01-15 06:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(mars_moon_observe(1, :boulder,
|
|
'2024-01-15 06:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
-------------+--------+--------
|
|
mars_deimos | 1 | -74
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 8: Io phase angle - should be [0, 360)
|
|
-- ============================================================
|
|
SELECT 'io_phase' AS test,
|
|
round(io_phase_angle('2024-03-15 03:00:00+00')::numeric, 1) AS phase_deg,
|
|
io_phase_angle('2024-03-15 03:00:00+00') >= 0.0
|
|
AND io_phase_angle('2024-03-15 03:00:00+00') < 360.0 AS in_range;
|
|
test | phase_deg | in_range
|
|
----------+-----------+----------
|
|
io_phase | 179.7 | t
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 9: Jupiter CML (System III) - should be [0, 360)
|
|
-- ============================================================
|
|
SELECT 'jupiter_cml' AS test,
|
|
round(jupiter_cml(:boulder, '2024-03-15 03:00:00+00')::numeric, 1) AS cml_deg,
|
|
jupiter_cml(:boulder, '2024-03-15 03:00:00+00') >= 0.0
|
|
AND jupiter_cml(:boulder, '2024-03-15 03:00:00+00') < 360.0 AS in_range;
|
|
test | cml_deg | in_range
|
|
-------------+---------+----------
|
|
jupiter_cml | 306.0 | t
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 10: Jupiter burst probability - known high probability zone
|
|
-- Source A: CML 200-260, Io phase 195-265 => p=0.8
|
|
-- ============================================================
|
|
SELECT 'burst_source_a' AS test,
|
|
jupiter_burst_probability(230.0, 230.0) AS p_source_a;
|
|
test | p_source_a
|
|
----------------+------------
|
|
burst_source_a | 0.8
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 11: Jupiter burst probability - known zones
|
|
-- ============================================================
|
|
SELECT 'burst_zones' AS test,
|
|
jupiter_burst_probability(90.0, 150.0) AS p_source_b,
|
|
jupiter_burst_probability(240.0, 350.0) AS p_source_c,
|
|
jupiter_burst_probability(100.0, 25.0) AS p_source_d,
|
|
jupiter_burst_probability(0.0, 130.0) AS p_quiet;
|
|
test | p_source_b | p_source_c | p_source_d | p_quiet
|
|
-------------+------------+------------+------------+---------
|
|
burst_zones | 0.6 | 0.5 | 0.15 | 0
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 12: Io phase changes over time (Io orbits in ~1.77 days)
|
|
-- Two times 12 hours apart should show significant phase change.
|
|
-- ============================================================
|
|
SELECT 'io_phase_changes' AS test,
|
|
round(io_phase_angle('2024-03-15 00:00:00+00')::numeric, 1) AS phase_0h,
|
|
round(io_phase_angle('2024-03-15 12:00:00+00')::numeric, 1) AS phase_12h,
|
|
abs(io_phase_angle('2024-03-15 00:00:00+00') -
|
|
io_phase_angle('2024-03-15 12:00:00+00')) > 10.0 AS changed;
|
|
test | phase_0h | phase_12h | changed
|
|
------------------+----------+-----------+---------
|
|
io_phase_changes | 205.0 | 103.4 | t
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 13: Error handling - invalid Galilean moon body_id
|
|
-- ============================================================
|
|
SELECT 'invalid_galilean' AS test, galilean_observe(4, :boulder, now());
|
|
ERROR: galilean_observe: body_id 4 must be 0-3 (Io, Europa, Ganymede, Callisto)
|
|
-- ============================================================
|
|
-- Test 14: Error handling - invalid Saturn moon body_id
|
|
-- ============================================================
|
|
SELECT 'invalid_saturn' AS test, saturn_moon_observe(8, :boulder, now());
|
|
ERROR: saturn_moon_observe: body_id 8 must be 0-7 (Mimas-Hyperion)
|