From e15428d610a4bd44f42636e2409966fb80c35f86 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 21 Feb 2026 18:23:59 -0700 Subject: [PATCH] Update CLAUDE.md and docs reference pages for v0.9.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CLAUDE.md: 82→106 functions, 8→9 types, 16→18 test suites, new file listings - New functions-refraction.mdx: Bennett refraction, P/T correction, apparent elevation, refracted passes - types.mdx: add equatorial type (24 bytes, apparent RA/Dec/distance of date) - functions-satellite.mdx: add eci_to_equatorial, eci_to_equatorial_geo, predict_passes_refracted - functions-solar-system.mdx: add 7 equatorial + light-time apparent functions - functions-stars-comets.mdx: add proper motion, equatorial, apparent functions - functions-de.mdx: add planet_equatorial_de, moon_equatorial_de - astro.config.mjs: add refraction page to sidebar --- CLAUDE.md | 53 ++-- docs/astro.config.mjs | 1 + .../content/docs/reference/functions-de.mdx | 65 ++++ .../docs/reference/functions-refraction.mdx | 209 +++++++++++++ .../docs/reference/functions-satellite.mdx | 115 ++++++++ .../docs/reference/functions-solar-system.mdx | 259 ++++++++++++++++ .../docs/reference/functions-stars-comets.mdx | 277 +++++++++++++++++- docs/src/content/docs/reference/types.mdx | 55 +++- 8 files changed, 1011 insertions(+), 23 deletions(-) create mode 100644 docs/src/content/docs/reference/functions-refraction.mdx diff --git a/CLAUDE.md b/CLAUDE.md index fbc6d5d..546e9f7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,9 +1,9 @@ # pg_orrery — A Database Orrery for PostgreSQL ## What This Is -A database orrery — celestial mechanics types and functions for PostgreSQL. Native C extension using PGXS, 82 SQL functions, 8 custom types, covering satellites (SGP4/SDP4), planets (VSOP87 + optional JPL DE441), Moon (ELP2000-82B), 19 planetary moons (L1.2/TASS17/GUST86/MarsSat), stars, comets, asteroids (MPC catalog), Jupiter radio bursts, and interplanetary Lambert transfers. +A database orrery — celestial mechanics types and functions for PostgreSQL. Native C extension using PGXS, 106 SQL functions, 9 custom types, covering satellites (SGP4/SDP4), planets (VSOP87 + optional JPL DE441), Moon (ELP2000-82B), 19 planetary moons (L1.2/TASS17/GUST86/MarsSat), stars (with proper motion), comets, asteroids (MPC catalog), Jupiter radio bursts, interplanetary Lambert transfers, equatorial RA/Dec coordinates, atmospheric refraction, and light-time correction. -**Current version:** 0.8.0 on branch `phase/spgist-orbital-trie` +**Current version:** 0.9.0 on branch `phase/spgist-orbital-trie` **Repository:** https://git.supported.systems/warehack.ing/pg_orrery **Documentation:** https://pg-orrery.warehack.ing @@ -11,7 +11,7 @@ A database orrery — celestial mechanics types and functions for PostgreSQL. Na ```bash make PG_CONFIG=/usr/bin/pg_config # Compile with PGXS sudo make install PG_CONFIG=/usr/bin/pg_config # Install extension -make installcheck PG_CONFIG=/usr/bin/pg_config # Run 16 regression test suites +make installcheck PG_CONFIG=/usr/bin/pg_config # Run 18 regression test suites ``` Requires: PostgreSQL 17 development headers, GCC, Make. @@ -27,7 +27,7 @@ Image: `git.supported.systems/warehack.ing/pg_orrery:pg17` ## Project Layout ``` -pg_orrery.control # Extension metadata (version 0.8.0) +pg_orrery.control # Extension metadata (version 0.9.0) Makefile # PGXS build + Docker targets sql/ pg_orrery--0.1.0.sql # v0.1.0: satellite types/functions/operators @@ -38,6 +38,7 @@ sql/ pg_orrery--0.6.0.sql # v0.6.0: conjunction screening pg_orrery--0.7.0.sql # v0.7.0: GiST improvements pg_orrery--0.8.0.sql # v0.8.0: orbital_elements type + MPC parser (82 functions) + pg_orrery--0.9.0.sql # v0.9.0: equatorial type, refraction, proper motion, light-time (106 functions) pg_orrery--0.1.0--0.2.0.sql # Migration: v0.1.0 → v0.2.0 (adds solar system) pg_orrery--0.2.0--0.3.0.sql # Migration: v0.2.0 → v0.3.0 (adds DE ephemeris) pg_orrery--0.3.0--0.4.0.sql # Migration: v0.3.0 → v0.4.0 @@ -45,6 +46,7 @@ sql/ pg_orrery--0.5.0--0.6.0.sql # Migration: v0.5.0 → v0.6.0 pg_orrery--0.6.0--0.7.0.sql # Migration: v0.6.0 → v0.7.0 pg_orrery--0.7.0--0.8.0.sql # Migration: v0.7.0 → v0.8.0 (orbital_elements type) + pg_orrery--0.8.0--0.9.0.sql # Migration: v0.8.0 → v0.9.0 (equatorial, refraction, proper motion, light-time) src/ pg_orrery.c # PG_MODULE_MAGIC + _PG_init() (GUC registration) types.h # All struct definitions + constants + DE body ID mapping @@ -55,7 +57,7 @@ src/ observer_type.c # Observer type with flexible string parsing sgp4_funcs.c # sgp4_propagate(), _safe(), _series(), tle_distance() coord_funcs.c # eci_to_geodetic(), eci_to_topocentric(), ground_track() - pass_funcs.c # next_pass(), predict_passes(), pass_visible() + pass_funcs.c # next_pass(), predict_passes(), predict_passes_refracted(), pass_visible() gist_tle.c # GiST operator class (&&, <->) # --- Solar System (v0.2.0) --- vsop87.c / vsop87.h # VSOP87 planetary ephemeris (Bretagnon 1988) @@ -63,11 +65,13 @@ src/ precession.c / precession.h # IAU 1976 precession (Lieske 1979) sidereal_time.c / .h # GMST calculation (Vallado Eq. 3-47) elliptic_to_rectangular.c/.h # Orbital element conversions - planet_funcs.c # planet_observe(), planet_heliocentric(), sun/moon_observe() - star_funcs.c # star_observe(), star_observe_safe() + planet_funcs.c # planet_observe(), planet_heliocentric(), sun/moon_observe(), _equatorial(), _apparent() + star_funcs.c # star_observe(), star_observe_safe(), star_equatorial(), star_observe_pm(), star_equatorial_pm() kepler_funcs.c # kepler_propagate(), comet_observe() kepler.h # Shared Kepler solver interface (kepler_position()) - orbital_elements_type.c # orbital_elements type, MPC parser, small_body_observe() + orbital_elements_type.c # orbital_elements type, MPC parser, small_body_observe/equatorial/apparent() + equatorial_funcs.c # equatorial type I/O, accessors, satellite/planet/sun/moon RA/Dec + refraction_funcs.c # atmospheric_refraction(), _ext(), topo_elevation_apparent() l12.c / l12.h # L1.2 Galilean moon theory (Lieske 1998) tass17.c / tass17.h # TASS 1.7 Saturn moon theory (Vienne & Duriez 1995) gust86.c / gust86.h # GUST86 Uranus moon theory (Laskar & Jacobson 1987) @@ -117,20 +121,22 @@ All types are fixed-size, `STORAGE = plain`, `ALIGNMENT = double`. No TOAST over | `pass_event` | 48 | AOS/MAX/LOS times + max_el + AOS/LOS azimuth | | `heliocentric` | 24 | x, y, z in AU (ecliptic J2000 frame) | | `orbital_elements` | 72 | Classical Keplerian elements for comets/asteroids (epoch, q, e, inc, omega, Omega, tp, H, G) | +| `equatorial` | 24 | Apparent RA (hours), Dec (degrees), distance (km) — of date | -## Function Domains (82 total) +## Function Domains (106 total) | Domain | Theory | Key Functions | Count | |--------|--------|---------------|-------| -| Satellite | SGP4/SDP4 (Brouwer 1959) | `observe()`, `predict_passes()`, `ground_track()` | 22 | -| Planets | VSOP87 (Bretagnon 1988) | `planet_observe()`, `planet_heliocentric()` | 3 | -| Sun/Moon | VSOP87 + ELP2000-82B | `sun_observe()`, `moon_observe()` | 2 | +| Satellite | SGP4/SDP4 (Brouwer 1959) | `observe()`, `predict_passes()`, `eci_to_equatorial()` | 25 | +| Planets | VSOP87 (Bretagnon 1988) | `planet_observe()`, `planet_equatorial()`, `planet_observe_apparent()` | 7 | +| Sun/Moon | VSOP87 + ELP2000-82B | `sun_observe()`, `moon_observe()`, `sun/moon_equatorial()` | 6 | | Planetary moons | L1.2, TASS17, GUST86, MarsSat | `galilean_observe()`, `saturn_moon_observe()` | 4 | -| Stars | J2000 + IAU 1976 precession | `star_observe()`, `star_observe_safe()` | 2 | -| Comets/asteroids | Two-body Keplerian + MPC | `small_body_observe()`, `oe_from_mpc()`, `kepler_propagate()` | 16 | +| Stars | J2000 + IAU 1976 precession | `star_observe()`, `star_equatorial()`, `star_observe_pm()` | 5 | +| Comets/asteroids | Two-body Keplerian + MPC | `small_body_observe()`, `small_body_equatorial()`, `oe_from_mpc()` | 19 | +| Refraction | Bennett (1982) | `atmospheric_refraction()`, `predict_passes_refracted()` | 4 | | Jupiter radio | Carr et al. (1983) | `jupiter_burst_probability()` | 3 | | Transfers | Lambert (Izzo 2015) | `lambert_transfer()`, `lambert_c3()` | 2 | -| DE ephemeris | JPL DE440/441 (optional) | `planet_observe_de()`, `moon_observe_de()` | 11 | +| DE ephemeris | JPL DE440/441 (optional) | `planet_observe_de()`, `planet_equatorial_de()` | 13 | | GiST index | Altitude-band approximation | `&&` (overlap), `<->` (distance) | 8 | | Diagnostics | -- | `pg_orrery_ephemeris_info()` | 1 | @@ -187,6 +193,7 @@ All functions are `PARALLEL SAFE`. VSOP87/ELP82B functions are `IMMUTABLE` (comp #define GAUSS_K 0.01720209895 /* AU^(3/2)/day */ #define OBLIQUITY_J2000 0.40909280422232897 /* 23.4392911 deg in radians */ #define J2000_JD 2451545.0 /* 2000 Jan 1.5 TT */ +#define C_LIGHT_AU_DAY 173.1446327 /* speed of light in AU/day */ ``` ## JPL DE Ephemeris (Optional) @@ -231,6 +238,8 @@ Every `_de()` function mirrors an existing VSOP87 function: | `saturn_moon_observe_de()` | `saturn_moon_observe()` | STABLE | | `uranus_moon_observe_de()` | `uranus_moon_observe()` | STABLE | | `mars_moon_observe_de()` | `mars_moon_observe()` | STABLE | +| `planet_equatorial_de()` | `planet_equatorial()` | STABLE | +| `moon_equatorial_de()` | `moon_equatorial()` | STABLE | | `pg_orrery_ephemeris_info()` | — | STABLE | ## Vendored SGP4/SDP4 @@ -252,7 +261,7 @@ All numerical logic is byte-identical to upstream. Verified against 518 Vallado ## Testing -16 regression test suites via `make installcheck`: +18 regression test suites via `make installcheck`: | Suite | What it tests | |-------|--------------| @@ -268,14 +277,16 @@ All numerical logic is byte-identical to upstream. Verified against 518 Vallado | moon_observe | Galilean/Saturn/Uranus/Mars moons, Io phase, Jupiter CML, burst probability | | lambert_transfer | Lambert solver, lambert_c3, pork chop grid, error handling | | de_ephemeris | DE function fallback to VSOP87, cross-provider consistency, error handling | -| vallado_518 | 518 Vallado test vectors (AIAA 2006-6753-Rev1), per-satellite breakdown | | od_fit | Orbit determination from ECI/topocentric/angles-only observations | -| orbital_elements | orbital_elements type I/O, MPC parser, small_body_observe/heliocentric | | spgist_tle | SP-GiST orbital trie index operations | +| orbital_elements | orbital_elements type I/O, MPC parser, small_body_observe/heliocentric | +| equatorial | equatorial type I/O, RA/Dec for planets/stars/satellites, proper motion, light-time | +| refraction | Bennett refraction, P/T correction, apparent elevation, refracted pass prediction | +| vallado_518 | 518 Vallado test vectors (AIAA 2006-6753-Rev1), per-satellite breakdown | ### PG Version Matrix -Test all 16 regression suites + DE reader unit test across PostgreSQL 14-18 using Docker: +Test all 18 regression suites + DE reader unit test across PostgreSQL 14-18 using Docker: ```bash make test-matrix # Full matrix (PG 14-18) @@ -299,9 +310,9 @@ Logs saved to `test/matrix-logs/pg${ver}.log`. The script reuses the Dockerfile **Live:** https://pg-orrery.warehack.ing -Starlight docs at `docs/` — 42 MDX pages covering all domains. +Starlight docs at `docs/` — 44 MDX pages covering all domains. -Sections: Getting Started, Guides (9 domain walkthroughs incl. DE ephemeris), Workflow Translation (Skyfield/Horizons/GMAT/Radio Jupiter Pro comparisons), Reference (all 82 functions incl. DE variants + orbital_elements), Architecture (Hamilton's principles, constant custody, observation pipeline), Performance (benchmarks). +Sections: Getting Started, Guides (9 domain walkthroughs incl. DE ephemeris), Workflow Translation (Skyfield/Horizons/GMAT/Radio Jupiter Pro comparisons), Reference (all 106 functions incl. DE variants, equatorial, refraction), Architecture (Hamilton's principles, constant custody, observation pipeline), Performance (benchmarks). ### Local Development ```bash diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index e15802c..d97b624 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -96,6 +96,7 @@ export default defineConfig({ { label: "Functions: Stars & Comets", slug: "reference/functions-stars-comets" }, { label: "Functions: Radio", slug: "reference/functions-radio" }, { label: "Functions: Transfers", slug: "reference/functions-transfers" }, + { label: "Functions: Refraction", slug: "reference/functions-refraction" }, { label: "Functions: DE Ephemeris", slug: "reference/functions-de" }, { label: "Functions: Orbit Determination", slug: "reference/functions-od" }, { label: "Operators & Indexes", slug: "reference/operators-gist" }, diff --git a/docs/src/content/docs/reference/functions-de.mdx b/docs/src/content/docs/reference/functions-de.mdx index d3fa2b2..5fb2d56 100644 --- a/docs/src/content/docs/reference/functions-de.mdx +++ b/docs/src/content/docs/reference/functions-de.mdx @@ -303,6 +303,71 @@ mars_moon_observe_de(moon_id int4, obs observer, t timestamptz) → topocentric --- +## planet_equatorial_de + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of a planet using JPL DE ephemeris. Falls back to VSOP87 plus the equatorial conversion when DE is unavailable. + +### Signature + +```sql +planet_equatorial_de(body_id int4, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `body_id` | `int4` | Planet identifier (1-8, excluding 0 and 3) | +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Compare DE vs VSOP87 equatorial coordinates for Mars +SELECT round(eq_ra(planet_equatorial(4, now()))::numeric, 6) AS ra_vsop87, + round(eq_ra(planet_equatorial_de(4, now()))::numeric, 6) AS ra_de, + round(eq_dec(planet_equatorial(4, now()))::numeric, 6) AS dec_vsop87, + round(eq_dec(planet_equatorial_de(4, now()))::numeric, 6) AS dec_de; +``` + +--- + +## moon_equatorial_de + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of the Moon using JPL DE ephemeris. Falls back to ELP2000-82B plus the equatorial conversion when DE is unavailable. + +### Signature + +```sql +moon_equatorial_de(t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Moon RA/Dec via DE +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM moon_equatorial_de(now()) AS e; +``` + +--- + ## pg_orrery_ephemeris_info Returns diagnostic information about the current ephemeris provider. diff --git a/docs/src/content/docs/reference/functions-refraction.mdx b/docs/src/content/docs/reference/functions-refraction.mdx new file mode 100644 index 0000000..9013a0d --- /dev/null +++ b/docs/src/content/docs/reference/functions-refraction.mdx @@ -0,0 +1,209 @@ +--- +title: "Functions: Atmospheric Refraction" +sidebar: + order: 7 +--- + +import { Aside, Tabs, TabItem } from "@astrojs/starlight/components"; + +Functions for computing atmospheric refraction corrections using Bennett's (1982) empirical formula. Earth's atmosphere bends light from celestial objects, making them appear higher above the horizon than their true geometric position. Near the horizon, refraction is approximately 0.57 degrees --- enough to extend satellite visibility windows by roughly 35 seconds at AOS and LOS, and to make the Sun appear above the horizon when it has already geometrically set. + +--- + +## atmospheric_refraction + +Computes the atmospheric refraction correction in degrees for a given geometric elevation using Bennett's (1982) formula under standard atmosphere conditions (pressure 1010 mbar, temperature 10 C). The domain is clamped at -1 degree to avoid singularity in the cotangent term. + +### Signature + +```sql +atmospheric_refraction(elevation_deg float8) → float8 +``` + +### Parameters + +| Parameter | Type | Unit | Description | +|-----------|------|------|-------------| +| `elevation_deg` | `float8` | degrees | Geometric elevation of the object above the horizon | + +### Returns + +Refraction correction in degrees. Always positive --- add this value to the geometric elevation to get the apparent elevation. At the horizon (0 degrees), refraction is approximately 0.57 degrees. It drops rapidly with increasing elevation and is negligible above 45 degrees. + + + +### Example + +```sql +-- Refraction at various elevations +SELECT elevation, + round(atmospheric_refraction(elevation)::numeric, 4) AS refraction_deg +FROM unnest(ARRAY[-1, 0, 5, 10, 20, 45, 90]) AS elevation; +``` + +```sql +-- How much does refraction shift the Sun at sunset? +SELECT round(atmospheric_refraction(0)::numeric, 4) AS horizon_refraction_deg; +``` + +--- + +## atmospheric_refraction_ext + +Computes atmospheric refraction with a pressure and temperature correction factor applied to Bennett's formula, following the Meeus formulation. Useful for high-altitude observatories or extreme weather conditions where standard atmosphere assumptions break down. + +### Signature + +```sql +atmospheric_refraction_ext(elevation_deg float8, pressure_mbar float8, temp_celsius float8) → float8 +``` + +### Parameters + +| Parameter | Type | Unit | Description | +|-----------|------|------|-------------| +| `elevation_deg` | `float8` | degrees | Geometric elevation of the object above the horizon | +| `pressure_mbar` | `float8` | mbar | Atmospheric pressure at the observer | +| `temp_celsius` | `float8` | C | Air temperature at the observer | + +### Returns + +Refraction correction in degrees, adjusted for the given pressure and temperature. The correction factor is `(P / 1010) * (283 / (273 + T))` applied to the standard Bennett formula result. + +### Example + +```sql +-- Refraction at Mauna Kea summit (4205m, ~620 mbar, -2C) +SELECT round(atmospheric_refraction_ext(5.0, 620.0, -2.0)::numeric, 4) AS refraction_mauna_kea, + round(atmospheric_refraction(5.0)::numeric, 4) AS refraction_standard; +``` + +```sql +-- Compare standard vs corrected refraction across a range of elevations +SELECT elevation, + round(atmospheric_refraction(elevation)::numeric, 4) AS standard, + round(atmospheric_refraction_ext(elevation, 850.0, -10.0)::numeric, 4) AS high_altitude_cold +FROM unnest(ARRAY[0, 2, 5, 10, 30]) AS elevation; +``` + +--- + +## topo_elevation_apparent + +Convenience function that returns the apparent elevation of an object by adding the atmospheric refraction correction to the geometric elevation stored in a `topocentric` value. The result is in degrees. + +### Signature + +```sql +topo_elevation_apparent(topocentric) → float8 +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| (unnamed) | `topocentric` | A topocentric observation result from any `*_observe` function | + +### Returns + +Apparent elevation in degrees --- the geometric elevation plus the Bennett refraction correction under standard atmosphere. Always higher than the geometric `topo_elevation()` value. + +### Example + +```sql +-- Compare geometric vs apparent elevation for the Moon +SELECT round(topo_elevation(t)::numeric, 3) AS geometric_el, + round(topo_elevation_apparent(t)::numeric, 3) AS apparent_el, + round(topo_elevation_apparent(t) - topo_elevation(t)::numeric, 4) AS refraction_correction +FROM moon_observe('40.0N 105.3W 1655m'::observer, now()) AS t; +``` + +```sql +-- Find objects that are geometrically below horizon but visible due to refraction +SELECT norad_id, + round(topo_elevation(o)::numeric, 3) AS geometric_el, + round(topo_elevation_apparent(o)::numeric, 3) AS apparent_el +FROM satellite_catalog, + observe_safe(tle, '40.0N 105.3W 1655m'::observer, now()) AS o +WHERE o IS NOT NULL + AND topo_elevation(o) < 0 + AND topo_elevation_apparent(o) > 0; +``` + +--- + +## predict_passes_refracted + +Predicts satellite passes using a refracted horizon threshold instead of the geometric horizon. The geometric threshold is set to -0.569 degrees, which corresponds to the apparent horizon after atmospheric refraction. This means satellites become visible approximately 35 seconds earlier at AOS and remain visible approximately 35 seconds later at LOS compared to `predict_passes`. + +### Signature + +```sql +predict_passes_refracted( + tle tle, + obs observer, + start_time timestamptz, + end_time timestamptz, + min_el float8 DEFAULT 0.0 +) → SETOF pass_event +``` + +### Parameters + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `tle` | `tle` | | Satellite TLE | +| `obs` | `observer` | | Observer location | +| `start_time` | `timestamptz` | | Start of the search window | +| `end_time` | `timestamptz` | | End of the search window | +| `min_el` | `float8` | `0.0` | Minimum peak elevation in degrees. Passes whose maximum elevation is below this threshold are excluded. | + +### Returns + +A set of `pass_event` records, ordered by AOS time. Each pass will show slightly earlier AOS and later LOS times compared to `predict_passes` due to the refracted horizon. + + + +### Example + +```sql +-- Compare geometric vs refracted pass predictions for the ISS +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 tle +) +SELECT pass_aos_time(p) AS rise, + pass_max_elevation(p) AS max_el, + pass_los_time(p) AS set, + pass_duration(p) AS dur +FROM iss, + predict_passes_refracted(tle, '40.0N 105.3W 1655m'::observer, + now(), now() + interval '24 hours', 10.0) AS p; +``` + +```sql +-- How much extra visibility does refraction add? +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 tle +), +geo AS ( + SELECT pass_duration(p) AS dur + FROM iss, predict_passes(tle, '40.0N 105.3W 1655m'::observer, + now(), now() + interval '24 hours') AS p + LIMIT 1 +), +refr AS ( + SELECT pass_duration(p) AS dur + FROM iss, predict_passes_refracted(tle, '40.0N 105.3W 1655m'::observer, + now(), now() + interval '24 hours') AS p + LIMIT 1 +) +SELECT geo.dur AS geometric_duration, + refr.dur AS refracted_duration +FROM geo, refr; +``` diff --git a/docs/src/content/docs/reference/functions-satellite.mdx b/docs/src/content/docs/reference/functions-satellite.mdx index 11d24c5..367d995 100644 --- a/docs/src/content/docs/reference/functions-satellite.mdx +++ b/docs/src/content/docs/reference/functions-satellite.mdx @@ -527,3 +527,118 @@ FROM satellite_catalog WHERE pass_visible(tle, '40.0N 105.3W 1655m'::observer, '2024-06-15 02:00:00+00', '2024-06-15 10:00:00+00'); ``` + +--- + +## eci_to_equatorial + +Converts a TEME ECI position to topocentric apparent equatorial coordinates (RA/Dec) for a given observer. The observer's position is subtracted from the satellite's ECI vector to produce parallax-corrected coordinates. For LEO satellites, observer parallax is approximately 1 degree. + +### Signature + +```sql +eci_to_equatorial(pos eci_position, obs observer, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `pos` | `eci_position` | TEME ECI position and velocity | +| `obs` | `observer` | Observer location on Earth | +| `t` | `timestamptz` | Time of the position (for sidereal time computation) | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from the observer's perspective. + +### Example + +```sql +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 tle +) +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 1) AS dist_km +FROM iss, + eci_to_equatorial( + sgp4_propagate(tle, now()), + '40.0N 105.3W 1655m'::observer, + now() + ) AS e; +``` + +--- + +## eci_to_equatorial_geo + +Converts a TEME ECI position to geocentric apparent equatorial coordinates (RA/Dec). This is the direction of the position vector as seen from Earth's center, independent of any observer location. + +### Signature + +```sql +eci_to_equatorial_geo(pos eci_position, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `pos` | `eci_position` | TEME ECI position | +| `t` | `timestamptz` | Time of the position | + +### Returns + +An `equatorial` with geocentric RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Geocentric RA/Dec of the ISS +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 tle +) +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg +FROM iss, + eci_to_equatorial_geo(sgp4_propagate(tle, now()), now()) AS e; +``` + +--- + +## predict_passes_refracted + +Predicts satellite passes using a refracted horizon threshold (-0.569 degrees geometric) instead of the geometric horizon. Atmospheric refraction makes satellites visible approximately 35 seconds earlier at AOS and later at LOS. + + + +### Signature + +```sql +predict_passes_refracted( + tle tle, + obs observer, + start_time timestamptz, + end_time timestamptz, + min_el float8 DEFAULT 0.0 +) → SETOF pass_event +``` + +### Parameters + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `tle` | `tle` | | Satellite TLE | +| `obs` | `observer` | | Observer location | +| `start_time` | `timestamptz` | | Start of the search window | +| `end_time` | `timestamptz` | | End of the search window | +| `min_el` | `float8` | `0.0` | Minimum peak elevation in degrees | + +### Returns + +A set of `pass_event` records with refraction-extended visibility windows. diff --git a/docs/src/content/docs/reference/functions-solar-system.mdx b/docs/src/content/docs/reference/functions-solar-system.mdx index 5672eb3..8596d77 100644 --- a/docs/src/content/docs/reference/functions-solar-system.mdx +++ b/docs/src/content/docs/reference/functions-solar-system.mdx @@ -228,3 +228,262 @@ FROM generate_series( moon_observe('40.0N 105.3W 1655m'::observer, t) AS m WHERE topo_elevation(m) > 0; ``` + +--- + +## planet_equatorial + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of a planet at a given time using VSOP87. The heliocentric ecliptic position is converted to geocentric equatorial and precessed to the date of observation via IAU 1976 precession. + +### Signature + +```sql +planet_equatorial(body_id int4, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `body_id` | `int4` | Planet identifier (1-8, same as `planet_heliocentric` excluding 0 and 3) | +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Current RA/Dec of all planets +SELECT body_id, + CASE body_id + WHEN 1 THEN 'Mercury' WHEN 2 THEN 'Venus' + WHEN 4 THEN 'Mars' WHEN 5 THEN 'Jupiter' + WHEN 6 THEN 'Saturn' WHEN 7 THEN 'Uranus' + WHEN 8 THEN 'Neptune' + END AS planet, + round(eq_ra(e)::numeric, 4) AS ra_h, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM unnest(ARRAY[1,2,4,5,6,7,8]) AS body_id, + planet_equatorial(body_id, now()) AS e; +``` + +--- + +## sun_equatorial + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of the Sun at a given time using VSOP87. + +### Signature + +```sql +sun_equatorial(t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Sun's current RA/Dec +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM sun_equatorial(now()) AS e; +``` + +--- + +## moon_equatorial + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of the Moon at a given time using ELP2000-82B. + +### Signature + +```sql +moon_equatorial(t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- Moon's current RA/Dec and distance +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM moon_equatorial(now()) AS e; +``` + +```sql +-- Moon's RA/Dec path over one lunation at daily intervals +SELECT t::date AS date, + round(eq_ra(e)::numeric, 3) AS ra_h, + round(eq_dec(e)::numeric, 3) AS dec_deg +FROM generate_series( + now(), now() + interval '29 days', interval '1 day' + ) AS t, + moon_equatorial(t) AS e; +``` + +--- + +## planet_observe_apparent + +Computes the topocentric position of a planet with single-iteration light-time correction. The planet's position is evaluated at the retarded time (observation time minus light travel time), while Earth's position is evaluated at the observation time. Uses VSOP87. + +### Signature + +```sql +planet_observe_apparent(body_id int4, obs observer, t timestamptz) → topocentric +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `body_id` | `int4` | Planet identifier (1-8, excluding 0 and 3) | +| `obs` | `observer` | Observer location on Earth | +| `t` | `timestamptz` | Observation time | + +### Returns + +A `topocentric` with azimuth, elevation, range (km), and range rate (km/s). The range reflects the geometric distance at the retarded time. + + + +### Example + +```sql +-- Compare geometric vs light-time corrected Mars observation +SELECT round(topo_azimuth(g)::numeric, 4) AS az_geo, + round(topo_azimuth(a)::numeric, 4) AS az_apparent, + round(topo_elevation(g)::numeric, 4) AS el_geo, + round(topo_elevation(a)::numeric, 4) AS el_apparent +FROM planet_observe(4, '40.0N 105.3W 1655m'::observer, now()) AS g, + planet_observe_apparent(4, '40.0N 105.3W 1655m'::observer, now()) AS a; +``` + +--- + +## sun_observe_apparent + +Computes the topocentric position of the Sun with light-time correction (approximately 8.3 minutes). Uses VSOP87. + +### Signature + +```sql +sun_observe_apparent(obs observer, t timestamptz) → topocentric +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `obs` | `observer` | Observer location on Earth | +| `t` | `timestamptz` | Observation time | + +### Returns + +A `topocentric` with azimuth, elevation, range (km), and range rate (km/s). + +### Example + +```sql +-- Sun position with light-time correction +SELECT round(topo_azimuth(t)::numeric, 4) AS az, + round(topo_elevation(t)::numeric, 4) AS el +FROM sun_observe_apparent('40.0N 105.3W 1655m'::observer, now()) AS t; +``` + +--- + +## planet_equatorial_apparent + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of a planet with light-time correction. The planet is evaluated at the retarded time. Uses VSOP87. + +### Signature + +```sql +planet_equatorial_apparent(body_id int4, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `body_id` | `int4` | Planet identifier (1-8, excluding 0 and 3) | +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km), corrected for light travel time. + +### Example + +```sql +-- Light-time corrected RA/Dec of Jupiter +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM planet_equatorial_apparent(5, now()) AS e; +``` + +--- + +## moon_equatorial_apparent + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of the Moon with light-time correction (approximately 1.3 seconds). Uses ELP2000-82B. + +### Signature + +```sql +moon_equatorial_apparent(t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km), corrected for light travel time. + + + +### Example + +```sql +-- Compare geometric vs light-time corrected Moon RA/Dec +SELECT round(eq_ra(g)::numeric, 6) AS ra_geo, + round(eq_ra(a)::numeric, 6) AS ra_apparent, + round(eq_dec(g)::numeric, 6) AS dec_geo, + round(eq_dec(a)::numeric, 6) AS dec_apparent +FROM moon_equatorial(now()) AS g, + moon_equatorial_apparent(now()) AS a; +``` diff --git a/docs/src/content/docs/reference/functions-stars-comets.mdx b/docs/src/content/docs/reference/functions-stars-comets.mdx index bf04a4d..0d38184 100644 --- a/docs/src/content/docs/reference/functions-stars-comets.mdx +++ b/docs/src/content/docs/reference/functions-stars-comets.mdx @@ -34,7 +34,7 @@ star_observe(ra_hours float8, dec_deg float8, obs observer, t timestamptz) → t A `topocentric` with azimuth and elevation in degrees. `topo_range` is 0 (infinite distance). `topo_range_rate` is 0. ### Example @@ -396,3 +396,278 @@ FROM asteroid_catalog, WHERE topo_elevation(t) > 20 ORDER BY topo_elevation(t) DESC; ``` + +--- + +## star_equatorial + +Computes the apparent equatorial coordinates (RA/Dec) of a star at a given time by precessing J2000 catalog coordinates to the date of observation via IAU 1976 precession. Does not account for proper motion. + +### Signature + +```sql +star_equatorial(ra_hours float8, dec_deg float8, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Unit | Description | +|-----------|------|------|-------------| +| `ra_hours` | `float8` | hours | Right Ascension in J2000 (0-24) | +| `dec_deg` | `float8` | degrees | Declination in J2000 (-90 to +90) | +| `t` | `timestamptz` | | Evaluation time | + +### Returns + +An `equatorial` with RA (hours) and Dec (degrees) precessed to the date of observation. Distance is 0 (infinite). + +### Example + +```sql +-- Precessed RA/Dec of Sirius at current date +SELECT round(eq_ra(e)::numeric, 6) AS ra_hours, + round(eq_dec(e)::numeric, 6) AS dec_deg +FROM star_equatorial(6.7525, -16.7161, now()) AS e; +``` + +--- + +## star_observe_pm + +Computes the topocentric position of a star with full proper motion, parallax, and radial velocity corrections. The proper motion convention follows Hipparcos/Gaia: `pm_ra` is mu_alpha * cos(delta) in milliarcseconds per year. Cos(dec) is clamped near the poles to avoid division by zero. + +### Signature + +```sql +star_observe_pm( + ra_hours float8, + dec_deg float8, + pm_ra_masyr float8, + pm_dec_masyr float8, + parallax_mas float8, + rv_kms float8, + obs observer, + t timestamptz +) → topocentric +``` + +### Parameters + +| Parameter | Type | Unit | Description | +|-----------|------|------|-------------| +| `ra_hours` | `float8` | hours | J2000 Right Ascension (0-24) | +| `dec_deg` | `float8` | degrees | J2000 Declination (-90 to +90) | +| `pm_ra_masyr` | `float8` | mas/yr | Proper motion in RA (mu_alpha * cos(delta), Hipparcos/Gaia convention) | +| `pm_dec_masyr` | `float8` | mas/yr | Proper motion in Declination | +| `parallax_mas` | `float8` | mas | Trigonometric parallax (0 if unknown) | +| `rv_kms` | `float8` | km/s | Radial velocity (0 if unknown) | +| `obs` | `observer` | | Observer location | +| `t` | `timestamptz` | | Observation time | + +### Returns + +A `topocentric` with azimuth, elevation, range (km from parallax, or 0 if parallax is 0), and range rate (km/s). + + + +### Example + +```sql +-- Observe Barnard's Star (large proper motion: 10.3 arcsec/yr total) +-- Hipparcos: RA 17h 57m 48.5s, Dec +4d 41m 36.2s +-- pm_ra = -798.58 mas/yr, pm_dec = 10328.12 mas/yr +-- parallax = 548.31 mas, rv = -110.6 km/s +SELECT round(topo_azimuth(t)::numeric, 2) AS az, + round(topo_elevation(t)::numeric, 2) AS el, + round(topo_range(t)::numeric, 0) AS dist_km +FROM star_observe_pm( + 17.9635, 4.6934, -- J2000 RA/Dec + -798.58, 10328.12, -- proper motion (mas/yr) + 548.31, -110.6, -- parallax (mas), RV (km/s) + '40.0N 105.3W 1655m'::observer, now() +) AS t; +``` + +--- + +## star_equatorial_pm + +Computes the apparent equatorial coordinates of a star with proper motion, parallax, and radial velocity corrections. Returns precessed coordinates of date. Distance is derived from parallax if greater than zero. + +### Signature + +```sql +star_equatorial_pm( + ra_hours float8, + dec_deg float8, + pm_ra_masyr float8, + pm_dec_masyr float8, + parallax_mas float8, + rv_kms float8, + t timestamptz +) → equatorial +``` + +### Parameters + +| Parameter | Type | Unit | Description | +|-----------|------|------|-------------| +| `ra_hours` | `float8` | hours | J2000 Right Ascension (0-24) | +| `dec_deg` | `float8` | degrees | J2000 Declination (-90 to +90) | +| `pm_ra_masyr` | `float8` | mas/yr | Proper motion in RA (mu_alpha * cos(delta)) | +| `pm_dec_masyr` | `float8` | mas/yr | Proper motion in Declination | +| `parallax_mas` | `float8` | mas | Trigonometric parallax (0 if unknown) | +| `rv_kms` | `float8` | km/s | Radial velocity (0 if unknown) | +| `t` | `timestamptz` | | Evaluation time | + +### Returns + +An `equatorial` with RA (hours) and Dec (degrees) corrected for proper motion and precessed to date. Distance in km from parallax (0 if parallax is 0 or unknown). + +### Example + +```sql +-- RA/Dec of Barnard's Star, corrected for proper motion +SELECT round(eq_ra(e)::numeric, 6) AS ra_hours, + round(eq_dec(e)::numeric, 6) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM star_equatorial_pm( + 17.9635, 4.6934, + -798.58, 10328.12, + 548.31, -110.6, + now() +) AS e; +``` + +```sql +-- Track the motion of Barnard's Star over 50 years +SELECT extract(year from t) AS year, + round(eq_ra(e)::numeric, 6) AS ra_h, + round(eq_dec(e)::numeric, 6) AS dec_deg +FROM generate_series( + '2000-01-01'::timestamptz, + '2050-01-01'::timestamptz, + interval '10 years' + ) AS t, + star_equatorial_pm(17.9635, 4.6934, -798.58, 10328.12, 548.31, -110.6, t) AS e; +``` + +--- + +## small_body_equatorial + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of a comet or asteroid from its `orbital_elements`. The body is propagated on a Keplerian orbit, and Earth's position is obtained from VSOP87. + +### Signature + +```sql +small_body_equatorial(oe orbital_elements, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `oe` | `orbital_elements` | Bundled orbital elements | +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km) from Earth's center. + +### Example + +```sql +-- RA/Dec of Ceres +WITH ceres AS ( + SELECT oe_from_mpc( + '00001 3.33 0.12 K24AM 60.07966 73.42937 80.26860 10.58664 0.0789126 0.21406048 2.7660961 0 MPO838504 8738 115 1801-2024 0.65 M-v 30k MPCLINUX 0000 (1) Ceres 20240825' + ) AS oe +) +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM ceres, + small_body_equatorial(oe, now()) AS e; +``` + +--- + +## small_body_observe_apparent + +Computes the topocentric position of a comet or asteroid with single-iteration light-time correction. The body is propagated at the retarded time (observation time minus light travel time), while Earth's position is evaluated at the observation time via VSOP87. + +### Signature + +```sql +small_body_observe_apparent(oe orbital_elements, obs observer, t timestamptz) → topocentric +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `oe` | `orbital_elements` | Bundled orbital elements | +| `obs` | `observer` | Observer location on Earth | +| `t` | `timestamptz` | Observation time | + +### Returns + +A `topocentric` with azimuth, elevation, range (km), and range rate (km/s), corrected for light travel time. + +### Example + +```sql +-- Observe Ceres with light-time correction from Boulder +WITH ceres AS ( + SELECT oe_from_mpc( + '00001 3.33 0.12 K24AM 60.07966 73.42937 80.26860 10.58664 0.0789126 0.21406048 2.7660961 0 MPO838504 8738 115 1801-2024 0.65 M-v 30k MPCLINUX 0000 (1) Ceres 20240825' + ) AS oe +) +SELECT round(topo_azimuth(t)::numeric, 2) AS az, + round(topo_elevation(t)::numeric, 2) AS el, + round((topo_range(t) / 149597870.7)::numeric, 4) AS dist_au +FROM ceres, + small_body_observe_apparent(oe, '40.0N 105.3W 1655m'::observer, now()) AS t; +``` + +--- + +## small_body_equatorial_apparent + +Computes the geocentric apparent equatorial coordinates (RA/Dec) of a comet or asteroid with light-time correction. The body is propagated at the retarded time. + +### Signature + +```sql +small_body_equatorial_apparent(oe orbital_elements, t timestamptz) → equatorial +``` + +### Parameters + +| Parameter | Type | Description | +|-----------|------|-------------| +| `oe` | `orbital_elements` | Bundled orbital elements | +| `t` | `timestamptz` | Evaluation time | + +### Returns + +An `equatorial` with RA (hours), Dec (degrees), and distance (km), corrected for light travel time. + +### Example + +```sql +-- Light-time corrected RA/Dec of Ceres +WITH ceres AS ( + SELECT oe_from_mpc( + '00001 3.33 0.12 K24AM 60.07966 73.42937 80.26860 10.58664 0.0789126 0.21406048 2.7660961 0 MPO838504 8738 115 1801-2024 0.65 M-v 30k MPCLINUX 0000 (1) Ceres 20240825' + ) AS oe +) +SELECT round(eq_ra(e)::numeric, 4) AS ra_hours, + round(eq_dec(e)::numeric, 4) AS dec_deg, + round(eq_distance(e)::numeric, 0) AS dist_km +FROM ceres, + small_body_equatorial_apparent(oe, now()) AS e; +``` diff --git a/docs/src/content/docs/reference/types.mdx b/docs/src/content/docs/reference/types.mdx index 8135926..12ccae4 100644 --- a/docs/src/content/docs/reference/types.mdx +++ b/docs/src/content/docs/reference/types.mdx @@ -6,7 +6,7 @@ sidebar: import { Aside, Tabs, TabItem } from "@astrojs/starlight/components"; -pg_orrery defines eight fixed-size base types and one SQL composite type that represent the core data structures of orbital mechanics. Each base type has a fixed on-disk size, a text I/O format for readability, and accessor functions for extracting individual fields. +pg_orrery defines nine fixed-size base types and one SQL composite type that represent the core data structures of orbital mechanics. Each base type has a fixed on-disk size, a text I/O format for readability, and accessor functions for extracting individual fields. ## tle @@ -338,6 +338,59 @@ FROM ceres; --- +## equatorial + +**Size:** 24 bytes + +Apparent equatorial coordinates of date. Stores three double-precision values: right ascension (radians internally, displayed as hours in the range [0, 24)), declination (radians internally, displayed as degrees in the range [-90, 90]), and distance in km. + +For solar system bodies, these are J2000 coordinates precessed to the date of observation via IAU 1976 precession. For satellites, these are TEME frame RA/Dec, which approximates coordinates of date to arcsecond accuracy. + +### Input Format + +A parenthesized tuple of three values: + +``` +(ra_hours,dec_degrees,distance_km) +``` + +```sql +SELECT '(4.29220000,20.60000000,885412345.678)'::equatorial; +``` + +### Accessor Functions + +| Function | Return Type | Unit | Description | +|----------|-------------|------|-------------| +| `eq_ra(equatorial)` | `float8` | hours | Right ascension [0, 24) | +| `eq_dec(equatorial)` | `float8` | degrees | Declination [-90, 90] | +| `eq_distance(equatorial)` | `float8` | km | Distance (0 for stars without parallax) | + +```sql +-- Geocentric RA/Dec of Jupiter +SELECT eq_ra(e) AS ra_hours, + eq_dec(e) AS dec_deg, + eq_distance(e) AS dist_km +FROM planet_equatorial(5, now()) AS e; +``` + +```sql +-- Compare RA/Dec of all planets +SELECT body_id, + CASE body_id + WHEN 1 THEN 'Mercury' WHEN 2 THEN 'Venus' + WHEN 4 THEN 'Mars' WHEN 5 THEN 'Jupiter' + WHEN 6 THEN 'Saturn' WHEN 7 THEN 'Uranus' + WHEN 8 THEN 'Neptune' + END AS planet, + round(eq_ra(e)::numeric, 4) AS ra_h, + round(eq_dec(e)::numeric, 4) AS dec_deg +FROM unnest(ARRAY[1,2,4,5,6,7,8]) AS body_id, + planet_equatorial(body_id, now()) AS e; +``` + +--- + ## observer_window **Type:** SQL composite (variable-length)