a4f8620a71
## 新增模块 (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项目
185 lines
6.2 KiB
Python
185 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Pancha Mahapurusha Yoga(五王瑜伽)完整检测模块 v1.0
|
|
基于BPHS和dashaflow (MIT) detect_yogas核心算法
|
|
|
|
五种瑜伽:
|
|
- Ruchaka Yoga (Mars)
|
|
- Bhadra Yoga (Mercury)
|
|
- Hamsa Yoga (Jupiter)
|
|
- Malavya Yoga (Venus)
|
|
- Shasha Yoga (Saturn)
|
|
|
|
含完整的燃烧(Combustion)/逆行(Retrograde)/受克(Affliction)失效条件检测
|
|
"""
|
|
|
|
from typing import Dict, List, Optional
|
|
|
|
SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
|
|
'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces']
|
|
|
|
KENDRA_HOUSES = {1, 4, 7, 10}
|
|
MAHAPURUSHA_PLANETS = {"Mars", "Mercury", "Jupiter", "Venus", "Saturn"}
|
|
|
|
MAHAPURUSHA_NAMES = {
|
|
"Mars": "Ruchaka Yoga",
|
|
"Mercury": "Bhadra Yoga",
|
|
"Jupiter": "Hamsa Yoga",
|
|
"Venus": "Malavya Yoga",
|
|
"Saturn": "Shasha Yoga",
|
|
}
|
|
|
|
MAHAPURUSHA_EFFECTS = {
|
|
"Ruchaka": "军事领袖、建筑大师、体魄强健、勇敢果断",
|
|
"Bhadra": "演说家、学者、机智聪慧、商业头脑",
|
|
"Hamsa": "精神导师、哲学家、富足慷慨、智慧卓越",
|
|
"Malavya": "艺术家、享乐者、魅力超凡、审美敏锐",
|
|
"Shasha": "政治家、长者、坚韧执着、权威地位",
|
|
}
|
|
|
|
EXALTATION = {'Sun':('Aries',10),'Moon':('Taurus',3),'Mars':('Capricorn',28),'Mercury':('Virgo',15),'Jupiter':('Cancer',5),'Venus':('Pisces',27),'Saturn':('Libra',20)}
|
|
OWN_SIGNS = {'Sun':{'Leo'},'Moon':{'Cancer'},'Mars':{'Aries','Scorpio'},'Mercury':{'Gemini','Virgo'},'Jupiter':{'Sagittarius','Pisces'},'Venus':{'Taurus','Libra'},'Saturn':{'Capricorn','Aquarius'}}
|
|
|
|
# Combustion orb (degrees from Sun)
|
|
COMBUSTION_ORB = {'Mars':17,'Mercury':12,'Jupiter':11,'Venus':10,'Saturn':15}
|
|
|
|
NATURAL_MALEFICS = {"Saturn", "Mars", "Sun", "Rahu", "Ketu"}
|
|
|
|
|
|
def _is_exalted_or_own(planet: str, sign: str) -> bool:
|
|
if planet in EXALTATION and EXALTATION[planet][0] == sign:
|
|
return True
|
|
if planet in OWN_SIGNS and sign in OWN_SIGNS[planet]:
|
|
return True
|
|
return False
|
|
|
|
|
|
def _is_combust(planet: str, planet_degree: float, sun_degree: float) -> bool:
|
|
"""检查行星是否被太阳燃烧"""
|
|
orb = COMBUSTION_ORB.get(planet, 10)
|
|
diff = abs(planet_degree - sun_degree)
|
|
if diff > 180:
|
|
diff = 360 - diff
|
|
return diff <= orb
|
|
|
|
|
|
def _has_malefic_aspect(planet_sign: str, all_planets: Dict) -> List[str]:
|
|
"""检查是否有凶星合相/相位该行星"""
|
|
afflicting = []
|
|
for pn, pd in all_planets.items():
|
|
if pn == planet_sign or pn not in NATURAL_MALEFICS:
|
|
continue
|
|
# 简单合相检查
|
|
if pd.get('sign') == planet_sign:
|
|
afflicting.append(pn)
|
|
return afflicting
|
|
|
|
|
|
def detect_pancha_mahapurusha(planets: Dict, sun_degree: float = None) -> List[Dict]:
|
|
"""
|
|
检测所有Pancha Mahapurusha Yoga,含失效条件。
|
|
|
|
Args:
|
|
planets: {planet: {'sign': str, 'house': int, 'degree': float, ...}}
|
|
sun_degree: 太阳黄道经度(用于燃烧检测)
|
|
|
|
Returns:
|
|
检测到的PMC Yoga列表
|
|
"""
|
|
yogas = []
|
|
sun_deg = sun_degree
|
|
|
|
for planet in MAHAPURUSHA_PLANETS:
|
|
pd = planets.get(planet)
|
|
if not pd:
|
|
continue
|
|
|
|
sign = pd.get('sign', '')
|
|
house = pd.get('house', 0)
|
|
|
|
# 基本条件:在Kendra + own/exalted
|
|
if house not in KENDRA_HOUSES:
|
|
continue
|
|
if not _is_exalted_or_own(planet, sign):
|
|
continue
|
|
|
|
yoga_name = MAHAPURUSHA_NAMES[planet]
|
|
effect = MAHAPURUSHA_EFFECTS.get(yoga_name.replace(" Yoga", ""), "")
|
|
|
|
# 检查失效条件
|
|
cancellations = []
|
|
is_valid = True
|
|
|
|
# 1. 燃烧检测
|
|
if sun_deg is not None:
|
|
planet_deg = pd.get('degree', 0)
|
|
if _is_combust(planet, planet_deg, sun_deg):
|
|
cancellations.append(f"{planet}被太阳燃烧(orb < {COMBUSTION_ORB.get(planet,10)}°) — Yoga效力大减")
|
|
is_valid = False
|
|
|
|
# 2. 逆行检测
|
|
if pd.get('retrograde', False):
|
|
cancellations.append(f"{planet}逆行 — Yoga效力减弱")
|
|
is_valid = False
|
|
|
|
# 3. 凶星受克
|
|
malefics = _has_malefic_aspect(sign, planets)
|
|
if malefics:
|
|
cancellations.append(f"{planet}受凶星合相: {', '.join(malefics)} — Yoga部分失效")
|
|
is_valid = False
|
|
|
|
# 4. Navamsa弱势(D9中落陷)
|
|
navamsa_sign = pd.get('navamsa_sign', '')
|
|
if navamsa_sign in OWN_SIGNS.get(planet, set()) or (planet in EXALTATION and EXALTATION[planet][0] == navamsa_sign):
|
|
pass # D9 also strong → yoga reinforced
|
|
elif navamsa_sign:
|
|
# Check if debilitated in D9
|
|
deb_sign_idx = (SIGNS.index(EXALTATION[planet][0]) + 6) % 12 if planet in EXALTATION and planet != 'Rahu' and planet != 'Ketu' else -1
|
|
if deb_sign_idx >= 0 and navamsa_sign == SIGNS[deb_sign_idx]:
|
|
cancellations.append(f"{planet}在Navamsa落陷 — Yoga根基不稳")
|
|
is_valid = False
|
|
|
|
yogas.append({
|
|
'name': yoga_name,
|
|
'planet': planet,
|
|
'sign': sign,
|
|
'house': house,
|
|
'is_valid': is_valid,
|
|
'strength': '完整' if is_valid else '削弱',
|
|
'effect': effect,
|
|
'cancellations': cancellations,
|
|
})
|
|
|
|
return yogas
|
|
|
|
|
|
def assess_pmc_strength(planets: Dict, sun_degree: float = None) -> Dict:
|
|
"""
|
|
评估Pancha Mahapurusha Yoga总体强度。
|
|
|
|
Returns:
|
|
PMC评估结果
|
|
"""
|
|
yogas = detect_pancha_mahapurusha(planets, sun_degree)
|
|
valid = [y for y in yogas if y['is_valid']]
|
|
invalid = [y for y in yogas if not y['is_valid']]
|
|
|
|
if len(valid) >= 2:
|
|
assessment = "多重大王瑜伽 — 命主在不同领域均有杰出天赋"
|
|
elif len(valid) == 1:
|
|
assessment = f"{valid[0]['name']} — 命主在特定领域有卓越潜力"
|
|
elif len(invalid) > 0:
|
|
st = [y['planet'] for y in invalid]
|
|
assessment = f"瑜伽潜质存在但因{', '.join(st)}受克而削弱"
|
|
else:
|
|
assessment = "无Pancha Mahapurusha Yoga"
|
|
|
|
return {
|
|
'method': 'Pancha Mahapurusha Yoga 完整检测 v1.0',
|
|
'yogas': yogas,
|
|
'valid_count': len(valid),
|
|
'invalid_count': len(invalid),
|
|
'assessment': assessment,
|
|
}
|