fix(narayana): show the source-aware seed beside the historical sequence (BUG-1264, upstream 1918ffaf)
This commit is contained in:
@@ -26,7 +26,7 @@ def cmd_narayana_dasha(args, chart_data):
|
||||
"Narayana Dasha 需要完整的行星经度数据。",
|
||||
])
|
||||
|
||||
from narayana_dasha import narayana_dasha_full_report
|
||||
from narayana_dasha import attach_narayana_method_comparison, narayana_dasha_full_report
|
||||
|
||||
planet_lons = {}
|
||||
for pn, pd in chart_data.get('planets', {}).items():
|
||||
@@ -59,6 +59,7 @@ def cmd_narayana_dasha(args, chart_data):
|
||||
from narayana_legacy_label import label_legacy_narayana # BUG-1215; Rath view BUG-1218
|
||||
label_legacy_narayana(result, lagna_sign_idx=asc_idx, planet_lons=planet_lons,
|
||||
current_age=current_age, birth_year=birth_year)
|
||||
attach_narayana_method_comparison(result, asc_idx, planet_lons, current_age, birth_year)
|
||||
|
||||
# 格式化输出
|
||||
lines = [
|
||||
@@ -99,6 +100,16 @@ def cmd_narayana_dasha(args, chart_data):
|
||||
for line in result.get('interpretation', []):
|
||||
lines.append(f" {line}")
|
||||
|
||||
source = (result.get('method_comparison') or {}).get('source_aware') or {}
|
||||
if source:
|
||||
lines.append("")
|
||||
lines.append("── 来源对照 ──")
|
||||
if source.get('status') == 'blocked':
|
||||
lines.append(f" 来源算法:blocked({source.get('reason')})")
|
||||
else:
|
||||
seed = source.get('seed_selection') or {}
|
||||
lines.append(f" 来源起运规则:{seed.get('profile')};起运星座:{seed.get('selected_sign')}")
|
||||
|
||||
rath = result.get('rath') or {}
|
||||
if rath:
|
||||
lines.append("")
|
||||
|
||||
@@ -66,6 +66,7 @@ except ModuleNotFoundError: # pragma: no cover - minimal environments
|
||||
return "\n".join(lines)
|
||||
from life_stage_hook import generate_life_stage_hooks
|
||||
from narayana_legacy_label import LEGACY_NOTE_ZH as LEGACY_NARAYANA_NOTE_ZH, rath_report_lines_zh # BUG-1215 / BUG-1218
|
||||
from narayana_dasha import narayana_comparison_lines_zh as _narayana_comparison_lines_zh
|
||||
from capability_evidence_pool import build_capability_evidence_pool_summary
|
||||
from guided_topic_discovery import build_guided_topics
|
||||
|
||||
@@ -9522,6 +9523,7 @@ def render_pl9_markdown(packet: dict) -> str:
|
||||
'',
|
||||
f'- 算法:{LEGACY_NARAYANA_NOTE_ZH}', # BUG-1215
|
||||
*rath_report_lines_zh(((worksheets.get('timing_and_predictive_systems') or {}).get('narayana_dasha') or {}).get('rath')), # BUG-1218
|
||||
*_narayana_comparison_lines_zh((worksheets.get('timing_and_predictive_systems') or {}).get('narayana_dasha')),
|
||||
'',
|
||||
'#### Patyayini 年内节奏支持',
|
||||
'',
|
||||
@@ -16244,7 +16246,7 @@ def cmd_full_reading(args):
|
||||
|
||||
# ── Step 4.13: Narayana Dasha(Rishi Dasha,v6.0.20)──
|
||||
try:
|
||||
from narayana_dasha import narayana_dasha_full_report
|
||||
from narayana_dasha import attach_narayana_method_comparison, narayana_dasha_full_report
|
||||
# 计算当前年龄(从出生到 today)
|
||||
birth_dt = _birth_datetime_from_args(args)
|
||||
today_dt = datetime.strptime(args.today, '%Y-%m-%d') if hasattr(args, 'today') and args.today else datetime.now()
|
||||
@@ -16256,8 +16258,10 @@ def cmd_full_reading(args):
|
||||
birth_year=args.year,
|
||||
)
|
||||
from narayana_legacy_label import label_legacy_narayana # BUG-1215
|
||||
report['modules']['narayana_dasha'] = label_legacy_narayana( # + Rath view, display only (BUG-1218)
|
||||
labeled = label_legacy_narayana( # + Rath view, display only (BUG-1218)
|
||||
narayana_result, lagna_sign_idx=asc_idx, planet_lons=planet_lons, current_age=current_age, birth_year=args.year)
|
||||
report['modules']['narayana_dasha'] = attach_narayana_method_comparison(
|
||||
labeled, asc_idx, planet_lons, current_age, args.year)
|
||||
except Exception as e:
|
||||
report['errors'].append(f"narayana-dasha: {e}")
|
||||
|
||||
|
||||
+176
-3
@@ -429,10 +429,64 @@ def _resolve_narayana_lord(
|
||||
return first if first_years >= second_years else second
|
||||
|
||||
|
||||
def _calc_narayana_mahadasha_profiled(
|
||||
lagna_sign_idx: int,
|
||||
planet_lons: Dict[str, float],
|
||||
start_year: float,
|
||||
*,
|
||||
duration_profile: str,
|
||||
sequence_profile: str,
|
||||
seed_profile: str,
|
||||
dual_lord_profile: str,
|
||||
) -> List[Dict]:
|
||||
"""Source-aware Mahadasha. The legacy two-argument path does not call this."""
|
||||
if seed_profile == "jaimini_lagna_seventh_strength_v1":
|
||||
selection = select_narayana_seed_sign(lagna_sign_idx, planet_lons)
|
||||
if selection.get("status") != "selected":
|
||||
raise ValueError(selection.get("reason") or "seed_not_selected")
|
||||
seed = int(selection["selected_sign_idx"])
|
||||
elif seed_profile == "legacy_lagna_v0":
|
||||
seed = lagna_sign_idx
|
||||
else:
|
||||
raise ValueError(f"unsupported Narayana seed profile: {seed_profile}")
|
||||
sequence = build_narayana_sign_sequence(seed, profile=sequence_profile)
|
||||
periods = []
|
||||
cum_years = start_year
|
||||
for sign_idx in sequence:
|
||||
lord = _resolve_narayana_lord(sign_idx, planet_lons, dual_lord_profile=dual_lord_profile)
|
||||
lord_sign_idx = _get_planet_sign(lord, planet_lons)
|
||||
if lord_sign_idx is None:
|
||||
lord_sign_idx = sign_idx
|
||||
years, _adjustment = calculate_narayana_period_years(
|
||||
sign_idx, lord, lord_sign_idx, profile=duration_profile,
|
||||
)
|
||||
periods.append({
|
||||
'sign': SIGNS[sign_idx],
|
||||
'sign_idx': sign_idx,
|
||||
'lord': lord,
|
||||
'lord_in_sign': SIGNS[lord_sign_idx],
|
||||
'lord_sign_idx': lord_sign_idx,
|
||||
'years': years,
|
||||
'count_from_to': f'{SIGNS[sign_idx]}({sign_idx})→{SIGNS[lord_sign_idx]}({lord_sign_idx})',
|
||||
'start_age': round(cum_years, 2),
|
||||
'end_age': round(cum_years + years, 2),
|
||||
'duration_profile': duration_profile,
|
||||
'sequence_profile': sequence_profile,
|
||||
'seed_profile': seed_profile,
|
||||
})
|
||||
cum_years += years
|
||||
return periods
|
||||
|
||||
|
||||
def calc_narayana_mahadasha(
|
||||
lagna_sign_idx: int,
|
||||
planet_lons: Dict[str, float],
|
||||
start_year: float = 0.0,
|
||||
*,
|
||||
duration_profile: str = "legacy_forward_v0",
|
||||
sequence_profile: str = "legacy_zodiacal_v0",
|
||||
seed_profile: str = "legacy_lagna_v0",
|
||||
dual_lord_profile: str = "legacy_primary_lord_v0",
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
计算 Narayana Dasha 大运序列(第1周期)。
|
||||
@@ -447,7 +501,24 @@ def calc_narayana_mahadasha(
|
||||
'sign': str, 'sign_idx': int, 'lord': str,
|
||||
'years': int, 'start_age': float, 'end_age': float,
|
||||
}
|
||||
|
||||
默认四个 profile 走原来的 Lagna 顺行循环,返回字段与打分调用保持一致。
|
||||
"""
|
||||
if not (
|
||||
duration_profile == "legacy_forward_v0"
|
||||
and sequence_profile == "legacy_zodiacal_v0"
|
||||
and seed_profile == "legacy_lagna_v0"
|
||||
and dual_lord_profile == "legacy_primary_lord_v0"
|
||||
):
|
||||
return _calc_narayana_mahadasha_profiled(
|
||||
lagna_sign_idx,
|
||||
planet_lons,
|
||||
start_year,
|
||||
duration_profile=duration_profile,
|
||||
sequence_profile=sequence_profile,
|
||||
seed_profile=seed_profile,
|
||||
dual_lord_profile=dual_lord_profile,
|
||||
)
|
||||
periods = []
|
||||
cum_years = start_year
|
||||
|
||||
@@ -864,8 +935,23 @@ def narayana_dasha_full_report(
|
||||
"""
|
||||
result = {}
|
||||
|
||||
# 1. 完整大运序列
|
||||
mahadasha = calc_narayana_mahadasha(lagna_sign_idx, planet_lons)
|
||||
# 1. 完整大运序列。默认 profile 仍走原来的两参数调用。
|
||||
if (
|
||||
duration_profile == "legacy_forward_v0"
|
||||
and sequence_profile == "legacy_zodiacal_v0"
|
||||
and seed_profile == "legacy_lagna_v0"
|
||||
and dual_lord_profile == "legacy_primary_lord_v0"
|
||||
):
|
||||
mahadasha = calc_narayana_mahadasha(lagna_sign_idx, planet_lons)
|
||||
else:
|
||||
mahadasha = calc_narayana_mahadasha(
|
||||
lagna_sign_idx,
|
||||
planet_lons,
|
||||
duration_profile=duration_profile,
|
||||
sequence_profile=sequence_profile,
|
||||
seed_profile=seed_profile,
|
||||
dual_lord_profile=dual_lord_profile,
|
||||
)
|
||||
total_cycle = sum(p['years'] for p in mahadasha)
|
||||
result['mahadasha_sequence'] = mahadasha
|
||||
result['total_cycle_years'] = total_cycle
|
||||
@@ -912,6 +998,90 @@ def narayana_dasha_full_report(
|
||||
return result
|
||||
|
||||
|
||||
def narayana_report_with_variants(lagna_sign_idx, planet_lons, current_age=0, birth_year=0):
|
||||
"""Report the historical sequence and a source-aware sequence side by side.
|
||||
|
||||
The returned top-level Mahadasha stays the historical profile. Rectification
|
||||
scoring calls ``calc_narayana_mahadasha`` directly and does not read this.
|
||||
Rath Ketu table 12 is not in the local sequence profiles, so that case is
|
||||
blocked instead of replaced with another table.
|
||||
"""
|
||||
legacy = narayana_dasha_full_report(lagna_sign_idx, planet_lons, current_age, birth_year)
|
||||
selection = select_narayana_seed_sign(lagna_sign_idx, planet_lons)
|
||||
if selection.get('status') != 'selected':
|
||||
blocked = {'status': 'blocked', 'reason': selection.get('reason')}
|
||||
return {
|
||||
**legacy,
|
||||
'selected_method': 'legacy_comparison_only',
|
||||
'method_comparison': {'source_aware': blocked, 'legacy': legacy},
|
||||
'comparison_required': True,
|
||||
}
|
||||
seed = selection['selected_sign_idx']
|
||||
if _get_planet_sign('Saturn', planet_lons) == seed:
|
||||
sequence = 'rath_saturn_table11_v1'
|
||||
elif _get_planet_sign('Ketu', planet_lons) == seed:
|
||||
blocked = {'status': 'blocked', 'reason': 'rath_ketu_table12_v1_not_in_local_sequence_profiles'}
|
||||
return {
|
||||
**legacy,
|
||||
'selected_method': 'legacy_comparison_only',
|
||||
'method_comparison': {'source_aware': blocked, 'legacy': legacy},
|
||||
'comparison_required': True,
|
||||
}
|
||||
else:
|
||||
sequence = 'rath_general_table10_v1'
|
||||
settings = dict(
|
||||
duration_profile='jaimini_odd_footed_dignity_v2',
|
||||
sequence_profile=sequence,
|
||||
seed_profile='jaimini_lagna_seventh_strength_v1',
|
||||
dual_lord_profile='jaimini_dual_lord_source_v1',
|
||||
antardasha_profile='parashara_equal_v1',
|
||||
)
|
||||
try:
|
||||
native = narayana_dasha_full_report(
|
||||
lagna_sign_idx, planet_lons, current_age, birth_year, **settings,
|
||||
)
|
||||
except ValueError as exc:
|
||||
blocked = {'status': 'blocked', 'reason': str(exc), 'settings': settings}
|
||||
return {
|
||||
**legacy,
|
||||
'selected_method': 'legacy_comparison_only',
|
||||
'method_comparison': {'source_aware': blocked, 'legacy': legacy},
|
||||
'comparison_required': True,
|
||||
}
|
||||
return {
|
||||
**legacy,
|
||||
'selected_method': 'legacy_with_source_aware_comparison',
|
||||
'method_comparison': {'source_aware': native, 'legacy': legacy},
|
||||
'comparison_required': True,
|
||||
}
|
||||
|
||||
|
||||
def narayana_comparison_lines_zh(narayana) -> List[str]:
|
||||
"""One display line naming the source-aware seed rule beside the legacy sequence."""
|
||||
if not isinstance(narayana, dict):
|
||||
return []
|
||||
source = (narayana.get('method_comparison') or {}).get('source_aware')
|
||||
if not isinstance(source, dict):
|
||||
return []
|
||||
if source.get('status') == 'blocked':
|
||||
return [f"- 来源对照:blocked({source.get('reason')})"]
|
||||
seed = source.get('seed_selection') or {}
|
||||
return [f"- 来源对照:所选起运规则 {seed.get('profile')},起运星座 {seed.get('selected_sign')}"]
|
||||
|
||||
|
||||
def attach_narayana_method_comparison(result, lagna_sign_idx, planet_lons, current_age=0, birth_year=0):
|
||||
"""Attach the side-by-side view without replacing the historical sequence."""
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
comparison = narayana_report_with_variants(
|
||||
lagna_sign_idx, planet_lons, current_age, birth_year,
|
||||
)
|
||||
result['method_comparison'] = comparison.get('method_comparison')
|
||||
result['comparison_required'] = True
|
||||
result['selected_method'] = comparison.get('selected_method')
|
||||
return result
|
||||
|
||||
|
||||
def _interpret_narayana(result: Dict, current_age: float) -> List[str]:
|
||||
"""Narayana Dasha 简要解读"""
|
||||
lines = []
|
||||
@@ -920,7 +1090,10 @@ def _interpret_narayana(result: Dict, current_age: float) -> List[str]:
|
||||
if md_seq:
|
||||
total = sum(p['years'] for p in md_seq)
|
||||
lines.append(f"Narayana Dasha 完整周期: {total} 年(12 星座 × 可变年数)")
|
||||
lines.append(f"起运星座: {result.get('lagna_sign', '?')}(Lagna)")
|
||||
seed = result.get('seed_selection') or {}
|
||||
rule = seed.get('profile') or result.get('seed_profile') or 'legacy_lagna_v0'
|
||||
sign = seed.get('selected_sign') or result.get('lagna_sign', '?')
|
||||
lines.append(f"起运星座: {sign}(所选起运规则 {rule})")
|
||||
|
||||
curr = result.get('current_dasha', {})
|
||||
md = curr.get('md')
|
||||
|
||||
Reference in New Issue
Block a user