An Astrological Engine Built on Astronomical Truth
"Moira" — the one who measures the thread.
Moira is a pure-Python astrological engine grounded in astronomical truth. Astronomy is the foundation. Astrology is the purpose. Every astrological output — longitude, house cusp, direction arc, time-lord boundary — is derived from a verifiable astronomical substrate: a JPL DE-series planetary kernel (de430, de440, or de441), IAU 2000A/2006 nutation and precession, and a sovereign fixed-star registry audited against SOFA/ERFA.
Moira was originally designed against DE441 for its extended date coverage (−13,000 to +17,000). The engine is kernel-agnostic: it accepts any compatible JPL SPK planetary kernel the user supplies. No particular release is assumed or bundled.
It is not a wrapper around Swiss Ephemeris or any other compiled library. Every stage of the reduction pipeline is implemented in readable, auditable Python with zero compiled binaries — from raw barycentric mechanics through light-time, aberration, deflection, and frame bias to the final ecliptic longitude.
Auditability. Every transformation — nutation, aberration, deflection, frame bias, topocentric parallax — is implemented in readable Python. No hidden pre-computation, no opaque binaries.
Precision. The planetary substrate is benchmarked against JPL Horizons and IAU ERFA. Fixed stars are audited against SOFA/ERFA anchor references from J1000 to J3000. Residuals are documented, not hidden.
Explicit policy. Computational choices — Delta-T branch, coordinate frame, ayanamsa definition, correction sequence — are declared, not ambient. Changing a policy is a visible act.
No runtime dependencies beyond jplephem. The IAU 2000A nutation series (1,365 lunisolar terms + 687 planetary terms) runs in pure Python. NumPy is an optional accelerator, not a requirement.
- Planets and luminaries — geocentric and topocentric reduction with iterative light-time, annual aberration, multi-body relativistic deflection (Sun, Jupiter, Saturn, Earth), IAU 2006 frame bias, and WGS-84 topocentric parallax.
- Fixed stars — sovereign registry of 1,809 named stars with proper motion, parallax, epoch propagation, and Stellar Quality classification. Audited anchor residual against SOFA/ERFA: 0.00048 arcseconds (J1000–J3000).
- Asteroid fleet — dedicated engines for classical asteroids (Ceres, Pallas, Juno, Vesta), Centaurs (Chiron, Pholus, Chariklo, Asbolus, Hylonome), and Trans-Neptunians (Ixion, Quaoar, Varuna, Orcus) via bundled SPK kernels. User-supplied
.bspkernels supported via the integrateddaf_writerfor any of the 887,000+ numbered minor planets in the JPL catalog. - Uranian / Hamburg School bodies — 8 hypothetical transneptunian planets (Cupido through Poseidon) plus Transpluto.
- Lunar nodes and apsides — True Node, Mean Node, Mean Lilith, True Lilith, and orbital nodes/apsides for all planetary bodies.
- Variable stars — phase and magnitude engine for eclipsing binaries and intrinsic variables; dedicated Algol API.
- Multiple star systems — Kepler orbital mechanics for visually resolvable pairs (Sirius AB, Alpha Centauri AB); catalog of 8 astrologically significant systems across VISUAL, WIDE, SPECTROSCOPIC, and OPTICAL types.
- House systems — 19 systems including Placidus, Koch, Regiomontanus, Campanus, Morinus, Porphyry, Whole Sign, Equal, APC, and Sunshine.
- Aspects — 22 zodiacal aspects with applying/separating/stationary motion-state detection; declination parallels and contra-parallels; antiscia and contra-antiscia.
- Aspect patterns — 21 multi-body configurations: T-Square, Grand Trine, Grand Cross, Yod, Kite, Mystic Rectangle, Stellium, Grand Sextile, Thor's Hammer, Boomerang Yod, and more.
- Midpoints — full midpoint matrix, midpoint trees, 90°/45°/22.5° dial projections, planetary pictures.
- Traditional dignities — domicile, exaltation, triplicity (diurnal/nocturnal), Egyptian and Ptolemaic terms, face, sect, hayz, and Almuten Figuris.
- Arabic Parts — 499 lots with dependency graphs and condition profiling.
- Hermetic decans — 36-decan system with computed positions for all ruling stars.
- Progressions — secondary, tertiary, minor, solar arc (longitude and right ascension), Naibod, ascendant arc; direct and converse variants for all methods.
- Primary directions — Placidus semi-arc and mundane; speculum computation; fixed-star targets.
- Returns — solar and lunar returns; planet returns.
- Time lords — annual and monthly profections; Firdaria (diurnal and nocturnal sequences, including Bonatti variant); Zodiacal Releasing (Vettius Valens method); Hyleg and Alcocoden.
- Vedic techniques — Vimshottari Dasha with nakshatra balance; sidereal positions; 27 nakshatra system; Varga/divisional charts (navamsa, dashamansa, dwadashamsa, saptamsa, trimshamsa).
- Eclipses — NASA-canon contact solver for solar and lunar eclipses; Saros series classification with heptagonal vertex labelling; local circumstance computation.
- Heliacal phenomena — heliacal rising and setting; acronychal rising and setting; planetary elongation extremes.
- Parans — paranatellonta field analysis with contour extraction and stability metrics.
- Occultations — lunar occultation of stars and planets; close-approach detection.
- Stations — retrograde stations with precise stationary-point search.
- Mapping — Astrocartography (ACG) lines for all planets; Local Space chart positions; Gauquelin sectors.
- Galactic coordinates — full equatorial-to-galactic transform and reference point catalog.
- Temporal systems — 28-mansion Arabic lunar stations (Manazil); Sothic cycle drift and Egyptian civil calendar conversion; void-of-course Moon windows.
- Harmonics — harmonic chart calculation, aspect-harmonic profiles, vibrational fingerprint analysis.
- Synastry — inter-chart aspects, house overlays, composite chart (midpoint method), Davison chart (spherical midpoint).
- Jones chart shapes — all 7 temperament types.
Moira initializes even when no planetary kernel is present. Kernel-dependent operations (for example chart()) raise a clear MissingEphemerisKernelError until a kernel is configured. See Kernel Setup below before executing planetary examples.
from datetime import datetime, timezone
from moira import Moira
m = Moira()
# 1. Planetary positions
chart = m.chart(datetime(2000, 1, 1, 12, 0, tzinfo=timezone.utc))
print(f"Sun: {chart.planets['Sun'].longitude:.6f} deg")
print(f"Moon: {chart.planets['Moon'].longitude:.6f} deg")
# 2. House cusps (Placidus, London)
from moira import HouseSystem
houses = m.houses(
datetime(2000, 1, 1, 12, 0, tzinfo=timezone.utc),
latitude=51.5074,
longitude=-0.1278,
system=HouseSystem.PLACIDUS,
)
print(f"ASC: {houses.asc:.4f} deg | MC: {houses.mc:.4f} deg")
# 3. Aspect patterns
from moira.patterns import find_all_patterns
patterns = find_all_patterns(chart.longitudes())
for p in patterns:
print(f"{p.name}: {', '.join(p.bodies)}")- Python 3.10 or later
jplephem >= 2.24(the only required runtime dependency)- A JPL DE-series planetary kernel (de430, de440, or de441 — not bundled; see below)
# Standard install (pure Python)
pip install moira-astro
# With NumPy acceleration for the nutation engine
pip install moira-astro[fast]Moira requires a JPL DE-series SPK planetary kernel for all planetary computation. No kernel is bundled — the files are large and the choice of release belongs to the user.
Supported kernels:
| Kernel | File | Size | Date range | Notes |
|---|---|---|---|---|
| DE441 | de441.bsp |
~3.1 GB | ~13 200 BCE – ~17 200 CE | Original design target; maximum date coverage |
| DE440 | de440.bsp |
~114 MB | 1550 BCE – 2650 CE | Current JPL standard; recommended for most users |
| DE430 | de430.bsp |
~128 MB | 1550 BCE – 2650 CE | Widely deployed predecessor to DE440 |
The easiest way to download and configure a kernel is the built-in Tkinter interface. It requires no extra dependencies — Tkinter ships with CPython on all platforms.
moira-kernel-managerThe window shows all supported kernels with extended descriptions (design rationale, date coverage, size trade-offs), live Installed/Missing status for each, and a real progress bar for downloads. You can also point Moira at a .bsp file already on disk without re-downloading.
What the GUI provides:
- Kernel list — planetary (de430, de440, de441) and supplemental (asteroids, small bodies) sections with size, date range, and status per row.
- Detail panel — selecting a row shows a full description of that kernel's coverage, accuracy, and when to prefer it over the alternatives.
- Download with progress — streams the selected kernel in the background; a progress bar tracks bytes received. A Cancel button interrupts the transfer and removes the partial file.
- Use selected — activates an installed kernel for the current session via
set_kernel_path(). - Browse… — open any
.bspfile already on disk and set it as the active kernel immediately.
# List all kernels and their status
moira-download-kernels --list
# Download all missing kernels (interactive prompt)
moira-download-kernels
# Download without prompting
moira-download-kernels --yesMoira()succeeds even if no kernel is installed. It auto-discovers any compatible kernel in the standard locations.m.is_kernel_available()reports kernel readiness.m.get_kernel_status()explains expected paths and remediation.m.available_kernelslists all installed compatible kernels.- Kernel-dependent calls raise
MissingEphemerisKernelErrorwith instructions.
Standard location: kernels/<filename>.bsp relative to the repository root, or ~/.moira/kernels/. The engine resolves either automatically.
Custom location: pass the path at construction, or call set_kernel_path() before the first Moira() instantiation:
from moira.spk_reader import set_kernel_path
from moira import Moira
set_kernel_path("/path/to/de440.bsp")
m = Moira()
print(m.is_kernel_available())
print(m.get_kernel_status())
print(m.available_kernels)Direct download links (JPL SSD):
- DE441: https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/de441.bsp
- DE440: https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/de440.bsp
- DE430: https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/de430.bsp
| Layer | Source | Bundled | Note |
|---|---|---|---|
| IAU 2000A/2006 nutation and precession tables | IAU | Yes | 2,414 terms; pure Python |
| DE-series planetary kernel | JPL | No | de430 (~115 MB), de440 (~114 MB), or de441 (~3.3 GB); download separately |
| Named star registry | Sovereign (star_registry.csv + JSON provenance) |
Yes | 1,809 stars; license-independent |
| Centaur kernel | Moira native | Yes | centaurs.bsp — Chiron, Pholus, Chariklo, Asbolus, Hylonome |
| Minor-body kernel | Moira native | Yes | minor_bodies.bsp — classical asteroids and select TNOs |
Moira is functionally identical with or without NumPy. When present, NumPy accelerates the IAU 2000A nutation evaluation from approximately 2.7 ms to 0.035 ms per call — a factor of roughly 79x. Numeric drift from the vectorised path is less than 3×10⁻¹⁶ degrees.
The acceleration matters most in phenomenon-searching loops (retrograde periods, eclipse searches, heliacal events, conjunction sweeps) where nutation is evaluated thousands of times. For single-chart work, the pure-Python path is adequate.
Moira is validated as a three-layer corpus. Each layer has its own correct evidence standard.
Astronomy layer — authoritative physical oracles first, enforced regression thereafter. References: IAU ERFA/SOFA, JPL Horizons, NASA catalogs, IERS.
Astrology layer — external chart software where stable and meaningful; doctrine-grounded invariants where no universal oracle exists. References: Swiss Ephemeris, Astro.com, canonical doctrine tables, structural invariants.
Experimental layer — subsystem-specific surfaces for sovereign or modern domains. Domains: sovereign fixed stars, variable stars, multiple star systems, galactic transforms, eclipse Saros classification.
Every validated claim must pass three gates:
- Gate of Source — inputs and reference data are tied to an independent authority.
- Gate of Flow — the computational path is explicit and inspectable.
- Gate of Oracle — outputs are benchmarked against an external reference appropriate to the domain.
When residuals remain, Moira documents them as model-basis differences rather than mislabeling them as engine defects. Two systems may be internally correct while answering different mathematical questions because of differing assumptions — for example, Delta-T branch, retarded-versus-geometric Moon treatment, or event-definition objective.
| Report | Verification Source |
|---|---|
VALIDATION_ASTRONOMY.md |
IAU ERFA/SOFA, JPL Horizons, NASA. Geocentric residual: 0.576 arcseconds (documented Delta-T divergence). |
VALIDATION_ASTROLOGY.md |
Swiss Ephemeris, Astro.com, canonical doctrine tables. Houses, ayanamshas, predictive cycles. |
VALIDATION_EXPERIMENTAL.md |
SOFA/ERFA, Swiss swetest, AAVSO, GCVS, binary orbit ephemerides. Sovereign stars, variable stars, multiple systems. |
graph TD
A[JPL Planetary Kernel\nChebyshev state vectors] --> B[SSB Barycentric Position\nkm · ICRF]
C[Sovereign Star Registry\n1809 named stars] --> D[Stellar Astrometric Position\nproper motion · parallax]
B --> E[1 · Light-Time Iteration\nbody at t − τ where τ = d/c]
E --> F[2 · Gravitational Deflection\nSun · Jupiter · Saturn · Earth]
F --> G[3 · Annual Aberration\nrelativistic · IAU SOFA]
G --> H[4 · IAU 2006 Frame Bias\nICRF → Mean Equator J2000]
D --> H
H --> I[5 · IAU 2006 Precession\nP03 polynomial series]
I --> J[6 · IAU 2000A Nutation\n1365 lunisolar + 687 planetary terms]
J --> K[True Equinox and Equator of Date]
K --> L[7 · Topocentric Parallax\nWGS-84 · optional]
K --> M[8 · Atmospheric Refraction\nSky positions only · optional]
K --> N[Ecliptic Projection\nTrue obliquity of date]
N --> O[Zodiacal Longitude · Latitude · Distance]
K --> P[Sidereal Frame · Ayanamsa\noptional]
K --> Q[House Cusps · 19 Systems\nrequires lat/lon]
The following traces every pipeline stage for Mars on 2000 January 1, 12:00 TT, using live DE441 kernel data. All numbers are from the running engine.
Time: JD_UT 2451545.000000 → JD_TT 2451545.000739 (ΔT = +63.807 s)
| Step | Operation | Vector / Value | Shift from Previous |
|---|---|---|---|
| 0 | DE441 kernel read — SSB → Mars | (206,980,508.6, −184,891.6, −5,666,529.8) km | — |
| 0 | DE441 kernel read — SSB → Earth | (−27,568,641.0, 132,361,060.2, 57,418,514.1) km | — |
| 0 | Geometric geocentric — Mars − Earth | distance: 276,697,408.2 km = 1.849608 AU | — |
| 1 | Light-time iteration — Mars at t − τ | τ = 0.010683 days = 15.383 min | 15.761 arcsec |
| 2 | Gravitational deflection — Sun + Jupiter + Saturn | sub-arcsecond bending of light path | 0.006 arcsec |
| 3 | Annual aberration — Earth velocity 29.786 km/s | relativistic displacement toward apex | 14.070 arcsec |
| 4 | IAU 2006 frame bias — ξ₀ = −16.617 mas, dε₀ = −6.819 mas | fixed ICRF → mean equinox J2000 rotation | 0.023 arcsec |
| 5 | IAU 2006 precession — P03 polynomial series | negligible at J2000 (reference epoch) | 0.016 arcsec |
| 6 | IAU 2000A nutation — Δψ = −13.932″, Δε = −5.769″ | true equator and equinox of date | 14.351 arcsec |
| 7 | Ecliptic projection — true obliquity ε = 23.437677° | λ = 327.963300° · β = −1.067779° · d = 1.849688 AU | — |
Final position: Aquarius 27° 57′ 48″ · distance 1.8497 AU · speed +0.7757°/day (direct)
Total pipeline correction from geometric to apparent: −43.760 arcsec
The largest contributors are nutation (−13.932″), annual aberration (−14.070″), and the combined light-time displacement (−15.761″). Gravitational deflection (0.006″) and frame bias (0.023″) are sub-arcsecond but non-negligible at sub-arcsecond accuracy targets.
Each correction stage can be toggled independently via planet_at(). The table below shows the measurable effect of disabling each stage on the Mars J2000.0 result.
| Parameter | Default | Effect on Mars J2000.0 longitude | Function |
|---|---|---|---|
apparent=True |
True |
Full pipeline active | planet_at() |
apparent=False |
— | Geometric position; all corrections skipped. Δ = +43.760 arcsec | planet_at() |
aberration=False |
— | Aberration stage skipped. Δ = +14.069 arcsec | planet_at() |
grav_deflection=False |
— | Deflection stage skipped. Δ = +0.003 arcsec | planet_at() |
nutation=False |
— | Nutation skipped; mean equinox used. Δ = +13.932 arcsec | planet_at() |
observer_lat/lon |
None |
When supplied, adds topocentric parallax (WGS-84). Effect: ~1° for Moon, <0.01″ beyond Jupiter | planet_at() |
refraction=True |
True |
Atmospheric refraction applied to altitude. Effect: ~0.57° at horizon | sky_position_at() |
delta_t_policy |
None |
Controls UT → TT conversion branch (IERS tables, polynomial, hybrid physical) | both |
The canonical documentation tree lives in wiki/. The flat moira.wiki/ Git wiki mirror is generated from it by python scripts/sync_git_wiki.py and should not be edited by hand.
| Document | Contents |
|---|---|
01_LIGHT_BOX_DOCTRINE.md |
The Light Box principle: transparency and derivation as design constraints. |
BEYOND_SWISS_EPHEMERIS.md |
Capabilities enabled by sovereign catalogs, explicit policy, and modern Python. |
CONSTITUTIONAL_PROCESS.md |
The Subsystem Constitutional Process — the development and governance protocol. |
MOIRA_ROADMAP.md |
Feature implementation status and mathematical accuracy register. |
MIT (c) 2026 Burkett