v3.7.0: 新增7大模块 - BPHS十六分盘/精确相位/Jaimini/高级Nakshatra/Argala门闩/Tajika年运/合盘分析

- varga.py: D2-D60 BPHS十六分盘完整计算
- aspects.py: 度数精确相位系统(tight/moderate/loose)
- jaimini.py: Chara Karaka 7/8 + Chara Dasha + Karakamsha
- nakshatra_advanced.py: Tara Bala + Sub-Lord KP系统
- argala.py: Argala门闩 + Virodha反干预
- tajika.py: Muntha/YearLord/Mudda Dasha/Tri-Pataka
- synastry.py: Ashta Koota 36分制 + Mangal Dosha + Papasamya

引擎升级至v3.7.0, 21个子命令全链路验证通过
This commit is contained in:
732642856
2026-04-25 00:34:21 +08:00
parent fffc940082
commit 0178dfb3e8
10 changed files with 2009 additions and 16 deletions
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
高级星宿分析模块 v1.0
Nakshatra深度分析系统
支持:
- Tara Bala(星宿力量匹配)
- Sub-Lord体系(KP占星)
- 精确Vimshottari起始点计算
- Nakshatra兼容性分析
- Navatara9星宿组)分类
"""
from typing import Dict, List, Tuple
import math
NAK_LIST = [
("Ashwini","Ketu",7),("Bharani","Venus",20),("Krittika","Sun",6),
("Rohini","Moon",10),("Mrigashira","Mars",7),("Ardra","Rahu",18),
("Punarvasu","Jupiter",16),("Pushya","Saturn",19),("Ashlesha","Mercury",17),
("Magha","Ketu",7),("Purva Phalguni","Venus",20),("Uttara Phalguni","Sun",6),
("Hasta","Moon",10),("Chitra","Mars",7),("Swati","Rahu",18),
("Vishakha","Jupiter",16),("Anuradha","Saturn",19),("Jyeshtha","Mercury",17),
("Mula","Ketu",7),("Purva Ashadha","Venus",20),("Uttara Ashadha","Sun",6),
("Shravana","Moon",10),("Dhanishta","Mars",7),("Shatabhisha","Rahu",18),
("Purva Bhadrapada","Jupiter",16),("Uttara Bhadrapada","Saturn",19),("Revati","Mercury",17),
]
NAK_NAMES = [n[0] for n in NAK_LIST]
NAK_LORDS = [n[1] for n in NAK_LIST]
NAK_YEARS = [n[2] for n in NAK_LIST]
# Navatara分组(从月亮星宿开始的9个星宿循环)
TARA_NAMES = ['Janma(生命)','Sampat(财富)','Vipat(危险)','Kshema(安全)',
'Pratyak(障碍)','Sadhana(成就)','Vadha(毁灭)','Mitra(友好)','ParamaMitra(至友)']
TARA_CN = {0:'生命Tara',1:'财富Tara',2:'危险Tara',3:'安全Tara',
4:'障碍Tara',5:'成就Tara',6:'毁灭Tara',7:'友好Tara',8:'至友Tara'}
# Nakshatra元素和属性
NAK_GANA = { # 气质类型
0:'Dev(神圣)',1:'Manushya(人类)',2:'Rakshasa(罗刹)',
3:'Dev',4:'Dev',5:'Manushya',6:'Dev',7:'Dev',8:'Rakshasa',
9:'Rakshasa',10:'Manushya',11:'Manushya',12:'Dev',13:'Rakshasa',14:'Dev',
15:'Rakshasa',16:'Dev',17:'Rakshasa',18:'Rakshasa',19:'Manushya',20:'Manushya',
21:'Dev',22:'Rakshasa',23:'Rakshasa',24:'Manushya',25:'Manushya',26:'Dev',
}
NAK_ELEMENT = {
0:'',1:'',2:'',3:'',4:'',5:'',6:'',7:'',8:'',
9:'',10:'',11:'',12:'',13:'',14:'',15:'',16:'',17:'',
18:'',19:'',20:'',21:'',22:'',23:'',24:'',25:'',26:'',
}
def find_nakshatra(longitude: float) -> Dict:
"""从恒星黄道经度精确计算Nakshatra"""
nak_span = 360.0 / 27 # 每个星宿13.333...°
nak_idx = int(longitude / nak_span) % 27
nak_start = nak_idx * nak_span
deg_in_nak = longitude - nak_start
pada_span = nak_span / 4 # 每个Pada 3.333...°
pada = int(deg_in_nak / pada_span) + 1
deg_in_pada = deg_in_nak - (pada - 1) * pada_span
return {
'nakshatra': NAK_NAMES[nak_idx],
'nakshatra_idx': nak_idx,
'nakshatra_lord': NAK_LORDS[nak_idx],
'dasha_years': NAK_YEARS[nak_idx],
'pada': pada,
'degree_in_nakshatra': round(deg_in_nak, 4),
'degree_in_pada': round(deg_in_pada, 4),
'gana': NAK_GANA.get(nak_idx, ''),
'element': NAK_ELEMENT.get(nak_idx, ''),
}
def calc_tara_bala(moon_nak_idx: int, target_nak_idx: int) -> Dict:
"""
Tara Bala计算:月亮星宿到目标星宿的9星宿循环关系
用于判断某个行星/事件星宿与月亮星宿的关系
0=Janma(中性), 1=Sampat(吉), 2=Vipat(凶), 3=Kshema(吉),
4=Pratyak(凶), 5=Sadhana(吉), 6=Vadha(凶), 7=Mitra(吉), 8=ParamaMitra(大吉)
"""
distance = (target_nak_idx - moon_nak_idx) % 9
tara_name = TARA_NAMES[distance]
tara_cn = TARA_CN[distance]
is_auspicious = distance in (1, 3, 5, 7, 8)
is_dangerous = distance in (2, 4, 6)
return {
'tara_index': distance,
'tara_name': tara_name,
'tara_cn': tara_cn,
'is_auspicious': is_auspicious,
'is_dangerous': is_dangerous,
'quality': 'auspicious' if is_auspicious else 'dangerous' if is_dangerous else 'neutral',
'interpretation': _tara_interp(distance),
}
def calc_all_tara_balas(moon_nak_idx: int, planet_lons: Dict[str, float]) -> Dict:
"""计算所有行星相对于月亮的Tara Bala"""
results = {}
for pname, lon in planet_lons.items():
p_nak = find_nakshatra(lon)
tara = calc_tara_bala(moon_nak_idx, p_nak['nakshatra_idx'])
results[pname] = {
'nakshatra': p_nak['nakshatra'],
'tara': tara,
}
return results
def calc_vimshottari_start(moon_longitude: float) -> Dict:
"""
精确计算Vimshottari Dasha的起始点
返回月亮所在星宿的守护星、已用度数比例、剩余年数
"""
nak = find_nakshatra(moon_longitude)
nak_idx = nak['nakshatra_idx']
nak_lord = NAK_LORDS[nak_idx]
total_years = NAK_YEARS[nak_idx]
# 已用比例
nak_span = 360.0 / 27
nak_start = nak_idx * nak_span
deg_in_nak = moon_longitude - nak_start
used_ratio = deg_in_nak / nak_span
remaining_ratio = 1 - used_ratio
# 第一个Mahadasha的剩余年数
first_mahadasha_remaining = total_years * remaining_ratio
first_mahadasha_elapsed = total_years * used_ratio
return {
'moon_nakshatra': nak['nakshatra'],
'moon_nakshatra_lord': nak_lord,
'moon_pada': nak['pada'],
'total_dasha_years': total_years,
'used_ratio': round(used_ratio, 6),
'remaining_ratio': round(remaining_ratio, 6),
'first_mahadasha_remaining_years': round(first_mahadasha_remaining, 4),
'first_mahadasha_elapsed_years': round(first_mahadasha_elapsed, 4),
'first_mahadasha_lord': nak_lord,
}
def calc_sub_lord(longitude: float, division: int = 9) -> Dict:
"""
Sub-Lord计算(KP占星体系)
将星宿进一步细分为Sub-Lord和Sub-Sub-Lord
参数:
longitude: 恒星黄道经度
division: 细分层级(9=Sub-Lord, 81=Sub-Sub-Lord
"""
# 主星宿
nak = find_nakshatra(longitude)
nak_span = 360.0 / 27
# Sub-Lord: 将星宿按守护星的大运年数比例细分
total_dasha_years = sum(NAK_YEARS) # 120年
nak_lord = NAK_NAMES[nak['nakshatra_idx']]
# 计算Sub-Lord
deg_in_nak = nak['degree_in_nakshatra']
sub_lord_span = nak_span * (NAK_YEARS[NAK_LORDS.index(NAK_LORDS[nak['nakshatra_idx']])]) / total_dasha_years
# 简化版:直接按9等分
sub_span = nak_span / 9
sub_idx = int(deg_in_nak / sub_span) % 9
# Sub-Lord是第sub_idx个行星(从星宿守护星开始的大运顺序)
DASHA_ORDER = ["Ketu","Venus","Sun","Moon","Mars","Rahu","Jupiter","Saturn","Mercury"]
nak_lord_idx = DASHA_ORDER.index(NAK_LORDS[nak['nakshatra_idx']])
sub_lord = DASHA_ORDER[(nak_lord_idx + sub_idx) % 9]
return {
'nakshatra': nak['nakshatra'],
'nakshatra_lord': nak_lord,
'sub_lord': sub_lord,
'sub_index': sub_idx,
'pada': nak['pada'],
'degree_in_nakshatra': round(deg_in_nak, 4),
}
def nakshatra_compatibility(nak1_idx: int, nak2_idx: int) -> Dict:
"""
Nakshatra兼容性分析(Koota系统中的星宿匹配部分)
基于Tara Bala和Nakshatra元素匹配
"""
# Tara匹配
tara = calc_tara_bala(nak1_idx, nak2_idx)
tara_score = 3 if tara['is_auspicious'] else 0 if tara['is_dangerous'] else 1.5
# 元素匹配
el1 = NAK_ELEMENT.get(nak1_idx, '')
el2 = NAK_ELEMENT.get(nak2_idx, '')
el_compatible = el1 == el2 or (el1 in ('','') and el2 in ('','')) or (el1 in ('','') and el2 in ('',''))
# Gana匹配
g1 = NAK_GANA.get(nak1_idx, '')
g2 = NAK_GANA.get(nak2_idx, '')
gana_score = 6 if g1 == g2 else 3 if ('Dev' in g1 and 'Manushya' in g2) or ('Manushya' in g1 and 'Dev' in g2) else 0
return {
'nak1': NAK_NAMES[nak1_idx],
'nak2': NAK_NAMES[nak2_idx],
'tara_bala': tara,
'tara_score': tara_score,
'element_match': {'e1': el1, 'e2': el2, 'compatible': el_compatible},
'gana_match': {'g1': g1, 'g2': g2, 'score': gana_score},
'overall': 'compatible' if tara_score >= 1.5 and el_compatible else 'challenging' if tara['is_dangerous'] else 'moderate',
}
def _tara_interp(idx):
interps = {
0: '生命Tara—中性,代表自我,不吉不凶',
1: '财富Tara—吉,带来物质和精神增长',
2: '危险Tara—凶,需要谨慎,可能带来损失',
3: '安全Tara—吉,提供保护和稳定',
4: '障碍Tara—凶,可能面临困难和延误',
5: '成就Tara—吉,有利于实现目标',
6: '毁灭Tara—凶,最大凶Tara,需特别注意',
7: '友好Tara—吉,提供支持和帮助',
8: '至友Tara—大吉,最强吉Tara',
}
return interps.get(idx, '')