Venus/Jupiter/Moon periods no longer collapse into one marriage-opportunity line. Full reading reports the ten BPHS conditional dasha families; Skill 6.9.16. Co-authored-by: Cursor <cursoragent@cursor.com>
155 lines
6.0 KiB
Python
155 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Punarphoo observation detector + relationship event-class split."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
|
|
from punarphoo import CLAIM_BOUNDARY, circular_degree_gap, detect_punarphoo # noqa: E402
|
|
from relationship_analysis import analyze_relationship, classify_relationship_event_class # noqa: E402
|
|
|
|
|
|
def test_circular_degree_gap_wraps_around_zero() -> None:
|
|
assert circular_degree_gap(359.0, 1.0) == 2.0
|
|
assert circular_degree_gap(10.0, 20.0) == 10.0
|
|
|
|
|
|
def test_detect_punarphoo_natal_same_house_within_orb() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 311.48, "house": 7},
|
|
"Saturn": {"longitude": 319.01, "house": 7},
|
|
}
|
|
result = detect_punarphoo(planets)
|
|
assert result["natal_present"] is True
|
|
assert result["same_house"] is True
|
|
assert result["orb_deg"] < 10.0
|
|
assert result["status"] == "observation_only"
|
|
assert result["production_tuning_allowed"] is False
|
|
assert result["claim_boundary"] == CLAIM_BOUNDARY
|
|
assert result["timing_observation_active"] is False
|
|
|
|
|
|
def test_detect_punarphoo_saturn_return_to_natal_moon() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 311.48, "house": 7},
|
|
"Saturn": {"longitude": 319.01, "house": 7},
|
|
}
|
|
result = detect_punarphoo(planets, transit_saturn_longitude=311.78)
|
|
assert result["natal_present"] is True
|
|
assert result["timing_observation_active"] is True
|
|
assert result["saturn_return_to_natal_moon"]["active"] is True
|
|
assert result["claim_boundary"] == CLAIM_BOUNDARY
|
|
|
|
|
|
def test_natal_punarphoo_alone_does_not_classify_as_romantic_activation() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 311.48, "house": 7, "sign": "Aquarius"},
|
|
"Saturn": {"longitude": 319.01, "house": 7, "sign": "Aquarius"},
|
|
"Venus": {"longitude": 341.99, "house": 8, "sign": "Pisces"},
|
|
"Jupiter": {"longitude": 165.27, "house": 2, "sign": "Virgo"},
|
|
}
|
|
split = classify_relationship_event_class(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Mercury"},
|
|
ul_sign="Libra",
|
|
darakaraka="Sun",
|
|
)
|
|
assert "Punarphoo" not in split["romantic_activation"]["hits"]
|
|
assert "7H_Moon" in split["romantic_activation"]["natal_structure"]
|
|
assert "natal_Punarphoo" in split["romantic_activation"]["natal_structure"]
|
|
assert split["event_class"] != "romantic_activation"
|
|
assert split["claim_status"] == "observation_only"
|
|
assert split["negative_holdout"]["production_tuning_allowed"] is False
|
|
|
|
|
|
def test_saturn_return_to_moon_adds_punarphoo_romantic_hit() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 311.48, "house": 7, "sign": "Aquarius"},
|
|
"Saturn": {"longitude": 319.01, "house": 7, "sign": "Aquarius"},
|
|
"Venus": {"longitude": 341.99, "house": 8, "sign": "Pisces"},
|
|
}
|
|
split = classify_relationship_event_class(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Mercury"},
|
|
transit_saturn_longitude=311.48,
|
|
)
|
|
assert "Punarphoo" in split["romantic_activation"]["hits"]
|
|
assert split["event_class"] == "romantic_activation"
|
|
|
|
|
|
def test_pratyantar_does_not_drive_event_class() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 313.26, "house": 7, "sign": "Aquarius"},
|
|
"Saturn": {"longitude": 305.73, "house": 7, "sign": "Aquarius"},
|
|
"Jupiter": {"longitude": 165.27, "house": 2, "sign": "Virgo"},
|
|
"Venus": {"longitude": 341.99, "house": 8, "sign": "Pisces"},
|
|
}
|
|
jupiter_pd = classify_relationship_event_class(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Mercury", "pratyantar": "Jupiter"},
|
|
)
|
|
assert "5L_dasha" not in jupiter_pd["romantic_activation"]["hits"]
|
|
assert "5L_pd" in jupiter_pd["pd_hits"]
|
|
assert jupiter_pd["event_class"] != "romantic_activation"
|
|
|
|
venus_pd = classify_relationship_event_class(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Ketu", "pratyantar": "Venus"},
|
|
)
|
|
assert "Venus_dasha" not in venus_pd["legal_marriage"]["hits"]
|
|
assert "Venus_pd" in venus_pd["pd_hits"]
|
|
assert venus_pd["event_class"] != "legal_marriage"
|
|
|
|
|
|
def test_venus_to_natal_moon_does_not_drive_romantic_class() -> None:
|
|
planets = {
|
|
"Moon": {"longitude": 313.26, "house": 7, "sign": "Aquarius"},
|
|
"Saturn": {"longitude": 305.73, "house": 7, "sign": "Aquarius"},
|
|
"Venus": {"longitude": 341.99, "house": 8, "sign": "Pisces"},
|
|
}
|
|
split = classify_relationship_event_class(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Ketu", "pratyantar": "Venus"},
|
|
transit_venus_longitude=311.28,
|
|
)
|
|
assert "7H_Venus_to_Moon" not in split["romantic_activation"]["hits"]
|
|
assert split["event_class"] != "romantic_activation"
|
|
assert "Venus_dasha" not in split["legal_marriage"]["hits"]
|
|
venus_obs = split["romantic_activation"]["venus_to_natal_moon"]
|
|
assert venus_obs["active"] is True
|
|
assert venus_obs["drives_event_class"] is False
|
|
assert venus_obs["status"] == "observation_only"
|
|
|
|
|
|
def test_analyze_relationship_does_not_flatten_timing_into_one_label() -> None:
|
|
planets = {
|
|
"Venus": {"sign": "Pisces", "house": 8},
|
|
"Moon": {"sign": "Aquarius", "house": 7, "longitude": 311.48},
|
|
"Saturn": {"sign": "Aquarius", "house": 7, "longitude": 319.01},
|
|
"Jupiter": {"sign": "Virgo", "house": 2},
|
|
}
|
|
analysis = analyze_relationship(
|
|
planets,
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn"},
|
|
ul_sign="Libra",
|
|
darakaraka="Sun",
|
|
)
|
|
assert analysis["event_class_split"]["claim_status"] == "observation_only"
|
|
assert analysis["timing"][0]["event_class"] in {
|
|
"romantic_activation",
|
|
"relationship_formation",
|
|
"legal_marriage",
|
|
"unclassified",
|
|
}
|
|
assert "不得合并" in analysis["timing"][0]["note"]
|