New equatorial type (24 bytes: RA/Dec/distance) captures apparent coordinates of date — what the observation pipeline computes at precession step 3 but was discarding before hour angle conversion. Matches telescope GoTo mount conventions. 24 new SQL functions (82 → 106 total): - equatorial type I/O + 3 accessors (eq_ra, eq_dec, eq_distance) - Satellite RA/Dec: eci_to_equatorial (topocentric), eci_to_equatorial_geo (geocentric) - Solar system equatorial: planet/sun/moon/small_body_equatorial - Atmospheric refraction: Bennett (1982) with domain clamp at -1 deg - Refracted pass prediction: predict_passes_refracted (horizon at -0.569 deg) - Stellar proper motion: star_observe_pm, star_equatorial_pm (Hipparcos/Gaia convention) - Light-time correction: planet/sun/small_body_observe_apparent, *_equatorial_apparent - DE equatorial variants: planet_equatorial_de, moon_equatorial_de Also includes v0.8.0 orbital_elements type (MPC parser, small_body_observe), GiST 0-based indexing fix, llms.txt updates, and doc improvements. All 18 regression suites pass. Zero build warnings (GCC + Clang).
121 lines
2.7 KiB
C
121 lines
2.7 KiB
C
/*
|
|
* refraction_funcs.c -- Atmospheric refraction for pg_orrery
|
|
*
|
|
* Bennett's (1982) formula for standard atmosphere, with optional
|
|
* pressure/temperature correction per Meeus (1991).
|
|
*
|
|
* Domain guard: clamp geometric elevation to -1 deg before tan()
|
|
* evaluation. Below that, Bennett's formula is outside its valid
|
|
* range and we return 0.
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
#include "fmgr.h"
|
|
#include "types.h"
|
|
#include <math.h>
|
|
|
|
PG_FUNCTION_INFO_V1(atmospheric_refraction);
|
|
PG_FUNCTION_INFO_V1(atmospheric_refraction_ext);
|
|
PG_FUNCTION_INFO_V1(topo_elevation_apparent);
|
|
|
|
#define RAD_TO_DEG (180.0 / M_PI)
|
|
#define DEG_TO_RAD (M_PI / 180.0)
|
|
|
|
/*
|
|
* bennett_refraction -- core Bennett (1982) formula
|
|
*
|
|
* Input: geometric elevation in degrees
|
|
* Output: refraction correction in degrees (>= 0)
|
|
*
|
|
* R = 1/tan(h + 7.31/(h + 4.4)) arcminutes
|
|
* where h is the geometric elevation in degrees.
|
|
*
|
|
* The formula diverges near h = -4.4 deg; clamp to -1 deg
|
|
* (below which the atmosphere model is meaningless anyway).
|
|
*/
|
|
static double
|
|
bennett_refraction(double h_deg)
|
|
{
|
|
double h, R;
|
|
|
|
if (h_deg < -1.0)
|
|
return 0.0;
|
|
|
|
h = fmax(h_deg, -1.0);
|
|
|
|
/* Bennett's formula: arcminutes */
|
|
R = 1.0 / tan((h + 7.31 / (h + 4.4)) * DEG_TO_RAD);
|
|
|
|
if (!isfinite(R))
|
|
return 0.0;
|
|
|
|
/* Convert arcminutes to degrees */
|
|
R /= 60.0;
|
|
|
|
if (R < 0.0)
|
|
R = 0.0;
|
|
|
|
return R;
|
|
}
|
|
|
|
|
|
/*
|
|
* atmospheric_refraction(elevation_deg) -> refraction_deg
|
|
*
|
|
* Standard atmosphere: P = 1010 mbar, T = 10 C.
|
|
*/
|
|
Datum
|
|
atmospheric_refraction(PG_FUNCTION_ARGS)
|
|
{
|
|
double h_deg = PG_GETARG_FLOAT8(0);
|
|
|
|
PG_RETURN_FLOAT8(bennett_refraction(h_deg));
|
|
}
|
|
|
|
|
|
/*
|
|
* atmospheric_refraction_ext(elevation_deg, pressure_mbar, temp_celsius)
|
|
* -> refraction_deg
|
|
*
|
|
* Meeus correction for non-standard atmosphere:
|
|
* R_corrected = R * (P / 1010.0) * (283.0 / (273.0 + T))
|
|
*/
|
|
Datum
|
|
atmospheric_refraction_ext(PG_FUNCTION_ARGS)
|
|
{
|
|
double h_deg = PG_GETARG_FLOAT8(0);
|
|
double P = PG_GETARG_FLOAT8(1);
|
|
double T = PG_GETARG_FLOAT8(2);
|
|
double R;
|
|
|
|
R = bennett_refraction(h_deg);
|
|
|
|
/* Meeus pressure/temperature correction */
|
|
R *= (P / 1010.0) * (283.0 / (273.0 + T));
|
|
|
|
if (!isfinite(R) || R < 0.0)
|
|
R = 0.0;
|
|
|
|
PG_RETURN_FLOAT8(R);
|
|
}
|
|
|
|
|
|
/*
|
|
* topo_elevation_apparent(topocentric) -> apparent_elevation_deg
|
|
*
|
|
* Geometric elevation from the topocentric type plus Bennett's
|
|
* atmospheric refraction correction.
|
|
*/
|
|
Datum
|
|
topo_elevation_apparent(PG_FUNCTION_ARGS)
|
|
{
|
|
pg_topocentric *topo = (pg_topocentric *) PG_GETARG_POINTER(0);
|
|
double el_deg;
|
|
double refr;
|
|
|
|
el_deg = topo->elevation * RAD_TO_DEG;
|
|
refr = bennett_refraction(el_deg);
|
|
|
|
PG_RETURN_FLOAT8(el_deg + refr);
|
|
}
|