Validation
Reference engine checked against Swiss Ephemeris; TypeScript port checked against golden fixtures. CI runs both on every commit.
Reference vs Swiss Ephemeris 2.10
Python reference vs Swiss Ephemeris at hundreds of random instants in 1900–2099: apparent geocentric ecliptic longitude (true equinox of date), all bodies, angles and cusps at six latitudes including polar Iceland. Max and RMS disagreement in arcseconds:
| Body | Max | RMS | Note |
|---|---|---|---|
| Sun | 0.4″ | 0.2″ | |
| Moon (precise tier) | 2.5″ | 0.9″ | JPL DE423 fit (2010); DE423 vs DE440 is <0.1″ over this span |
| Moon (embedded series) | 9.6″ | 2.8″ | 60-term ELP abridged |
| Mercury | 0.5″ | 0.2″ | |
| Venus | 0.8″ | 0.2″ | |
| Mars | 0.7″ | 0.2″ | |
| Jupiter | 0.9″ | 0.3″ | |
| Saturn | 0.8″ | 0.4″ | |
| Uranus | 1.9″ | 0.7″ | series truncation; complete VSOP87 holds ≤1″ |
| Neptune | 4.6″ | 2.2″ | series truncation; complete VSOP87 holds ≤1″ |
| Pluto | 2.5″ | 1.0″ | series valid 1885-2099 |
| Chiron | 1.0″ | 0.3″ | JPL Horizons fit, 1850-2150 |
| Mean node | 0.1″ | 0.1″ | |
| True node | 0.8″ | 0.4″ | vs full JPL DE431 files; vs Swiss Ephemeris's BUILT-IN (Moshier) ephemeris expect up to ~1′ (measured: 50″ max, 8″ median, 300 epochs) — that is the built-in lunar theory's own node error, not ours |
| Ascendant / MC | 3.2″ | — | |
| Placidus cusps (all 12) | 3.2″ | — | |
| Mean Lilith | 1.3″ | 0.5″ | mean lunar apogee on the inclined orbit; latitude ≤0.1″ |
| Sidereal longitudes | — | — | ayanamsa model vs SE ≤0.005″ (Vondrák 2011, same model both sides); sidereal longitudes inherit each body's tropical bound |
| RA / Dec | 2.1″ | — | rotation is exact; bound tracks each body's ecliptic accuracy (Moon worst) |
| Topocentric Moon | 2.5″ | — | parallax model adds ≤0.1″ over the geocentric bound |
| House cusps, 8 new systems | 0.0″ | 0.0″ | Koch, Regiomontanus, Campanus, Alcabitius, Morinus, Meridian, Polich-Page, Vehlow: exact vs swe_houses_armc (200 polar-inclusive cases each) |
| Vertex / east point | 0.0″ | 0.0″ | exact vs swe_houses_armc |
| Magnitudes | 0.045 mag″ | — | Mallama 2018; Moon (Allen law) valid to phase angle 140° |
| Rise/set/meridian transit | 0.5 s″ | — | vs swe_rise_trans, 48 polar-inclusive cases per body; Moon bound tracks its position accuracy |
| Crossings / lunar phases | 4 s″ | — | vs swe_solcross/swe_mooncross and elongation root-finds |
| Stations | 55 s″ | — | ill-conditioned by nature: speed-zero slope ~0.01°/day² turns sub-arcsecond model differences into minutes |
| True Lilith (osc. apogee) | 187″ | — | hypersensitive to the lunar theory (~1/e amplification); SE's own Moshier-vs-DE difference dominates. 'True Lilith' values disagree across software at this scale |
| Ceres, Pallas, Juno, Vesta, Pholus | 1.0″ | 0.3″ | JPL Horizons fits 1850-2150 (residual <5e-6 AU); same geocentric pipeline as Chiron. No independent SE oracle here: SE's asteroid files are unavailable in Moshier mode |
| Uranian bodies (Cupido…Poseidon) | 2.3″ | — | Hamburg-school constant-element Kepler orbits, elements fitted to SE 2.10's built-in definitions (fit_uranian.py prints per-body figures; Zeus is fit-noise-limited at ~3″ heliocentric). Uranian practice works in arcminutes |
| Fixed stars (318-star catalog) | 0.3″ | — | HYG-derived catalog (ICRS J2000 + proper motions, full 3D space motion, Vondrák 2011 precession); vs swe_fixstar fed the same rows |
| Star-anchored ayanamsas | 0.5″ | — | galcent_0sag and true_citra computed from the apparent star; bound tracks the fixed-star chain (≤0.3″) plus the body's tropical accuracy |
| Gauquelin sectors | 0.0001 sectors″ | — | rise/set of disc center with refraction (SE method 3): exact to the rise/set bound |
| Eclipses (solar + lunar) | 9 s″ | — | times of maximum vs swe; types exact over 1990-2030 (92 lunar + 89 solar, zero mismatches); lunar magnitudes ≤0.0013 (Danjon parallax enlargement, recovered empirically). Contact times typically ≤15 s, minutes for grazing geometries. Global circumstances only — no ground paths |
Chart software usually displays to the arcminute (60″). Birth-time uncertainty dominates these deltas. Post-2025 instants also depend on each engine's ΔT extrapolation, which no model can pin down: Build Notes.
TypeScript port vs reference
3,218 golden checks (bodies, timescales, nutation, twelve house systems, fixed stars, Gauquelin sectors, eclipses, speeds, retrograde flags, polar Placidus fallback). Worst deviation 0.41 nano-arcseconds. Same algorithms in IEEE doubles; tolerance is far below astronomical relevance: a porting bug fails the build.
Cross-checks
Moon fit to JPL DE423: 0.19 km residual (≈0.1″). Chiron fit from Horizons vs Swiss Ephemeris asteroid file: 0.85″ worst-case. MCP aspect-date search verified hit-for-hit against an independent scan (nine Mars sextiles, minute agreement, retrograde triple pass included).
Reproduce
git clone the repo, npm install && npm run build && npm test. Discrepancy vs any professional ephemeris: open an issue with UTC instant and coordinates.
Range 1800–2149 (1850–2150 for precise Moon/Chiron). Placidus undefined above polar circles: falls back to whole-sign and reports the fallback in the response. Methods → Build notes →