v6.1.7: Push Yoga validation F1 above 95 percent
- Inject D9/D60/Panchanga context into yoga and full-reading flows - Add --context-json support for explicit YogaContext payloads - Tighten Sankha Yoga movable-sign branch to require distinct L1/L10 lords - Regenerate validation_logic_report: FP 36, FN 67, F1 95.02%
This commit is contained in:
@@ -1,5 +1,29 @@
|
||||
# 印度占星 Skill 更新日志
|
||||
|
||||
## v6.1.7(2026-06-08)—— Yoga F1 首次突破 95% 与 Sankha 误报收紧
|
||||
|
||||
> **目标**:继续 Yoga 精度冲刺,但只发布源码语义明确、能减少误报且不牺牲召回的规则修复。
|
||||
|
||||
### 关键改进
|
||||
- `full-reading` 与 `yoga` 子命令补齐 D9/D60/Panchanga 上下文注入:出生信息路径会从 `varga-full` 构造 YogaContext,让依赖 Navamsa / Shashtiamsa 的 Yoga 规则在主链路中实际生效。
|
||||
- `yoga --context-json` 支持显式传入包含 `d9`、`d60`、`panchanga` 的上下文,便于验证脚本和外部 API 复用同一 Yoga 引擎。
|
||||
- 收紧 `sankha_yoga` 第二分支:`L1 and L10 together in a movable sign` 必须是两个不同宫主实际同宫;当 `L1 == L10`(双子/处女/射手/双鱼上升常见)时,不再把共享宫主误判为“1宫主与10宫主同宫”。
|
||||
- 修复效果:移除 Stephen Hawking、Max Planck、Cristiano Ronaldo 三个 Sankha Yoga false positive 中的 2 个(整体 FP 38→36),FN 保持 67 不变。
|
||||
- 保持“准确率优先”:未为了短期召回扩大 Thrikaala / Dharidhra / Nishkapata 等高风险规则。
|
||||
|
||||
### 验证
|
||||
```bash
|
||||
python3 -m py_compile scripts/yoga_engine.py scripts/validate_logic_v2.py
|
||||
python3 scripts/validate_logic_v2.py
|
||||
python3 scripts/jyotish_engine.py full-reading --year 1990 --month 6 --day 15 --hour 10 --minute 30 --lat 39.9 --lon 116.4 --tz 8
|
||||
```
|
||||
- 60 张测试图,82 条可对比规则
|
||||
- FP=36,FN=67
|
||||
- Precision=96.46%,Recall=93.61%,F1=95.02%
|
||||
- full-reading smoke:`summary.status=complete`,`errors=[]`,`modules=47`,`modules.yoga.context_layers=['d60','d9','panchanga']`
|
||||
|
||||
---
|
||||
|
||||
## v6.1.6(2026-06-07)—— full-reading 五系统推运收敛与接口修复
|
||||
|
||||
> **目标**:继续“合并隐藏模块→打通引擎→验证可用”的优化路线,将 Ashtottari / Yogini / Kalachakra 从独立模块进一步接入 `full-reading` 主链路。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: jyotish-vedic-astrology
|
||||
version: 6.1.6
|
||||
version: 6.1.7
|
||||
description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、Shadbala、Ashtakavarga、HTML报告、深度解盘。
|
||||
---
|
||||
|
||||
@@ -10,19 +10,19 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力
|
||||
> **严格路由**:`references/strict-workflow-router.md`(⭐涉及事业/婚恋/财务/应期/技法验证时必须优先读取)
|
||||
> **覆盖矩阵**:`references/technique-capability-matrix.md`(⭐判断技法 covered/partial/missing 时必须参考)
|
||||
> **机器注册表**:`references/technique_registry.json` + `scripts/audit_capabilities.py`(⭐用于自动审计与CI门禁)
|
||||
> **版本**:v6.1.6 | **详细变更**:`CHANGELOG.md`
|
||||
> **版本**:v6.1.7 | **详细变更**:`CHANGELOG.md`
|
||||
|
||||
## Yoga 逻辑验证指标
|
||||
|
||||
| 指标 | v6.0.45(旧基线) | v6.0.47(当前) |
|
||||
|---|---|---|
|
||||
| Precision | 83.26% | **92.50%** |
|
||||
| Recall | 91.52% | **91.71%** |
|
||||
| **F1 Score** | 87.19% | **92.10%** |
|
||||
| FP | 193 | **78** |
|
||||
| FN | 89 | **87** |
|
||||
| 指标 | v6.0.45(旧基线) | v6.1.7(当前) |
|
||||
|---|---:|---:|
|
||||
| Precision | 83.26% | **96.46%** |
|
||||
| Recall | 91.52% | **93.61%** |
|
||||
| **F1 Score** | 87.19% | **95.02%** |
|
||||
| FP | 193 | **36** |
|
||||
| FN | 89 | **67** |
|
||||
|
||||
> v6.0.46: 修复 6 条规则(FP 193→78)。v6.0.47: 修复 dharidhra bidirectional associated() → one-way aspect(),FP 未进一步下降因残余根因在 lord 解析(co-lord vs 古典宫主)和 rasi/house 差异。
|
||||
> v6.1.7 当前真实指标以 `references/validation_logic_report.json` 为准:60张测试图、82条可对比规则,FP=36、FN=67、F1=95.02%。关键提升来自 aspect 方向修正、D9/D60 上下文注入、Thrikaala Gnana 收紧、Dharidhra/Navamsa 方法恢复、五系统 Dasha Convergence 接入、full-reading YogaContext 桥接,以及 Sankha Yoga 共享宫主误报收紧。
|
||||
|
||||
---
|
||||
|
||||
@@ -313,9 +313,9 @@ $PYTHON $SCRIPT <子命令> [参数]
|
||||
|
||||
---
|
||||
|
||||
**版本**:v6.1.6-full-reading-five-dasha-convergence
|
||||
**版本**:v6.1.7-yoga-f1-95-sankha-tightening
|
||||
**创建日期**:2026-04-20
|
||||
**最后更新**:2026-06-07(v6.1.6 将 Ashtottari/Yogini/Kalachakra 接入 full-reading,Dasa Convergence 从三系统升级为 Vimshottari + Chara + Yogini + Ashtottari + Kalachakra 五系统;修复 Pancha Pakshi/RTN 接口与替代 Dasha current 周期循环。Yoga 当前以 `references/validation_logic_report.json` 为准。)
|
||||
**最后更新**:2026-06-08(v6.1.7 在 v6.1.6 五系统推运收敛基础上,收紧 Sankha Yoga 第二分支:L1/L10 共享宫主不再视为两宫主同宫,Yoga F1 首次达到 95.02%。Yoga 当前以 `references/validation_logic_report.json` 为准。)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"summary": {
|
||||
"charts_tested": 60,
|
||||
"comparable_rules": 82,
|
||||
"skill_total": 1020,
|
||||
"skill_total": 1018,
|
||||
"pyjhora_total": 1049,
|
||||
"unmapped_pyjhora": 718,
|
||||
"missing_mappings": {
|
||||
@@ -99,27 +99,22 @@
|
||||
]
|
||||
},
|
||||
"agreements": 982,
|
||||
"false_positives": 38,
|
||||
"false_positives": 36,
|
||||
"false_negatives": 67,
|
||||
"precision": 0.9627,
|
||||
"precision": 0.9646,
|
||||
"recall": 0.9361,
|
||||
"f1": 0.9493
|
||||
"f1": 0.9502
|
||||
},
|
||||
"false_positives": [
|
||||
{
|
||||
"chart": "Albert Einstein",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
"rule_name": "Dharidhra Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Albert Einstein",
|
||||
"rule_id": "bvr_bhaga_chumbana_yoga",
|
||||
"rule_name": "Bhaga Chumbana Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Nikola Tesla",
|
||||
"rule_id": "bvr_bhratruvriddhi_precise",
|
||||
"rule_name": "Bhratruvriddhi Yoga"
|
||||
"chart": "Albert Einstein",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
"rule_name": "Dharidhra Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Nikola Tesla",
|
||||
@@ -127,9 +122,9 @@
|
||||
"rule_name": "Krisanga Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Stephen Hawking",
|
||||
"rule_id": "sankha_yoga",
|
||||
"rule_name": "Sankha Yoga"
|
||||
"chart": "Nikola Tesla",
|
||||
"rule_id": "bvr_bhratruvriddhi_precise",
|
||||
"rule_name": "Bhratruvriddhi Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Charles Darwin",
|
||||
@@ -153,13 +148,13 @@
|
||||
},
|
||||
{
|
||||
"chart": "Richard Feynman",
|
||||
"rule_id": "bvr_018_ubhayachara_precise",
|
||||
"rule_name": "Ubhayachara Yoga"
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
"rule_name": "Nishkapata Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Richard Feynman",
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
"rule_name": "Nishkapata Yoga"
|
||||
"rule_id": "bvr_018_ubhayachara_precise",
|
||||
"rule_name": "Ubhayachara Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Mahatma Gandhi",
|
||||
@@ -188,13 +183,13 @@
|
||||
},
|
||||
{
|
||||
"chart": "Barack Obama",
|
||||
"rule_id": "bvr_yukthi_samanwithavagmi_yoga",
|
||||
"rule_name": "Yukthi Samanwithavagmi Yoga"
|
||||
"rule_id": "bvr_bandhubhisthyaktha_precise",
|
||||
"rule_name": "Bandhubhisthyaktha Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Barack Obama",
|
||||
"rule_id": "bvr_bandhubhisthyaktha_precise",
|
||||
"rule_name": "Bandhubhisthyaktha Yoga"
|
||||
"rule_id": "bvr_yukthi_samanwithavagmi_yoga",
|
||||
"rule_name": "Yukthi Samanwithavagmi Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Pablo Picasso",
|
||||
@@ -216,20 +211,15 @@
|
||||
"rule_id": "adhi_yoga",
|
||||
"rule_name": "Adhi Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "MS Dhoni",
|
||||
"rule_id": "bvr_karma_malika_precise",
|
||||
"rule_name": "Karma Malika Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "MS Dhoni",
|
||||
"rule_id": "bvr_mathibhramana_yoga",
|
||||
"rule_name": "Mathibhramana Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "brahma_yoga",
|
||||
"rule_name": "Brahma Yoga"
|
||||
"chart": "MS Dhoni",
|
||||
"rule_id": "bvr_karma_malika_precise",
|
||||
"rule_name": "Karma Malika Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
@@ -237,14 +227,14 @@
|
||||
"rule_name": "Vosi Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Cristiano Ronaldo",
|
||||
"rule_id": "bvr_dwadasa_sahodara_yoga",
|
||||
"rule_name": "Dwadasa Sahodara Yoga"
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "brahma_yoga",
|
||||
"rule_name": "Brahma Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Cristiano Ronaldo",
|
||||
"rule_id": "sankha_yoga",
|
||||
"rule_name": "Sankha Yoga"
|
||||
"rule_id": "bvr_dwadasa_sahodara_yoga",
|
||||
"rule_name": "Dwadasa Sahodara Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Pele",
|
||||
@@ -273,13 +263,13 @@
|
||||
},
|
||||
{
|
||||
"chart": "Princess Diana",
|
||||
"rule_id": "bvr_ayatna_griha_prapta_yoga",
|
||||
"rule_name": "Ayatna Griha Prapta Yoga"
|
||||
"rule_id": "bvr_bandhu_pujya_yoga",
|
||||
"rule_name": "Bandhu Pujya Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Princess Diana",
|
||||
"rule_id": "bvr_bandhu_pujya_yoga",
|
||||
"rule_name": "Bandhu Pujya Yoga"
|
||||
"rule_id": "bvr_ayatna_griha_prapta_yoga",
|
||||
"rule_name": "Ayatna Griha Prapta Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "J. Krishnamurti",
|
||||
@@ -288,13 +278,13 @@
|
||||
},
|
||||
{
|
||||
"chart": "Ramana Maharshi",
|
||||
"rule_id": "bvr_matru_sneha_yoga",
|
||||
"rule_name": "Matru Sneha Yoga"
|
||||
"rule_id": "bvr_utthama_graha_yoga",
|
||||
"rule_name": "Utthama Griha Yoga"
|
||||
},
|
||||
{
|
||||
"chart": "Ramana Maharshi",
|
||||
"rule_id": "bvr_utthama_graha_yoga",
|
||||
"rule_name": "Utthama Griha Yoga"
|
||||
"rule_id": "bvr_matru_sneha_yoga",
|
||||
"rule_name": "Matru Sneha Yoga"
|
||||
}
|
||||
],
|
||||
"false_negatives": [
|
||||
@@ -307,14 +297,6 @@
|
||||
"bahu_puthra_yoga_221"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Marie Curie",
|
||||
"rule_id": "parvata_yoga",
|
||||
"rule_name": "Parvata Yoga",
|
||||
"pyjhora_names": [
|
||||
"parvata_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Marie Curie",
|
||||
"rule_id": "bvr_grihanasa_yoga",
|
||||
@@ -332,6 +314,14 @@
|
||||
"thrikaala_gnana_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Marie Curie",
|
||||
"rule_id": "parvata_yoga",
|
||||
"rule_name": "Parvata Yoga",
|
||||
"pyjhora_names": [
|
||||
"parvata_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Nikola Tesla",
|
||||
"rule_id": "bvr_thrikaala_gnana_yoga",
|
||||
@@ -370,14 +360,6 @@
|
||||
"parannabhojana_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Mahatma Gandhi",
|
||||
"rule_id": "bvr_pisacha_grastha_yoga",
|
||||
"rule_name": "Pisacha Grastha Yoga",
|
||||
"pyjhora_names": [
|
||||
"pisacha_grastha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Mahatma Gandhi",
|
||||
"rule_id": "brahma_yoga",
|
||||
@@ -395,6 +377,14 @@
|
||||
"matrudeerghayur_yoga_197"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Mahatma Gandhi",
|
||||
"rule_id": "bvr_pisacha_grastha_yoga",
|
||||
"rule_name": "Pisacha Grastha Yoga",
|
||||
"pyjhora_names": [
|
||||
"pisacha_grastha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Narendra Modi",
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
@@ -412,14 +402,6 @@
|
||||
"utthama_graha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Indira Gandhi",
|
||||
"rule_id": "bvr_sumukha_precise",
|
||||
"rule_name": "Sumukha Yoga",
|
||||
"pyjhora_names": [
|
||||
"sumukha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Indira Gandhi",
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
@@ -429,6 +411,14 @@
|
||||
"nishkapata_yoga_206"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Indira Gandhi",
|
||||
"rule_id": "bvr_sumukha_precise",
|
||||
"rule_name": "Sumukha Yoga",
|
||||
"pyjhora_names": [
|
||||
"sumukha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Nelson Mandela",
|
||||
"rule_id": "bvr_apakeerthi_yoga",
|
||||
@@ -475,6 +465,15 @@
|
||||
"matru_satrutwa_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Margaret Thatcher",
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
"rule_name": "Nishkapata Yoga",
|
||||
"pyjhora_names": [
|
||||
"nishkapata_yoga_205",
|
||||
"nishkapata_yoga_206"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Margaret Thatcher",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
@@ -489,15 +488,6 @@
|
||||
"dharidhra_yoga_152"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Margaret Thatcher",
|
||||
"rule_id": "bvr_nishkapata_precise",
|
||||
"rule_name": "Nishkapata Yoga",
|
||||
"pyjhora_names": [
|
||||
"nishkapata_yoga_205",
|
||||
"nishkapata_yoga_206"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Rabindranath Tagore",
|
||||
"rule_id": "bvr_kapata_yoga",
|
||||
@@ -534,6 +524,14 @@
|
||||
"kapata_yoga_204"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Wolfgang Mozart",
|
||||
"rule_id": "bvr_theevrabuddhi_yoga",
|
||||
"rule_name": "Theevrabuddhi Yoga",
|
||||
"pyjhora_names": [
|
||||
"theevrabuddhi_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Wolfgang Mozart",
|
||||
"rule_id": "bvr_raja_bhanga_yoga",
|
||||
@@ -543,14 +541,6 @@
|
||||
"raja_bhanga_yoga_299"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Wolfgang Mozart",
|
||||
"rule_id": "bvr_theevrabuddhi_yoga",
|
||||
"rule_name": "Theevrabuddhi Yoga",
|
||||
"pyjhora_names": [
|
||||
"theevrabuddhi_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Wolfgang Mozart",
|
||||
"rule_id": "bvr_pittharoga_yoga",
|
||||
@@ -645,20 +635,6 @@
|
||||
"bahu_sthree_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Azim Premji",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
"rule_name": "Dharidhra Yoga",
|
||||
"pyjhora_names": [
|
||||
"dharidhra_yoga_144",
|
||||
"dharidhra_yoga_147",
|
||||
"dharidhra_yoga_148",
|
||||
"dharidhra_yoga_149",
|
||||
"dharidhra_yoga_150",
|
||||
"dharidhra_yoga_151",
|
||||
"dharidhra_yoga_152"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Azim Premji",
|
||||
"rule_id": "bvr_ayatna_griha_prapta_yoga",
|
||||
@@ -686,6 +662,20 @@
|
||||
"nishkapata_yoga_206"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Azim Premji",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
"rule_name": "Dharidhra Yoga",
|
||||
"pyjhora_names": [
|
||||
"dharidhra_yoga_144",
|
||||
"dharidhra_yoga_147",
|
||||
"dharidhra_yoga_148",
|
||||
"dharidhra_yoga_149",
|
||||
"dharidhra_yoga_150",
|
||||
"dharidhra_yoga_151",
|
||||
"dharidhra_yoga_152"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Muhammad Ali",
|
||||
"rule_id": "pushkala_yoga",
|
||||
@@ -713,11 +703,11 @@
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "bvr_matrunasa_precise",
|
||||
"rule_name": "Matrunasa Yoga",
|
||||
"rule_id": "bvr_matrudeerghayur_yoga",
|
||||
"rule_name": "Matrudeerghayur Yoga",
|
||||
"pyjhora_names": [
|
||||
"matrunasa_yoga_198",
|
||||
"matrunasa_yoga_199"
|
||||
"matrudeerghayur_yoga_196",
|
||||
"matrudeerghayur_yoga_197"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -730,6 +720,15 @@
|
||||
"kapata_yoga_204"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "bvr_matrunasa_precise",
|
||||
"rule_name": "Matrunasa Yoga",
|
||||
"pyjhora_names": [
|
||||
"matrunasa_yoga_198",
|
||||
"matrunasa_yoga_199"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "bvr_dharidhra_11_precise",
|
||||
@@ -744,15 +743,6 @@
|
||||
"dharidhra_yoga_152"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Lionel Messi",
|
||||
"rule_id": "bvr_matrudeerghayur_yoga",
|
||||
"rule_name": "Matrudeerghayur Yoga",
|
||||
"pyjhora_names": [
|
||||
"matrudeerghayur_yoga_196",
|
||||
"matrudeerghayur_yoga_197"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Cristiano Ronaldo",
|
||||
"rule_id": "bvr_matru_sneha_yoga",
|
||||
@@ -810,6 +800,14 @@
|
||||
"matrudeerghayur_yoga_197"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Dalai Lama",
|
||||
"rule_id": "bvr_utthama_graha_yoga",
|
||||
"rule_name": "Utthama Griha Yoga",
|
||||
"pyjhora_names": [
|
||||
"utthama_graha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Dalai Lama",
|
||||
"rule_id": "brahma_yoga",
|
||||
@@ -819,11 +817,11 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Dalai Lama",
|
||||
"rule_id": "bvr_utthama_graha_yoga",
|
||||
"rule_name": "Utthama Griha Yoga",
|
||||
"chart": "Pope Francis",
|
||||
"rule_id": "bvr_bhratruvriddhi_precise",
|
||||
"rule_name": "Bhratruvriddhi Yoga",
|
||||
"pyjhora_names": [
|
||||
"utthama_graha_yoga"
|
||||
"bhratruvriddhi_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -836,11 +834,12 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Pope Francis",
|
||||
"rule_id": "bvr_bhratruvriddhi_precise",
|
||||
"rule_name": "Bhratruvriddhi Yoga",
|
||||
"chart": "J. Krishnamurti",
|
||||
"rule_id": "bvr_grihanasa_yoga",
|
||||
"rule_name": "Grihanasa Yoga",
|
||||
"pyjhora_names": [
|
||||
"bhratruvriddhi_yoga"
|
||||
"grihanasa_yoga_191",
|
||||
"grihanasa_yoga_192"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -851,15 +850,6 @@
|
||||
"vanchana_chora_bheethi_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "J. Krishnamurti",
|
||||
"rule_id": "bvr_grihanasa_yoga",
|
||||
"rule_name": "Grihanasa Yoga",
|
||||
"pyjhora_names": [
|
||||
"grihanasa_yoga_191",
|
||||
"grihanasa_yoga_192"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Ramana Maharshi",
|
||||
"rule_id": "bvr_pittharoga_yoga",
|
||||
@@ -868,6 +858,14 @@
|
||||
"pittharoga_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Paramahansa Yogananda",
|
||||
"rule_id": "bvr_bandhubhisthyaktha_precise",
|
||||
"rule_name": "Bandhubhisthyaktha Yoga",
|
||||
"pyjhora_names": [
|
||||
"bandhubhisthyaktha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Paramahansa Yogananda",
|
||||
"rule_id": "bvr_matrunasa_precise",
|
||||
@@ -877,14 +875,6 @@
|
||||
"matrunasa_yoga_199"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Paramahansa Yogananda",
|
||||
"rule_id": "bvr_bandhubhisthyaktha_precise",
|
||||
"rule_name": "Bandhubhisthyaktha Yoga",
|
||||
"pyjhora_names": [
|
||||
"bandhubhisthyaktha_yoga"
|
||||
]
|
||||
},
|
||||
{
|
||||
"chart": "Paramahansa Yogananda",
|
||||
"rule_id": "bvr_dattha_puthra_yoga",
|
||||
|
||||
@@ -1288,7 +1288,7 @@
|
||||
"category": "auspicious",
|
||||
"logic": {
|
||||
"type": "custom",
|
||||
"expr": "\n# PyJHora/BVR-12: (L1 strong and L5/L6 in mutual kendras) OR\n# (L1 and L10 together in a movable sign and L9 strong). PyJHora strong() uses\n# house_strength >= FRIEND, not generic kendra/trikona strength.\nl1, l5, l6, l9, l10 = [lord(h) for h in [1, 5, 6, 9, 10]]\nif not all(p in ctx.planets for p in [l1, l5, l6, l9, l10]):\n False\nelse:\n l1h, l5h, l6h, l9h, l10h = [house_of(p) for p in [l1, l5, l6, l9, l10]]\n cond1 = strong(l1) and offset(l5h, l6h) in [0, 3, 6, 9] and offset(l6h, l5h) in [0, 3, 6, 9]\n cond2 = strong(l9) and house_of(l1) == house_of(l10) and movable_house(l1h)\n cond1 or cond2\n",
|
||||
"expr": "\n# PyJHora/BVR-12: (L1 strong and L5/L6 in mutual kendras) OR\n# (L1 and L10 together in a movable sign and L9 strong). PyJHora strong() uses\n# house_strength >= FRIEND, not generic kendra/trikona strength.\nl1, l5, l6, l9, l10 = [lord(h) for h in [1, 5, 6, 9, 10]]\nif not all(p in ctx.planets for p in [l1, l5, l6, l9, l10]):\n False\nelse:\n l1h, l5h, l6h, l9h, l10h = [house_of(p) for p in [l1, l5, l6, l9, l10]]\n cond1 = strong(l1) and offset(l5h, l6h) in [0, 3, 6, 9] and offset(l6h, l5h) in [0, 3, 6, 9]\n # The second branch requires actual conjunction of two distinct lords; if L1==L10\n # (common for Gemini/Virgo/Sagittarius/Pisces ascendants), PyJHora does not count\n # the shared lord as \"L1 and L10 together\" for Sankha Yoga.\n cond2 = l1 != l10 and strong(l9) and house_of(l1) == house_of(l10) and movable_house(l1h)\n cond1 or cond2\n",
|
||||
"combo_template": "上升主强且5/6宫主互为Kendra,或1/10宫主合于变动星座且9宫主强"
|
||||
},
|
||||
"effects": [
|
||||
@@ -1299,7 +1299,8 @@
|
||||
"strength": "强",
|
||||
"enabled": true,
|
||||
"source_reference": "BVR-12: L1 strong, L5/L6 in mutual Kendras",
|
||||
"bvr_chapter": "Chapter 2"
|
||||
"bvr_chapter": "Chapter 2",
|
||||
"accuracy_note": "v6.1.7: tightened movable-sign branch to require distinct L1/L10 lords; removes shared-lord false positives for dual ascendants."
|
||||
},
|
||||
{
|
||||
"id": "bheri_yoga",
|
||||
|
||||
+103
-1
@@ -418,6 +418,60 @@ def _add_chart_args(p):
|
||||
p.add_argument('--node-mode', default='mean', choices=['mean', 'true'], help='Rahu/Ketu节点口径:mean=Mean Node(默认,JHora常用/Swiss direct baseline),true=True Node(PyJHora默认)')
|
||||
|
||||
|
||||
def _varga_chart_to_yoga_context(varga_chart):
|
||||
"""Convert varga.py output into yoga_engine context chart shape."""
|
||||
if not isinstance(varga_chart, dict):
|
||||
return {}
|
||||
asc = varga_chart.get('Ascendant', {})
|
||||
asc_sign = asc.get('sign') if isinstance(asc, dict) else None
|
||||
asc_idx = SIGNS.index(asc_sign) if asc_sign in SIGNS else None
|
||||
planets_ctx = {}
|
||||
for pn, pd in varga_chart.items():
|
||||
if pn in ('Ascendant', '_meta', '_dignity', '_d9_analysis', '_d60_analysis'):
|
||||
continue
|
||||
if not isinstance(pd, dict) or 'sign' not in pd:
|
||||
continue
|
||||
sign = pd.get('sign')
|
||||
sign_idx = pd.get('sign_idx')
|
||||
if sign_idx is None and sign in SIGNS:
|
||||
sign_idx = SIGNS.index(sign)
|
||||
house = None
|
||||
if asc_idx is not None and sign_idx is not None:
|
||||
house = ((int(sign_idx) - asc_idx) % 12) + 1
|
||||
planets_ctx[pn] = {
|
||||
'sign': sign,
|
||||
'house': house,
|
||||
'degree': pd.get('degree_in_sign', pd.get('degree')),
|
||||
'degree_in_sign': pd.get('degree_in_sign', pd.get('degree')),
|
||||
'sign_idx': sign_idx,
|
||||
}
|
||||
return {
|
||||
'ascendant': asc_sign,
|
||||
'ascendant_degree': asc.get('degree_in_sign') if isinstance(asc, dict) else None,
|
||||
'planets': planets_ctx,
|
||||
}
|
||||
|
||||
|
||||
def _build_yoga_context_from_vargas(varga_result, planet_lons=None):
|
||||
"""Build optional YogaContext payload with D9/D60 and basic panchanga."""
|
||||
context = {}
|
||||
if isinstance(varga_result, dict):
|
||||
d9 = varga_result.get('D9_Navamsa') or {}
|
||||
d60 = varga_result.get('D60_Shashtiamsa') or varga_result.get('D60_Shashtyamsa') or {}
|
||||
if d9:
|
||||
context['d9'] = _varga_chart_to_yoga_context(d9)
|
||||
if d60:
|
||||
context['d60'] = _varga_chart_to_yoga_context(d60)
|
||||
if isinstance(planet_lons, dict) and 'Moon' in planet_lons and 'Sun' in planet_lons:
|
||||
tithi_no = int(((planet_lons.get('Moon', 0) - planet_lons.get('Sun', 0)) % 360) / 12) + 1
|
||||
context['panchanga'] = {
|
||||
'tithi': tithi_no,
|
||||
'paksha': 'waxing' if 1 <= tithi_no <= 15 else 'waning',
|
||||
'is_waning_moon': tithi_no > 15,
|
||||
}
|
||||
return context
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 公共星盘计算(供 chart/shadbala/ashtakavarga 共用,v3.4提取)
|
||||
# ============================================================================
|
||||
@@ -608,6 +662,8 @@ def cmd_yoga(args):
|
||||
planets = {}
|
||||
asc = args.ascendant or "Aries"
|
||||
|
||||
yoga_context = None
|
||||
|
||||
if args.planets:
|
||||
for item in args.planets.split(','):
|
||||
parts = item.strip().split(':')
|
||||
@@ -619,6 +675,12 @@ def cmd_yoga(args):
|
||||
except ValueError:
|
||||
pass
|
||||
planets[parts[0].strip()] = pdata
|
||||
context_json = getattr(args, 'context_json', None)
|
||||
if context_json:
|
||||
try:
|
||||
yoga_context = json.loads(context_json)
|
||||
except Exception:
|
||||
yoga_context = None
|
||||
else:
|
||||
required_birth_fields = ["year", "month", "day", "hour", "minute", "lat", "lon"]
|
||||
has_birth_input = all(getattr(args, field, None) is not None for field in required_birth_fields)
|
||||
@@ -630,6 +692,7 @@ def cmd_yoga(args):
|
||||
if chart is None:
|
||||
return {"error": "swisseph未安装"}
|
||||
asc = chart.get("ascendant", {}).get("sign", asc)
|
||||
planet_lons_for_varga = {}
|
||||
for pname, pd in chart.get("planets", {}).items():
|
||||
if isinstance(pd, dict) and "sign" in pd and "house" in pd:
|
||||
planets[pname] = {
|
||||
@@ -637,13 +700,25 @@ def cmd_yoga(args):
|
||||
"house": pd["house"],
|
||||
"degree": pd.get("degree_in_sign", pd.get("degree")),
|
||||
}
|
||||
if pd.get("degree_raw") is not None:
|
||||
planet_lons_for_varga[pname] = pd.get("degree_raw")
|
||||
try:
|
||||
from varga import calc_all_vargas
|
||||
asc_deg_raw = chart.get("ascendant", {}).get("degree_raw")
|
||||
if asc_deg_raw is not None and planet_lons_for_varga:
|
||||
yoga_context = _build_yoga_context_from_vargas(
|
||||
calc_all_vargas(planet_lons_for_varga, asc_deg_raw, [9, 60]),
|
||||
planet_lons_for_varga,
|
||||
)
|
||||
except Exception:
|
||||
yoga_context = None
|
||||
|
||||
ai = SIGNS.index(asc) if asc in SIGNS else 0
|
||||
kl = list(set([SIGN_LORDS[SIGNS[(ai + h - 1) % 12]] for h in [1, 4, 7, 10]]))
|
||||
tl = list(set([SIGN_LORDS[SIGNS[(ai + h - 1) % 12]] for h in [1, 5, 9]]))
|
||||
|
||||
# 调用数据驱动引擎(yoga_engine.py)
|
||||
yogas = detect_yogas(planets, asc)
|
||||
yogas = detect_yogas(planets, asc, context=yoga_context)
|
||||
|
||||
return {
|
||||
"ascendant": asc,
|
||||
@@ -3076,6 +3151,32 @@ def cmd_full_reading(args):
|
||||
if d1_data:
|
||||
varga_result["D1_Rashi"] = d1_data
|
||||
report['modules']['varga_full'] = varga_result
|
||||
|
||||
# v6.1.7: Re-run Yoga with D9/D60 context after varga-full is available.
|
||||
# The earlier Step 3 remains a D1-only fallback for backward compatibility.
|
||||
try:
|
||||
yoga_context = _build_yoga_context_from_vargas(varga_result, planet_lons)
|
||||
yoga_planets = {}
|
||||
for pn, pd in planets.items():
|
||||
if isinstance(pd, dict) and 'sign' in pd and 'house' in pd:
|
||||
yoga_planets[pn] = {
|
||||
'sign': pd['sign'],
|
||||
'house': pd['house'],
|
||||
'degree': pd.get('degree_in_sign', pd.get('degree')),
|
||||
}
|
||||
yoga_result = cmd_yoga(type('Args', (), {
|
||||
'ascendant': asc_sign,
|
||||
'planets': ','.join([
|
||||
f"{k}:{v['sign']}:{v['house']}" + (f":{v['degree']}" if v.get('degree') is not None else "")
|
||||
for k, v in yoga_planets.items()
|
||||
]),
|
||||
'context_json': json.dumps(yoga_context, ensure_ascii=False),
|
||||
})())
|
||||
yoga_result['context_layers'] = sorted(k for k, v in yoga_context.items() if v)
|
||||
report['modules']['yoga'] = yoga_result
|
||||
except Exception as yoga_ctx_e:
|
||||
report['errors'].append(f"yoga-context-injection: {yoga_ctx_e}")
|
||||
|
||||
report['modules']['vargottama'] = _calc_vargottama(planets, varga_result)
|
||||
report['modules']['pushkara'] = _calc_pushkara_flags(planets)
|
||||
except Exception as e:
|
||||
@@ -3901,6 +4002,7 @@ def main():
|
||||
_add_chart_args(p)
|
||||
p.add_argument('--ascendant', default=None)
|
||||
p.add_argument('--planets', default=None, help="格式: 'Sun:Aries:9[:10.5],Moon:Aquarius:7[:15.2],...';若提供则优先使用并忽略出生信息")
|
||||
p.add_argument('--context-json', default=None, help='可选:传入包含 d9/d60/panchanga 的 YogaContext JSON')
|
||||
for action in p._actions:
|
||||
if action.dest in ['year', 'month', 'day', 'hour', 'minute', 'lat', 'lon']:
|
||||
action.required = False
|
||||
|
||||
Reference in New Issue
Block a user