Phase 1 — Stars, comets, Keplerian propagation: - star_observe() / star_observe_safe(): fixed star alt/az via IAU 1976 precession, equatorial-to-horizontal transform - kepler_propagate(): two-body Keplerian orbit propagation for elliptic, parabolic, and hyperbolic orbits - comet_observe(): observe comets/asteroids from orbital elements - heliocentric type: ecliptic J2000 position (x, y, z in AU) Phase 2 — VSOP87 planets, ELP82B Moon, Sun: - planet_heliocentric(): VSOP87 heliocentric ecliptic J2000 positions for Mercury through Neptune (Bretagnon & Francou, MIT) - planet_observe(): full observation pipeline for any planet - sun_observe(): Sun position from negated Earth VSOP87 - moon_observe(): ELP2000-82B lunar position (Chapront-Touzé, MIT) - Clean-room precession (IAU 2006) and sidereal time (IERS 2010) - elliptic_to_rectangular utility (Stellarium, MIT) All Stellarium extractions are MIT-licensed, thread-safe (static caching removed for PARALLEL SAFE), zero external data files. All 9 regression tests pass (90ms total).
106 lines
4.5 KiB
Plaintext
106 lines
4.5 KiB
Plaintext
-- star_observe regression tests
|
|
--
|
|
-- Tests IAU 1976 precession and equatorial-to-horizontal transform.
|
|
-- Reference time: J2000.0 (2000-01-01 12:00:00 UTC) simplifies
|
|
-- precession checks (should be identity at epoch).
|
|
-- Setup: common observer location (Boulder, CO)
|
|
\set boulder '''40.015N 105.270W 1655m'''::observer
|
|
-- ============================================================
|
|
-- Test 1: Star at J2000.0 epoch (precession should be ~identity)
|
|
-- Polaris: RA 2h 31m 49.09s = 2.530303h, Dec +89.2641 deg
|
|
-- At J2000.0 from Boulder, should be at high elevation (~49 deg)
|
|
-- because observer lat ~40N and Polaris dec ~89.26 deg
|
|
-- ============================================================
|
|
SELECT 'polaris_j2000' AS test,
|
|
round(topo_azimuth(star_observe(2.530303, 89.2641, :boulder,
|
|
'2000-01-01 12:00:00+00'))::numeric, 1) AS az_deg,
|
|
round(topo_elevation(star_observe(2.530303, 89.2641, :boulder,
|
|
'2000-01-01 12:00:00+00'))::numeric, 1) AS el_deg;
|
|
test | az_deg | el_deg
|
|
---------------+--------+--------
|
|
polaris_j2000 | 359.4 | 39.5
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 2: Star on the celestial equator at RA=LST should transit
|
|
-- at elevation = (90 - observer_lat) from the south.
|
|
-- For Boulder (lat ~40): transit elevation ~50 deg, az ~180
|
|
-- We pick RA such that it's on the meridian at our test time.
|
|
-- ============================================================
|
|
-- Test 3: Polaris from different times (precession moves it)
|
|
-- At 2025-06-15, precession has shifted by ~0.35 deg over 25 years.
|
|
-- Elevation should change by a fraction of a degree.
|
|
SELECT 'polaris_2025' AS test,
|
|
round(topo_elevation(star_observe(2.530303, 89.2641, :boulder,
|
|
'2025-06-15 04:00:00+00'))::numeric, 1) AS el_deg;
|
|
test | el_deg
|
|
--------------+--------
|
|
polaris_2025 | 39.4
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 4: Sirius (brightest star)
|
|
-- RA 6h 45m 08.92s = 6.752478h, Dec -16.7161 deg
|
|
-- From Boulder at 2024-01-15 03:00 UTC (evening, winter)
|
|
-- Should be visible (positive elevation)
|
|
-- ============================================================
|
|
SELECT 'sirius_winter' AS test,
|
|
round(topo_azimuth(star_observe(6.752478, -16.7161, :boulder,
|
|
'2024-01-15 03:00:00+00'))::numeric, 0) AS az_deg,
|
|
round(topo_elevation(star_observe(6.752478, -16.7161, :boulder,
|
|
'2024-01-15 03:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | az_deg | el_deg
|
|
---------------+--------+--------
|
|
sirius_winter | 132 | 18
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 5: Vega
|
|
-- RA 18h 36m 56.34s = 18.615650h, Dec +38.7837 deg
|
|
-- ============================================================
|
|
SELECT 'vega' AS test,
|
|
round(topo_elevation(star_observe(18.615650, 38.7837, :boulder,
|
|
'2024-07-15 04:00:00+00'))::numeric, 0) AS el_deg;
|
|
test | el_deg
|
|
------+--------
|
|
vega | 66
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 6: star_observe_safe with invalid RA returns NULL
|
|
-- ============================================================
|
|
SELECT 'safe_null' AS test,
|
|
star_observe_safe(25.0, 45.0, :boulder, '2024-01-01 00:00:00+00') IS NULL AS is_null;
|
|
test | is_null
|
|
-----------+---------
|
|
safe_null | t
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 7: Heliocentric type I/O round-trip
|
|
-- ============================================================
|
|
SELECT 'helio_io' AS test,
|
|
'(1.0000000000,0.0000000000,0.0000000000)'::heliocentric::text AS val;
|
|
test | val
|
|
----------+------------------------------------------
|
|
helio_io | (1.0000000000,0.0000000000,0.0000000000)
|
|
(1 row)
|
|
|
|
SELECT 'helio_accessors' AS test,
|
|
round(helio_x(h)::numeric, 4) AS x,
|
|
round(helio_y(h)::numeric, 4) AS y,
|
|
round(helio_z(h)::numeric, 4) AS z,
|
|
round(helio_distance(h)::numeric, 4) AS dist
|
|
FROM (SELECT '(0.3000000000,0.4000000000,0.0000000000)'::heliocentric AS h) sub;
|
|
test | x | y | z | dist
|
|
-----------------+--------+--------+--------+--------
|
|
helio_accessors | 0.3000 | 0.4000 | 0.0000 | 0.5000
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Test 8: star_observe with error input
|
|
-- ============================================================
|
|
SELECT 'error_ra' AS test, star_observe(30.0, 0.0, :boulder, now());
|
|
ERROR: right ascension out of range: 30.000000
|
|
HINT: RA must be in [0, 24) hours.
|