mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
e69c0714b9
Pierwszy increment implementacji warstwy logicznej (ścieżka A). LOG-24: interfejs EphemerisEngine z dwoma backendami — SkyfieldEngine (własny, permisywny: Skyfield MIT + dane JPL public domain) oraz RemoteEngine (klient izolowanej usługi swisseph). Fabryka + leniwa inicjalizacja; endpointy /chart/positions i /chart/compare. LOG-01: pozycje obiektów (długość/szerokość ekliptyczna, prędkość, kierunek, formaty: w znaku / absolutny / dziesiętny). LOG-25/28: harness porównawczy (compare.py) z progami tolerancji oraz wspólny kontrakt parzystości; pełen zestaw testów. LOG-27: services/engine-swisseph — osobna, opcjonalna usługa AGPL (pyswisseph, tryb Moshiera), licencjonowana osobno, w compose pod profilem "comparison"; nie wchodzi do zamkniętego produktu. Walidacja: SkyfieldEngine zgadza się ze Swiss Ephemeris co do ~1" dla wszystkich 10 obiektów na horoskopie referencyjnym (30.04.1984, Warszawa); 12 testów przechodzi (silnik B pomijany gdy nieskonfigurowany). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
1.8 KiB
Python
45 lines
1.8 KiB
Python
"""Walidacja silnika własnego względem wyroczni (LOG-01 + LOG-25).
|
|
|
|
Porównujemy pozycje policzone Skyfieldem ze znanymi wartościami Swiss Ephemeris
|
|
(astro.com) dla horoskopu referencyjnego. To dokładnie mechanizm LOG-25 — tyle
|
|
że wyrocznią są tu zapisane wcześniej wartości referencyjne zamiast żywej usługi
|
|
swisseph. Tolerancja 2' (120") z zapasem na różnicę barycentrum/centrum planety.
|
|
"""
|
|
from app.engine.compare import compare_positions
|
|
from app.engine.models import ObjectPosition
|
|
|
|
# obiekt -> (długość absolutna w stopniach, retrogradacja) — Swiss Ephemeris / astro.com
|
|
REFERENCE = {
|
|
"Sun": (40.139167, False), # Tau 10°08'21"
|
|
"Moon": (30.551389, False), # Tau 0°33'05"
|
|
"Mercury": (27.383889, True), # Ari 27°23'02" Rx
|
|
"Venus": (27.676944, False), # Ari 27°40'37"
|
|
"Mars": (234.541111, True), # Sco 24°32'28" Rx
|
|
"Jupiter": (282.961667, True), # Cap 12°57'42" Rx
|
|
"Saturn": (223.310833, True), # Sco 13°18'39" Rx
|
|
"Uranus": (252.813333, True), # Sag 12°48'48" Rx
|
|
"Neptune": (271.220833, True), # Cap 1°13'15" Rx
|
|
"Pluto": (210.478889, True), # Sco 0°28'44" Rx
|
|
}
|
|
|
|
TOLERANCE_ARCSEC = 120.0
|
|
|
|
|
|
def _reference_positions():
|
|
return [
|
|
ObjectPosition(name, lon, 0.0, (-1.0 if retro else 1.0), retro)
|
|
for name, (lon, retro) in REFERENCE.items()
|
|
]
|
|
|
|
|
|
def test_positions_match_swisseph_reference(own_engine, reference_moment):
|
|
got = own_engine.positions(reference_moment)
|
|
report = compare_positions(got, _reference_positions(), lon_tol_arcsec=TOLERANCE_ARCSEC)
|
|
assert report.ok, report.summary()
|
|
|
|
|
|
def test_retrograde_flags_match(own_engine, reference_moment):
|
|
got = {p.name: p for p in own_engine.positions(reference_moment)}
|
|
for name, (_lon, retro) in REFERENCE.items():
|
|
assert got[name].retrograde == retro, f"{name}: kierunek niezgodny"
|