pg_orrery/test/expected/rise_set.out
Ryan Malloy a349f5505a Add v0.13.0: nutation, make_equatorial constructor, rise/set predictions
Integrate IAU 2000B nutation (~9 arcsec) into the solar system observation
pipeline via precess_and_nutate_j2000_to_date(). Affects all planet, star,
moon, and small body RA/Dec and az/el values. Satellite SGP4/TEME pipeline
unchanged.

Add make_equatorial(ra_hours, dec_deg, distance_km) constructor to replace
error-prone text literal casts.

Add 8 rise/set prediction functions (planet_next_rise/set, sun_next_rise/set,
moon_next_rise/set, sun_next_rise/set_refracted) using bisection algorithm
adapted from satellite pass prediction. Returns NULL for circumpolar and
polar night edge cases.

Fix DE fallback test fragility: replace exact float equality with tolerance
comparisons to handle GCC LTO inlining divergence across translation units.

132 -> 141 SQL objects. 22 -> 24 regression suites. All 24 passing.
2026-02-25 13:53:22 -07:00

158 lines
6.1 KiB
Plaintext

-- rise_set.sql -- Tests for v0.13.0: rise/set prediction functions
--
-- Verifies solar system body rise/set predictions using the bisection
-- algorithm adapted from satellite pass prediction.
CREATE EXTENSION IF NOT EXISTS pg_orrery;
NOTICE: extension "pg_orrery" already exists, skipping
-- ============================================================
-- Test observer: Eagle, Idaho (~43.7N, ~116.4W, 800m)
-- Mid-latitude location with normal rise/set behavior.
-- ============================================================
-- Use a fixed epoch in northern hemisphere winter (Jan 15, 2024 midnight UTC)
-- Sun should rise around ~15:30 UTC (8:30 AM MST) and set around ~00:30 UTC next day
-- Sun rise/set (geometric)
SELECT sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS sun_rises;
sun_rises
-----------
t
(1 row)
SELECT sun_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS sun_sets;
sun_sets
----------
t
(1 row)
-- Sunrise should be within 24h of the epoch
SELECT extract(epoch FROM
sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
- '2024-01-15 00:00:00+00'::timestamptz) / 3600.0
BETWEEN 0 AND 24.0 AS sunrise_within_24h;
sunrise_within_24h
--------------------
t
(1 row)
-- Sunset should be within 24h of the epoch
SELECT extract(epoch FROM
sun_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
- '2024-01-15 00:00:00+00'::timestamptz) / 3600.0
BETWEEN 0 AND 24.0 AS sunset_within_24h;
sunset_within_24h
-------------------
t
(1 row)
-- ============================================================
-- Moon rise/set
-- ============================================================
SELECT moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS moon_rises;
moon_rises
------------
t
(1 row)
SELECT moon_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS moon_sets;
moon_sets
-----------
t
(1 row)
-- ============================================================
-- Planet rise/set (Jupiter -- typically visible in winter evening)
-- ============================================================
SELECT planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS jupiter_rises;
jupiter_rises
---------------
t
(1 row)
SELECT planet_next_set(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
IS NOT NULL AS jupiter_sets;
jupiter_sets
--------------
t
(1 row)
-- ============================================================
-- Refracted vs geometric: refracted sunrise earlier than geometric
-- ============================================================
SELECT sun_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
< sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
AS refracted_sunrise_earlier;
refracted_sunrise_earlier
---------------------------
t
(1 row)
SELECT sun_next_set_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
> sun_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
AS refracted_sunset_later;
refracted_sunset_later
------------------------
t
(1 row)
-- Refracted-geometric difference should be ~2-5 minutes (120-300 seconds)
SELECT abs(extract(epoch FROM
sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
- sun_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
BETWEEN 60 AND 600 AS refraction_offset_reasonable;
refraction_offset_reasonable
------------------------------
t
(1 row)
-- ============================================================
-- Consistency: rise_time of the NEXT rise should be ~24h later
-- ============================================================
SELECT extract(epoch FROM
sun_next_rise('(43.7,-116.4,800)'::observer,
sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
+ interval '1 minute')
- sun_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz))
/ 3600.0
BETWEEN 23.0 AND 25.0 AS next_rise_about_24h_later;
next_rise_about_24h_later
---------------------------
t
(1 row)
-- ============================================================
-- Circumpolar check: Sun from 70N in June (midnight sun)
-- Sun should NOT set within 7 days
-- ============================================================
SELECT sun_next_set('(70.0,25.0,0)'::observer, '2024-06-21 00:00:00+00'::timestamptz)
IS NULL AS midnight_sun_no_set;
midnight_sun_no_set
---------------------
t
(1 row)
-- ============================================================
-- Never-rises check: Sun from 70N in December (polar night)
-- Sun should NOT rise within 7 days
-- ============================================================
SELECT sun_next_rise('(70.0,25.0,0)'::observer, '2024-12-21 00:00:00+00'::timestamptz)
IS NULL AS polar_night_no_rise;
polar_night_no_rise
---------------------
t
(1 row)
-- ============================================================
-- Error cases
-- ============================================================
-- Invalid body_id
DO $$ BEGIN PERFORM planet_next_rise(0, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'body_id=0: %', SQLERRM; END $$;
NOTICE: body_id=0: planet_next_rise: body_id 0 must be 1-8 (Mercury-Neptune)
DO $$ BEGIN PERFORM planet_next_rise(3, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'body_id=3(Earth): %', SQLERRM; END $$;
NOTICE: body_id=3(Earth): cannot observe Earth from Earth
DO $$ BEGIN PERFORM planet_next_rise(9, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'body_id=9: %', SQLERRM; END $$;
NOTICE: body_id=9: planet_next_rise: body_id 9 must be 1-8 (Mercury-Neptune)