feat(upstream): merge a6f47abd engine, MCP, and orchestrator
Three-way-merge calculation modules and pl9-export into the product fork while keeping commercial API routes, Raman ayanamsa, and the consultation contract as a keypath superset. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+58
-26
@@ -70,6 +70,24 @@ def _estimate_sun_sign(birth_month: int, birth_day: int) -> int:
|
||||
return 0 # fallback
|
||||
|
||||
|
||||
def _muntha_from_natal_ascendant(natal_asc_sign_idx: int, completed_years: int) -> Dict:
|
||||
"""Advance Muntha from the natal ascendant, one sign per completed year."""
|
||||
muntha_sign_idx = (int(natal_asc_sign_idx) + int(completed_years)) % 12
|
||||
return {
|
||||
'status': 'used',
|
||||
'muntha_sign_idx': muntha_sign_idx,
|
||||
'muntha_sign': SIGNS[muntha_sign_idx],
|
||||
'muntha_lord': SIGN_LORDS[SIGNS[muntha_sign_idx]],
|
||||
'natal_asc_sign_idx': int(natal_asc_sign_idx),
|
||||
'natal_asc_sign': SIGNS[int(natal_asc_sign_idx)],
|
||||
'age': int(completed_years),
|
||||
'formula': (
|
||||
f'(natal ascendant {SIGNS[int(natal_asc_sign_idx)]} + '
|
||||
f'completed years {int(completed_years)}) mod 12 = {SIGNS[muntha_sign_idx]}'
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 工具函数
|
||||
# =========================================================================
|
||||
@@ -115,7 +133,7 @@ def _datetime_to_jd_ut(dt: datetime) -> float:
|
||||
|
||||
|
||||
def _get_sun_lon_jd(jd_ut: float, ayanamsa_name: str = 'lahiri') -> Optional[float]:
|
||||
"""计算给定 JD (UT) 的太阳恒星黄经(Lahiri)"""
|
||||
"""计算给定 JD (UT) 的太阳恒星黄经(默认 Raman)"""
|
||||
if not HAS_SWE:
|
||||
return None
|
||||
try:
|
||||
@@ -138,7 +156,7 @@ def find_solar_return_ut(
|
||||
tz: float = 0.0,
|
||||
max_iter: int = 30,
|
||||
tol_deg: float = 0.0003, # ~1 arcsec
|
||||
ayanamsa_name: str = 'lahiri',
|
||||
ayanamsa_name: str = 'raman',
|
||||
) -> Dict:
|
||||
"""
|
||||
计算太阳返照(Solar Return)精确 UT 时刻。
|
||||
@@ -176,7 +194,7 @@ def _find_solar_return_swe(
|
||||
target_year: int,
|
||||
max_iter: int,
|
||||
tol_deg: float,
|
||||
ayanamsa_name: str = 'lahiri',
|
||||
ayanamsa_name: str = 'raman',
|
||||
) -> Dict:
|
||||
"""使用 swisseph 精确计算太阳返照时刻(Newton 迭代法)"""
|
||||
# 近似起始点:出生日期在目标年份的同一天
|
||||
@@ -278,7 +296,7 @@ def calc_solar_return_chart(
|
||||
birth_hour: int, birth_minute: int,
|
||||
birth_lat: float, birth_lon: float, birth_tz: float,
|
||||
target_year: int,
|
||||
ayanamsa_name: str = 'lahiri',
|
||||
ayanamsa_name: str = 'raman',
|
||||
) -> Dict:
|
||||
"""
|
||||
计算太阳返照盘(Varshaphala)。
|
||||
@@ -402,7 +420,7 @@ def solar_return_full_report(
|
||||
birth_hour: int, birth_minute: int,
|
||||
birth_lat: float, birth_lon: float, birth_tz: float,
|
||||
target_year: int,
|
||||
ayanamsa_name: str = 'lahiri',
|
||||
ayanamsa_name: str = 'raman',
|
||||
) -> Dict:
|
||||
"""
|
||||
太阳返照盘完整报告(Varshaphala 年运分析)。
|
||||
@@ -456,27 +474,31 @@ def solar_return_full_report(
|
||||
'age': sr['age'],
|
||||
}
|
||||
planet_lons = sr['planet_lons']
|
||||
sr_planets = sr.get('chart', {}).get('planets', {})
|
||||
tajika_planets = {
|
||||
pn: {
|
||||
'longitude': pd.get('degree_raw', pd.get('degree')),
|
||||
'speed': pd.get('speed'),
|
||||
}
|
||||
for pn, pd in sr_planets.items()
|
||||
if pn in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn')
|
||||
and isinstance(pd, dict)
|
||||
and pd.get('degree_raw', pd.get('degree')) is not None
|
||||
and pd.get('speed') is not None
|
||||
}
|
||||
asc_sign_idx = sr['asc_sign_idx']
|
||||
|
||||
# 2. Muntha(正确算法:从返照盘太阳星座开始数)
|
||||
# 2. Muntha advances from the natal ascendant, not the solar sign.
|
||||
try:
|
||||
# Solar return sun sign = birth sun sign (by definition of solar return)
|
||||
sr_sun_sign = int(planet_lons.get('Sun', 0) / 30) % 12
|
||||
muntha_sign = (sr_sun_sign + age) % 12
|
||||
muntha_note = ''
|
||||
if degraded:
|
||||
muntha_note = '(基于查表法估算太阳星座,实际Muntha可能偏差±1星座)'
|
||||
result['muntha'] = {
|
||||
'muntha_sign_idx': muntha_sign,
|
||||
'muntha_sign': SIGNS[muntha_sign],
|
||||
'muntha_lord': SIGN_LORDS[SIGNS[muntha_sign]],
|
||||
'sr_sun_sign_idx': sr_sun_sign,
|
||||
'sr_sun_sign': SIGNS[sr_sun_sign],
|
||||
'age': age,
|
||||
'formula': f'(返照盘太阳星座{sr_sun_sign} + 年龄{age}) mod 12 = {muntha_sign}',
|
||||
'interpretation': _interpret_muntha_sign(muntha_sign),
|
||||
'note': muntha_note,
|
||||
}
|
||||
natal_asc = sr.get('birth_asc_sign_idx') if not degraded else None
|
||||
if natal_asc is None:
|
||||
result['muntha'] = {
|
||||
'status': 'blocked',
|
||||
'reason': 'natal_ascendant_required_for_muntha',
|
||||
}
|
||||
else:
|
||||
result['muntha'] = _muntha_from_natal_ascendant(natal_asc, age)
|
||||
result['muntha']['interpretation'] = _interpret_muntha_sign(result['muntha']['muntha_sign_idx'])
|
||||
except Exception as e:
|
||||
result['muntha'] = {'error': str(e)}
|
||||
|
||||
@@ -500,7 +522,7 @@ def solar_return_full_report(
|
||||
else:
|
||||
try:
|
||||
from tajika import calc_tajika_yogas
|
||||
yogas = calc_tajika_yogas(planet_lons, chart_type='varsha')
|
||||
yogas = calc_tajika_yogas(tajika_planets, chart_type='varsha')
|
||||
result['tajika_yogas'] = yogas
|
||||
except Exception as e:
|
||||
result['tajika_yogas'] = {'error': str(e)}
|
||||
@@ -512,8 +534,18 @@ def solar_return_full_report(
|
||||
try:
|
||||
from tajika import calc_all_sahams
|
||||
asc_lon = sr['ascendant'].get('lon', sr['ascendant'].get('degree', 0))
|
||||
sr_dt_ut = sr['solar_return']['dt_ut']
|
||||
sahams = calc_all_sahams(planet_lons, asc_lon, sr_dt_ut, chart_type='varsha')
|
||||
sr_dt_local = sr['solar_return'].get('dt_local')
|
||||
if sr_dt_local is None:
|
||||
raise ValueError('solar_return_local_datetime_required_for_saham_daynight')
|
||||
sahams = calc_all_sahams(
|
||||
planet_lons,
|
||||
asc_lon,
|
||||
sr_dt_local,
|
||||
chart_type='varsha',
|
||||
lat=birth_lat,
|
||||
lon=birth_lon,
|
||||
tz=birth_tz,
|
||||
)
|
||||
result['sahams'] = sahams
|
||||
except Exception as e:
|
||||
result['sahams'] = {'error': str(e)}
|
||||
|
||||
Reference in New Issue
Block a user