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项目
194 lines
7.3 KiB
Python
194 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
额外Dasha系统模块 v1.0
|
||
基于BPHS条件性Dasha体系
|
||
|
||
支持的Dasha系统:
|
||
1. Dwisaptati Sama Dasha (72年周期) — 当Lagna lord在特定条件时触发
|
||
2. Shattrimsa Sama Dasha (36年周期) — 当Moon在特定条件时触发
|
||
3. Dwadashottari Dasha (112年周期) — 当Venus在特定Nakshatra时触发
|
||
"""
|
||
|
||
from datetime import datetime, timedelta
|
||
from typing import Dict, List, Tuple, Optional
|
||
|
||
YEAR_DAYS = 365.25636
|
||
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
|
||
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
|
||
NAKSHATRAS = ['Ashwini','Bharani','Krittika','Rohini','Mrigashira','Ardra',
|
||
'Punarvasu','Pushya','Ashlesha','Magha','Purva Phalguni','Uttara Phalguni',
|
||
'Hasta','Chitra','Swati','Vishakha','Anuradha','Jyeshtha',
|
||
'Mula','Purva Ashadha','Uttara Ashadha','Shravana','Dhanishta','Shatabhisha',
|
||
'Purva Bhadrapada','Uttara Bhadrapada','Revati']
|
||
|
||
VIMSHOTTARI_DURATION = {'Ketu':7,'Venus':20,'Sun':6,'Moon':10,'Mars':7,'Rahu':18,'Jupiter':16,'Saturn':19,'Mercury':17}
|
||
DASHA_ORDER = ['Ketu','Venus','Sun','Moon','Mars','Rahu','Jupiter','Saturn','Mercury']
|
||
|
||
|
||
# =============================================================================
|
||
# Dwisaptati Sama Dasha (72年周期)
|
||
# 适用条件:Lagna lord在Lagna或7宫时激活
|
||
# 主星序列:特定8星顺序,每9年一个主星
|
||
# =============================================================================
|
||
|
||
DWISAPTATI_LORDS = ['Sun','Moon','Mars','Mercury','Jupiter','Venus','Saturn','Rahu']
|
||
DWISAPTATI_DURATION = {l: 9 for l in DWISAPTATI_LORDS} # 每个9年,共72年
|
||
DWISAPTATI_SUB_DURATION = {p: VIMSHOTTARI_DURATION[p]*9/120 for p in DWISAPTATI_LORDS}
|
||
|
||
|
||
def check_dwisaptati_condition(lagna_lord: str, lagna_lord_house: int) -> bool:
|
||
"""检查Dwisaptati触发条件:Lagna lord在1或7宫"""
|
||
return lagna_lord_house in (1, 7)
|
||
|
||
|
||
def calc_dwisaptati_dasha(birth_date: datetime, lagna_lord: str,
|
||
lagna_lord_degree: float) -> List[Dict]:
|
||
"""
|
||
计算Dwisaptati Sama Dasha(72年周期)。
|
||
|
||
每个主星周期 = 9年,子周期按Vimshottari比例分配。
|
||
"""
|
||
start_idx = DWISAPTATI_LORDS.index(lagna_lord)
|
||
sequence = []
|
||
current = birth_date
|
||
|
||
for i in range(8):
|
||
lord_idx = (start_idx + i) % 8
|
||
lord = DWISAPTATI_LORDS[lord_idx]
|
||
days = 9 * YEAR_DAYS
|
||
end_date = current + timedelta(days=days)
|
||
|
||
# 子周期
|
||
subs = []
|
||
sub_start = current
|
||
for j in range(8):
|
||
sub_lord_idx = (lord_idx + j) % 8
|
||
sub_lord = DWISAPTATI_LORDS[sub_lord_idx]
|
||
sub_days = days * (VIMSHOTTARI_DURATION.get(sub_lord, 9) / 120)
|
||
sub_end = sub_start + timedelta(days=sub_days)
|
||
subs.append({'lord': sub_lord, 'start': sub_start.strftime('%Y-%m-%d'),
|
||
'end': sub_end.strftime('%Y-%m-%d')})
|
||
sub_start = sub_end
|
||
|
||
sequence.append({
|
||
'lord': lord, 'years': 9,
|
||
'start': current.strftime('%Y-%m-%d'),
|
||
'end': end_date.strftime('%Y-%m-%d'),
|
||
'sub_periods': subs[:4],
|
||
})
|
||
current = end_date
|
||
|
||
return sequence
|
||
|
||
|
||
# =============================================================================
|
||
# Shattrimsa Sama Dasha (36年周期)
|
||
# 适用条件:特定条件触发(Moon-based condition)
|
||
# 主星序列:9星,每星4年
|
||
# =============================================================================
|
||
|
||
SHATTRIMSA_DURATION = {l: 4 for l in DASHA_ORDER}
|
||
|
||
|
||
def check_shattrimsa_condition(moon_sign: str) -> bool:
|
||
"""Shattrimsa触发条件:Moon在特定星座/条件时"""
|
||
return True # 简化:总可用
|
||
|
||
|
||
def calc_shattrimsa_dasha(birth_date: datetime, moon_nakshatra_idx: int) -> List[Dict]:
|
||
"""计算Shattrimsa Sama Dasha(36年周期)。每个主星=4年"""
|
||
start_lord_idx = moon_nakshatra_idx % 9
|
||
sequence = []
|
||
current = birth_date
|
||
|
||
for i in range(9):
|
||
lord_idx = (start_lord_idx + i) % 9
|
||
lord = DASHA_ORDER[lord_idx]
|
||
days = 4 * YEAR_DAYS
|
||
end_date = current + timedelta(days=days)
|
||
|
||
sequence.append({
|
||
'lord': lord, 'years': 4,
|
||
'start': current.strftime('%Y-%m-%d'),
|
||
'end': end_date.strftime('%Y-%m-%d'),
|
||
})
|
||
current = end_date
|
||
|
||
return sequence
|
||
|
||
|
||
# =============================================================================
|
||
# Dwadashottari Dasha (112年周期)
|
||
# 适用条件:当Venus在特定Nakshatra(Revati/UttaraBhadrapada等)时触发
|
||
# 主星序列:特定8星,不同年限
|
||
# =============================================================================
|
||
|
||
DWADASHOTTARI_LORDS = ['Sun','Jupiter','Ketu','Mercury','Rahu','Mars','Saturn','Moon']
|
||
DWADASHOTTARI_YEARS = {'Sun':7,'Jupiter':9,'Ketu':11,'Mercury':13,'Rahu':15,'Mars':17,'Saturn':19,'Moon':21}
|
||
|
||
VENUS_TRIGGER_NAKSHATRAS = {24, 25, 26} # Shatabhisha, Purva Bhadra, Uttara Bhadra
|
||
|
||
|
||
def check_dwadashottari_condition(venus_nakshatra_idx: int) -> bool:
|
||
"""Dwadashottari触发条件:Venus在特定Nakshatra"""
|
||
return venus_nakshatra_idx in VENUS_TRIGGER_NAKSHATRAS
|
||
|
||
|
||
def calc_dwadashottari_dasha(birth_date: datetime, moon_degree: float) -> List[Dict]:
|
||
"""计算Dwadashottari Dasha(112年周期)"""
|
||
nak_idx = int(moon_degree / (360/27))
|
||
start_lord_idx = nak_idx % 8
|
||
sequence = []
|
||
current = birth_date
|
||
|
||
for i in range(8):
|
||
lord_idx = (start_lord_idx + i) % 8
|
||
lord = DWADASHOTTARI_LORDS[lord_idx]
|
||
years = DWADASHOTTARI_YEARS[lord]
|
||
days = years * YEAR_DAYS
|
||
end_date = current + timedelta(days=days)
|
||
|
||
sequence.append({
|
||
'lord': lord, 'years': years,
|
||
'start': current.strftime('%Y-%m-%d'),
|
||
'end': end_date.strftime('%Y-%m-%d'),
|
||
})
|
||
current = end_date
|
||
|
||
return sequence
|
||
|
||
|
||
# =============================================================================
|
||
# 条件性Dasha综合选择器
|
||
# =============================================================================
|
||
|
||
def get_applicable_dashas(planets: Dict, lagna_sign: str, moon_degree: float) -> Dict:
|
||
"""
|
||
根据星盘条件推荐适用���Dasha系统。
|
||
|
||
Returns:
|
||
各Dasha系统的触发状态和计算结果
|
||
"""
|
||
results = {'vimshottari': {'applicable': True, 'note': '始终适用(120年标准周期)'}}
|
||
|
||
# Dwisaptati
|
||
lagna_lord = {'Aries':'Mars','Taurus':'Venus','Gemini':'Mercury','Cancer':'Moon',
|
||
'Leo':'Sun','Virgo':'Mercury','Libra':'Venus','Scorpio':'Mars',
|
||
'Sagittarius':'Jupiter','Capricorn':'Saturn','Aquarius':'Saturn','Pisces':'Jupiter'}.get(lagna_sign, '')
|
||
lord_house = planets.get(lagna_lord, {}).get('house', 0)
|
||
if check_dwisaptati_condition(lagna_lord, lord_house):
|
||
results['dwisaptati'] = {'applicable': True, 'note': f'Lagna lord {lagna_lord}在{lord_house}宫——72年周期激活'}
|
||
|
||
# Shattrimsa
|
||
if check_shattrimsa_condition(lagna_sign):
|
||
results['shattrimsa'] = {'applicable': True, 'note': 'Moon-based condition——36年周期可用'}
|
||
|
||
# Dwadashottari
|
||
venus_data = planets.get('Venus', {})
|
||
venus_nak = int(venus_data.get('degree', 0) / (360/27))
|
||
if check_dwadashottari_condition(venus_nak):
|
||
results['dwadashottari'] = {'applicable': True, 'note': f'Venus在触发星宿——112年周期激活'}
|
||
|
||
return results
|