Add 4 refracted rise/set functions completing the rise/set feature set: - planet_next_rise/set_refracted: -0.569 deg threshold (refraction only, point source — even Jupiter at opposition is only 24 arcsec) - moon_next_rise/set_refracted: -0.833 deg threshold (refraction + mean semidiameter, same as Sun) Add IAU constellation identification from Roman (1987) CDS VI/42: - 357 boundary segments covering all 88 constellations - Precesses J2000 coordinates to B1875.0 epoch for lookup - Two overloads: constellation(equatorial) and constellation(float8, float8) - IMMUTABLE (compiled-in static data) 141 -> 147 SQL objects. 24 -> 25 regression suites. All 25 pass.
220 lines
8.7 KiB
Plaintext
220 lines
8.7 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)
|
|
|
|
-- ============================================================
|
|
-- Planet refracted rise/set (v0.14.0)
|
|
-- ============================================================
|
|
-- Planet refracted rise should be earlier than geometric
|
|
SELECT planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
< planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
AS planet_refracted_rise_earlier;
|
|
planet_refracted_rise_earlier
|
|
-------------------------------
|
|
t
|
|
(1 row)
|
|
|
|
-- Planet refracted set should be later than geometric
|
|
SELECT planet_next_set_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
> planet_next_set(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
AS planet_refracted_set_later;
|
|
planet_refracted_set_later
|
|
----------------------------
|
|
t
|
|
(1 row)
|
|
|
|
-- Planet refraction offset should be reasonable (30-300 seconds)
|
|
SELECT abs(extract(epoch FROM
|
|
planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
- planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
|
BETWEEN 30 AND 300 AS planet_refraction_offset_reasonable;
|
|
planet_refraction_offset_reasonable
|
|
-------------------------------------
|
|
t
|
|
(1 row)
|
|
|
|
-- ============================================================
|
|
-- Moon refracted rise/set (v0.14.0)
|
|
-- ============================================================
|
|
-- Moon refracted rise should be earlier than geometric
|
|
SELECT moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
< moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
AS moon_refracted_rise_earlier;
|
|
moon_refracted_rise_earlier
|
|
-----------------------------
|
|
t
|
|
(1 row)
|
|
|
|
-- Moon refracted set should be later than geometric
|
|
SELECT moon_next_set_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
> moon_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
AS moon_refracted_set_later;
|
|
moon_refracted_set_later
|
|
--------------------------
|
|
t
|
|
(1 row)
|
|
|
|
-- Moon refraction offset should be reasonable (60-600 seconds)
|
|
SELECT abs(extract(epoch FROM
|
|
moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
|
- moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
|
BETWEEN 60 AND 600 AS moon_refraction_offset_reasonable;
|
|
moon_refraction_offset_reasonable
|
|
-----------------------------------
|
|
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)
|