-- refraction regression tests -- -- Tests atmospheric refraction (Bennett 1982), pressure/temperature -- correction, apparent elevation, and refracted pass prediction. \set boulder '''40.015N 105.270W 1655m'''::observer -- ISS TLE for pass prediction tests (inline in CTEs below) -- ============================================================ -- Test 1: Refraction at horizon (0 deg) ~ 0.57 deg -- Bennett: R = 1/tan(0 + 7.31/4.4) arcmin ~ 34.5 arcmin ~ 0.575 deg -- ============================================================ SELECT 'refr_horizon' AS test, round(atmospheric_refraction(0.0)::numeric, 2) AS refr_deg; -- ============================================================ -- Test 2: Refraction at 30 deg ~ 0.03 deg -- ============================================================ SELECT 'refr_30deg' AS test, round(atmospheric_refraction(30.0)::numeric, 3) AS refr_deg; -- ============================================================ -- Test 3: Refraction at zenith (90 deg) ~ 0 deg -- ============================================================ SELECT 'refr_zenith' AS test, round(atmospheric_refraction(90.0)::numeric, 4) AS refr_deg; -- ============================================================ -- Test 4: Refraction at 10 deg ~ 0.09 deg -- ============================================================ SELECT 'refr_10deg' AS test, round(atmospheric_refraction(10.0)::numeric, 3) AS refr_deg; -- ============================================================ -- Test 5: Domain guard - refraction at -5 deg should return 0 -- (below -1 deg validity range) -- ============================================================ SELECT 'refr_below_range' AS test, atmospheric_refraction(-5.0) AS refr_deg; -- ============================================================ -- Test 6: Domain guard - refraction at -10 deg returns 0 (no NaN) -- ============================================================ SELECT 'refr_deep_neg' AS test, atmospheric_refraction(-10.0) AS refr_deg, atmospheric_refraction(-10.0) = atmospheric_refraction(-10.0) AS is_finite; -- ============================================================ -- Test 7: Refraction at exactly -1 deg (edge of domain) -- Should return a small positive value -- ============================================================ SELECT 'refr_minus1' AS test, atmospheric_refraction(-1.0) > 0 AS positive; -- ============================================================ -- Test 8: Extended refraction with P/T correction -- Standard: P=1010, T=10 should match basic function -- ============================================================ SELECT 'refr_ext_standard' AS test, round(atmospheric_refraction_ext(0.0, 1010.0, 10.0)::numeric, 2) AS refr_deg, round(atmospheric_refraction(0.0)::numeric, 2) AS refr_basic, round(atmospheric_refraction_ext(0.0, 1010.0, 10.0)::numeric, 4) = round(atmospheric_refraction(0.0)::numeric, 4) AS match; -- ============================================================ -- Test 9: Extended refraction - cold high-altitude -- At P=700 mbar, T=-20 C, refraction should be reduced -- ============================================================ SELECT 'refr_ext_cold' AS test, round(atmospheric_refraction_ext(0.0, 700.0, -20.0)::numeric, 2) AS refr_deg, atmospheric_refraction_ext(0.0, 700.0, -20.0) < atmospheric_refraction(0.0) AS less_than_standard; -- ============================================================ -- Test 10: Extended refraction - hot sea level -- At P=1013, T=35 C, refraction should be slightly different -- ============================================================ SELECT 'refr_ext_hot' AS test, round(atmospheric_refraction_ext(0.0, 1013.0, 35.0)::numeric, 2) AS refr_deg; -- ============================================================ -- Test 11: Apparent elevation for a topocentric observation -- Sun near horizon: geometric el small -> apparent el higher -- ============================================================ SELECT 'apparent_el' AS test, round(topo_elevation(sun_observe(:boulder, '2024-03-20 00:30:00+00'))::numeric, 1) AS geometric, round(topo_elevation_apparent(sun_observe(:boulder, '2024-03-20 00:30:00+00'))::numeric, 1) AS apparent, topo_elevation_apparent(sun_observe(:boulder, '2024-03-20 00:30:00+00')) > topo_elevation(sun_observe(:boulder, '2024-03-20 00:30:00+00')) AS refraction_positive; -- ============================================================ -- Test 12: Apparent elevation for star high up (refraction small) -- Polaris from Boulder has el ~49 deg; refraction ~0.01 deg -- ============================================================ SELECT 'apparent_el_high' AS test, round(topo_elevation_apparent( star_observe(2.530303, 89.2641, :boulder, '2024-06-15 04:00:00+00'))::numeric, 1) AS apparent_deg; -- ============================================================ -- Test 13: Refracted pass prediction returns results -- Using the ISS TLE, should find passes in a week window -- ============================================================ WITH iss AS ( SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025 2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle AS t ) SELECT 'refracted_passes' AS test, count(*) > 0 AS has_passes FROM iss, predict_passes_refracted( t, :boulder, '2024-01-02 00:00:00+00', '2024-01-09 00:00:00+00'); -- ============================================================ -- Test 14: Refracted passes find at least as many as standard -- Because refracted horizon is -0.569 deg, satellites visible ~35s earlier -- ============================================================ SELECT 'refracted_more_passes' AS test, (SELECT count(*) FROM predict_passes_refracted( '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025 2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle, :boulder, '2024-01-02 00:00:00+00', '2024-01-09 00:00:00+00')) >= (SELECT count(*) FROM predict_passes( '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025 2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle, :boulder, '2024-01-02 00:00:00+00', '2024-01-09 00:00:00+00')) AS refracted_ge_standard; -- ============================================================ -- Test 15: Monotonicity - refraction decreases with elevation -- ============================================================ SELECT 'refr_monotonic' AS test, atmospheric_refraction(0.0) > atmospheric_refraction(10.0) AS r0_gt_r10, atmospheric_refraction(10.0) > atmospheric_refraction(30.0) AS r10_gt_r30, atmospheric_refraction(30.0) > atmospheric_refraction(60.0) AS r30_gt_r60, atmospheric_refraction(60.0) > atmospheric_refraction(90.0) AS r60_gt_r90;