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项目
182 lines
7.0 KiB
Python
182 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
出生时间矫正模块 v1.0
|
|
基于 vedic-astro-skills (MIT) rectifier方法论 + BPHS标准
|
|
|
|
核心方法:
|
|
1. 事件回溯法 — 收集10-25个生命事件,通过Dasha/Transit反向校准
|
|
2. Lagna边界检测 — 0-3度或27-30度自动触发
|
|
3. 分盘敏感度 — 根据矫正后精度决定分盘启用范围
|
|
4. 双Lagna对比 — 相邻星座双盘交叉验证
|
|
"""
|
|
|
|
from datetime import datetime, timedelta
|
|
from typing import Dict, List, Tuple, Optional
|
|
|
|
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
|
|
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
|
|
|
|
# 关键人生事件与宫位/Dasha的映射
|
|
EVENT_HOUSE_MAP = {
|
|
'marriage': {'primary': 7, 'secondary': [2, 11], 'karaka': 'Venus'},
|
|
'child_birth': {'primary': 5, 'secondary': [9], 'karaka': 'Jupiter'},
|
|
'career_start': {'primary': 10, 'secondary': [6, 2], 'karaka': 'Saturn'},
|
|
'career_change': {'primary': 10, 'secondary': [6, 8], 'karaka': 'Saturn'},
|
|
'promotion': {'primary': 10, 'secondary': [5, 9], 'karaka': 'Jupiter'},
|
|
'relocation': {'primary': 4, 'secondary': [12, 9], 'karaka': 'Rahu'},
|
|
'education_end': {'primary': 5, 'secondary': [9, 4], 'karaka': 'Jupiter'},
|
|
'father_death': {'primary': 9, 'secondary': [8, 4], 'karaka': 'Sun'},
|
|
'mother_death': {'primary': 4, 'secondary': [8, 2], 'karaka': 'Moon'},
|
|
'accident': {'primary': 8, 'secondary': [6, 1], 'karaka': 'Mars'},
|
|
'health_crisis': {'primary': 6, 'secondary': [8, 1], 'karaka': 'Saturn'},
|
|
'windfall': {'primary': 2, 'secondary': [11, 5], 'karaka': 'Jupiter'},
|
|
'financial_loss': {'primary': 12, 'secondary': [8, 6], 'karaka': 'Saturn'},
|
|
'spiritual_awakening': {'primary': 9, 'secondary': [12, 5], 'karaka': 'Ketu'},
|
|
}
|
|
|
|
# 矫正精度与分盘启用矩阵
|
|
ACCURACY_MATRIX = {
|
|
'minute': {'D1': True, 'D9': True, 'D10': True, 'D5': True, 'D4': True, 'D7': 'warn', 'D30': False, 'D60': False},
|
|
'15min': {'D1': True, 'D9': True, 'D10': 'warn', 'D5': 'warn', 'D4': 'warn', 'D7': False},
|
|
'1hour': {'D1': True, 'D9': 'warn'},
|
|
'unknown': {'D1': True, 'D9': 'warn'},
|
|
'rectified': {'D1': True, 'D9': True, 'D10': True, 'D5': True, 'D4': True, 'D7': 'warn', 'D30': False},
|
|
}
|
|
|
|
|
|
def check_lagna_boundary(asc_degree: float) -> Tuple[bool, str]:
|
|
"""检查Lagna是否接近星座边界(0-3度或27-30度)"""
|
|
deg_in_sign = asc_degree % 30
|
|
if deg_in_sign <= 3.0:
|
|
return True, f'Lagna接近星座起点({deg_in_sign:.1f}°),时间敏感度高'
|
|
if deg_in_sign >= 27.0:
|
|
return True, f'Lagna接近星座终点({deg_in_sign:.1f}°),可能跨星座'
|
|
return False, ''
|
|
|
|
|
|
def get_effective_accuracy(declared_accuracy: str, time_source: str) -> str:
|
|
"""根据用户声明精度和时间来源计算有效精度"""
|
|
ACCURACY_RULES = {
|
|
('minute', 'hospital'): 'minute',
|
|
('minute', 'family_clear'): '5min',
|
|
('minute', 'family_vague'): '15min',
|
|
('15min', '*'): '15min',
|
|
('1hour', '*'): '1hour',
|
|
('unknown', '*'): 'unknown',
|
|
}
|
|
for (acc, src), result in ACCURACY_RULES.items():
|
|
if (acc == declared_accuracy or acc == '*') and (src == time_source or src == '*'):
|
|
return result
|
|
return declared_accuracy
|
|
|
|
|
|
def get_enabled_vargas(accuracy: str) -> Dict[str, str]:
|
|
"""根据矫正精度获取可用的分盘列表"""
|
|
matrix = ACCURACY_MATRIX.get(accuracy, ACCURACY_MATRIX['unknown'])
|
|
result = {}
|
|
for varga, status in matrix.items():
|
|
if status is True:
|
|
result[varga] = 'enabled'
|
|
elif status == 'warn':
|
|
result[varga] = 'enabled_with_warning'
|
|
else:
|
|
result[varga] = 'disabled'
|
|
return result
|
|
|
|
|
|
def calculate_confidence(events_matched: int, events_total: int,
|
|
accuracy: str, lagna_boundary: bool) -> Dict:
|
|
"""
|
|
计算矫正置信度。
|
|
|
|
Args:
|
|
events_matched: 匹配的事件数
|
|
events_total: 总事件数
|
|
accuracy: 矫正精度
|
|
lagna_boundary: 是否在Lagna边界
|
|
|
|
Returns:
|
|
置信度评估
|
|
"""
|
|
match_rate = events_matched / events_total if events_total > 0 else 0
|
|
base_confidence = match_rate * 100
|
|
|
|
# 精度加成
|
|
if accuracy in ('minute', '5min'):
|
|
base_confidence = min(100, base_confidence + 10)
|
|
|
|
# Lagna边界扣除
|
|
if lagna_boundary:
|
|
base_confidence = max(0, base_confidence - 15)
|
|
|
|
if base_confidence >= 90:
|
|
level = 'high'
|
|
assessment = '矫正置信度高,分盘分析可用'
|
|
elif base_confidence >= 70:
|
|
level = 'medium'
|
|
assessment = '矫正置信度中等,主力盘(D1/D9)可用,高级分盘需谨慎'
|
|
elif base_confidence >= 50:
|
|
level = 'low'
|
|
assessment = '矫正置信度偏低,建议只用D1分析'
|
|
else:
|
|
level = 'insufficient'
|
|
assessment = '矫正证据不足,建议收集更多事件后重试'
|
|
|
|
return {
|
|
'confidence': round(base_confidence, 1),
|
|
'level': level,
|
|
'assessment': assessment,
|
|
'events_matched': events_matched,
|
|
'events_total': events_total,
|
|
}
|
|
|
|
|
|
def recommend_event_types(planet_positions: Dict) -> List[str]:
|
|
"""
|
|
根据星盘配置推荐适合验证的事件类型。
|
|
|
|
信号越强的领域,事件回溯命中率越高。
|
|
"""
|
|
recommendations = []
|
|
|
|
# 检查婚姻信号
|
|
if planet_positions.get('Venus', {}).get('house') in (1, 4, 7, 10):
|
|
recommendations.append('marriage')
|
|
if planet_positions.get('Jupiter', {}).get('house') in (5, 9):
|
|
recommendations.append('child_birth')
|
|
if planet_positions.get('Saturn', {}).get('house') in (10, 6):
|
|
recommendations.append('career_start')
|
|
if planet_positions.get('Rahu', {}).get('house') in (4, 9, 12):
|
|
recommendations.append('relocation')
|
|
if planet_positions.get('Mars', {}).get('house') in (8, 6, 1):
|
|
recommendations.append('accident')
|
|
if planet_positions.get('Jupiter', {}).get('house') in (2, 11):
|
|
recommendations.append('windfall')
|
|
|
|
# 最少返回3个
|
|
if len(recommendations) < 3:
|
|
recommendations.extend(['career_change', 'education_end', 'relocation'])
|
|
|
|
return recommendations[:8] # 最多8个推荐
|
|
|
|
|
|
def suggest_correction_direction(asc_degree: float, lagna_boundary: bool,
|
|
events_early: int, events_late: int) -> str:
|
|
"""
|
|
建议矫正方向(提前或延后)。
|
|
"""
|
|
if not lagna_boundary:
|
|
return 'Lagna不在边界,时间偏差可能较小'
|
|
|
|
if events_early > events_late:
|
|
direction = '提前'
|
|
minutes = abs(events_early - events_late) * 3
|
|
return f'事件偏早,建议: 出生时间**提前**约{minutes}分钟'
|
|
elif events_late > events_early:
|
|
direction = '延后'
|
|
minutes = abs(events_late - events_early) * 3
|
|
return f'事件偏晚,建议: 出生时间**延后**约{minutes}分钟'
|
|
else:
|
|
return '事件时序正常,无需大幅调整'
|