Files
Jyotisha/scripts/sudarshana_chakra.py
T
732642856 a4f8620a71 v6.2.0: 全面技法宝库升级 — 16个新模块 + 12个文件优化
## 新增模块 (16个)
### P0 精度修复
- ashtakavarga: calc_prastara_av() + calc_sodhita_av()
- kakshya.py: Kakshya评分系统 (8区间×3.75°)
- shadbala.py: Sputa Drishti + Yuddha Bala

### P1 核心升级
- bhava_bala.py: 宫位三元力量 (jyotishganit MIT)
- pancha_mahapurusha.py: PMC完整检测含4层失效条件
- sade_sati.py: Sade Sati+Kantaka Shani
- sudarshana_chakra.py: 三参考点盘+收敛分析
- tajika.py: Sahams 7→36 + Tajika Yogas 10种
- birth_time_rectifier.py: 生时矫正

### P2 覆盖扩展
- kp_system.py: KP Sublord+ABCD Significator (diliprk/VedicAstro MIT)
- synastry.py: 16因子合盘36分制 (dashaflow MIT)
- muhurtha_election.py: 6活动选举 (dashaflow MIT)
- career_analysis.py: 结构化事业引擎
- relationship_analysis.py: 结构化感情引擎
- conditional_dashas.py: Dwisaptati+Shattrimsa+Dwadashottari
- divisional_charts_extended: D81/D108/D144
- remedies.py: 5类补救系统

## 修改文件
jaimini/dasha_calculator/shadbala/SKILL.md/COVERAGE_AUDIT等12个

## 开源复用: 4个MIT项目
2026-06-11 19:03:21 +08:00

204 lines
7.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Sudarshana Chakra(苏达沙那轮)模块
基于BPHS传统三参考点盘系统
三个参考点:
1. Lagna (上升) → 自我、身体
2. Chandra (月亮) → 情感、心理
3. Surya (太阳) → 灵魂、生命力
当三个参考点中同一宫位/行星配置一致时,事件确认度高。
"""
from typing import Dict, List
SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces']
SIGN_LORDS = {
'Aries': 'Mars', 'Taurus': 'Venus', 'Gemini': 'Mercury', 'Cancer': 'Moon',
'Leo': 'Sun', 'Virgo': 'Mercury', 'Libra': 'Venus', 'Scorpio': 'Mars',
'Sagittarius': 'Jupiter', 'Capricorn': 'Saturn', 'Aquarius': 'Saturn', 'Pisces': 'Jupiter'
}
def _build_reference_chart(planet_positions: Dict, reference_sign_idx: int) -> Dict:
"""
基于指定参考点构建重新排列的星盘。
以reference_sign_idx为第1宫,重新计算所有行星的宫位。
Args:
planet_positions: {planet: {'sign_idx': int, 'degree': float}}
reference_sign_idx: 参考星座索引(作为第1宫)
Returns:
重新排列的星盘 {planet: {'house': int, 'sign': str, ...}}
"""
chart = {
'reference_sign': SIGNS[reference_sign_idx],
'houses': {},
'planets': {},
}
# 计算每个宫位对应的星座
for house_num in range(1, 13):
sign_idx = (reference_sign_idx + house_num - 1) % 12
chart['houses'][house_num] = {
'sign': SIGNS[sign_idx],
'rasi_lord': SIGN_LORDS[SIGNS[sign_idx]],
}
# 重新计算行星宫位
for planet, data in planet_positions.items():
sign_idx = data.get('sign_idx', data.get('sign', 0))
if isinstance(sign_idx, str):
sign_idx = SIGNS.index(sign_idx) if sign_idx in SIGNS else 0
house = (sign_idx - reference_sign_idx) % 12 + 1
chart['planets'][planet] = {
'sign': SIGNS[sign_idx],
'house': house,
'degree': data.get('degree', 0),
}
return chart
def _find_convergences(lagna_chart: Dict, chandra_chart: Dict, surya_chart: Dict) -> Dict:
"""
寻找三个参考点盘中的一致性(Convergence)。
当同一宫位在至少两个参考点中有重要配置时,标记为收敛点。
Returns:
收敛分析结果
"""
convergences = []
SEVEN_PLANETS = ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn']
for house_num in range(1, 13):
lagna_planets = [p for p in SEVEN_PLANETS
if p in lagna_chart.get('planets', {})
and lagna_chart['planets'][p].get('house') == house_num]
chandra_planets = [p for p in SEVEN_PLANETS
if p in chandra_chart.get('planets', {})
and chandra_chart['planets'][p].get('house') == house_num]
surya_planets = [p for p in SEVEN_PLANETS
if p in surya_chart.get('planets', {})
and surya_chart['planets'][p].get('house') == house_num]
# 寻找至少两个参考点中共有的行星
all_in_house = set(lagna_planets + chandra_planets + surya_planets)
for planet in all_in_house:
count = (1 if planet in lagna_planets else 0) + \
(1 if planet in chandra_planets else 0) + \
(1 if planet in surya_planets else 0)
if count >= 2:
convergences.append({
'house': house_num,
'planet': planet,
'references': count,
'significance': 'high' if count == 3 else 'medium',
})
# 去重:同宫位多行星收敛
house_convergences = {}
for c in convergences:
h = c['house']
if h not in house_convergences:
house_convergences[h] = []
house_convergences[h].append(c)
return {
'total_convergences': len(convergences),
'high_confidence': [c for c in convergences if c['significance'] == 'high'],
'house_analysis': house_convergences,
}
def calc_sudarshana_chakra(planet_positions: Dict,
asc_sign: str = None,
asc_sign_idx: int = None,
moon_degree: float = None,
sun_degree: float = None) -> Dict:
"""
计算Sudarshana Chakra(三参考点盘)。
Args:
planet_positions: {planet: {'sign': str 或 'sign_idx': int, 'degree': float}}
asc_sign: 上升星座名称(优先)
asc_sign_idx: 上升星座索引
moon_degree: 月亮黄道经度(0-360,用于确定月亮星座)
sun_degree: 太阳黄道经度(0-360,用于确定太阳星座)
Returns:
完整的Sudarshana Chakra分析
"""
# 确定三个参考点星座索引
if asc_sign and asc_sign in SIGNS:
lagna_ref = SIGNS.index(asc_sign)
elif asc_sign_idx is not None:
lagna_ref = asc_sign_idx % 12
else:
lagna_ref = 0
if moon_degree is not None:
chandra_ref = int(moon_degree / 30) % 12
else:
# 尝试从行星位置中获取
moon_data = planet_positions.get('Moon', {})
chandra_ref = moon_data.get('sign_idx', 0)
if isinstance(chandra_ref, str):
chandra_ref = SIGNS.index(chandra_ref) if chandra_ref in SIGNS else 3
if sun_degree is not None:
surya_ref = int(sun_degree / 30) % 12
else:
sun_data = planet_positions.get('Sun', {})
surya_ref = sun_data.get('sign_idx', 0)
if isinstance(surya_ref, str):
surya_ref = SIGNS.index(surya_ref) if surya_ref in SIGNS else 4
# 构建三个参考点盘
lagna_chart = _build_reference_chart(planet_positions, lagna_ref)
chandra_chart = _build_reference_chart(planet_positions, chandra_ref)
surya_chart = _build_reference_chart(planet_positions, surya_ref)
# 寻找收敛
convergence = _find_convergences(lagna_chart, chandra_chart, surya_chart)
return {
'method': 'Sudarshana Chakra 三参考点盘 (BPHS标准)',
'version': '1.0',
'references': {
'lagna': {'sign': SIGNS[lagna_ref], 'role': '自我/身体'},
'chandra': {'sign': SIGNS[chandra_ref], 'role': '情感/心理'},
'surya': {'sign': SIGNS[surya_ref], 'role': '灵魂/生命力'},
},
'charts': {
'lagna_based': lagna_chart,
'chandra_based': chandra_chart,
'surya_based': surya_chart,
},
'convergence': convergence,
'assessment': _assess_chakra(convergence),
}
def _assess_chakra(convergence: Dict) -> str:
"""评估Sudarshana Chakra的总体结构"""
high = len(convergence.get('high_confidence', []))
total = convergence.get('total_convergences', 0)
if high >= 3:
return '强烈收敛 — 三个参考点高度一致,事件确认度极高'
elif high >= 1 or total >= 5:
return '中等收敛 — 部分领域一致性较强'
elif total >= 1:
return '弱收敛 — 少数领域有一致性'
else:
return '无收敛 — 三个参考点分散,需从多角度分别分析'