-- 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)