Files
Jyotisha/tests/test_d12_parent_probes.py
T

255 lines
9.3 KiB
Python

"""D12 parent-probe research helpers. Public charts only; no production edits."""
from __future__ import annotations
from datetime import datetime
from decimal import Decimal
import pytest
from scripts.research import d12_parent_probes_lib as lib
BODIES = ("Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Rahu", "Ketu")
def signs(**updates: int) -> dict[str, int]:
base = {name: 0 for name in BODIES}
base.update(updates)
return base
def test_preregistration_locks_the_gate_numbers() -> None:
prereg = lib.load_prereg()
lib.assert_prereg_locked(prereg)
births = lib.json.loads(lib.HOLDOUT_PATH.read_text(encoding="utf-8"))["cases"]
digest = lib.case_id_digest([case["case_id"] for case in births])
assert digest == prereg["birth_records"]["case_id_sha256"]
assert len(births) == 77
def test_house_lord_career_and_separation_follow_the_preregistration() -> None:
assert lib.house_of(0, 0) == 1
assert lib.house_of(8, 0) == 9
assert lib.lord_of(0, 9) == "Jupiter"
assert lib.lord_of(0, 4) == "Moon"
assert lib.career_house(9) == 6
assert lib.career_house(10) == 7
assert lib.separated(0, 5)
assert lib.separated(0, 1)
assert not lib.separated(0, 0)
assert not lib.separated(0, 2)
def test_care_abstains_only_on_a_kendra_tie_and_financial_uses_house_2() -> None:
abstain = lib.read_probes(signs(**{name: 1 for name in BODIES}), 0, 9)
assert abstain["mother_more_daily_care"] == "abstain"
assert abstain["father_financial_lead"] == "yes"
study_no = lib.read_probes(
signs(Sun=0, Moon=1, Jupiter=3, Mercury=4, Venus=4, Mars=4, Saturn=2, Rahu=4),
1,
9,
)
assert study_no["father_guided_study"] == "no"
institutional = lib.read_probes(signs(Saturn=5), 0, 9)
assert institutional["father_work_institutional"] == "yes"
def test_missing_rahu_does_not_invent_a_node() -> None:
bare = {name: 0 for name in BODIES if name != "Rahu"}
labels = lib.read_probes(bare, 0, 9)
assert labels["parents_long_apart"] in {"yes", "no"}
def test_nearest_cut_tie_break_and_true_side() -> None:
signs_at = {-2: 1, -1: 1, 0: 1, 1: 2, 2: 2}
assert lib.nearest_cut(lib.cuts(signs_at)) == (0, 1)
tied = {-3: 0, -2: 1, -1: 1, 0: 1, 1: 1, 2: 2, 3: 2}
assert lib.nearest_cut(lib.cuts(tied)) == (1, 2)
mirror = {-3: 0, -2: 0, -1: 1, 0: 1, 1: 1, 2: 1, 3: 2}
assert lib.nearest_cut(lib.cuts(mirror)) == (-2, -1)
both = {-1: 0, 0: 1, 1: 2}
assert lib.nearest_cut(lib.cuts(both)) == (0, 1)
assert lib.true_side(signs_at, (0, 1)) == (0, 1)
with pytest.raises(RuntimeError):
lib.true_side({0: 1, 1: 1}, (0, 1))
def test_segment_representative_prefers_the_recorded_minute() -> None:
assert lib.segment_representative([-2, -1, 0, 1]) == 0
assert lib.segment_representative([-4, -3]) == -3
assert lib.segment_representative([2, 3, 4]) == 2
def test_tie_is_not_a_selection_and_unclear_is_not_counted() -> None:
answers = {probe: "yes" for probe in lib.PROBES}
same = {probe: "yes" for probe in lib.PROBES}
assert lib.side_score(same, answers) == 6
mixed = dict(same)
mixed["parents_long_apart"] = "abstain"
unclear = dict(answers)
unclear["father_guided_study"] = "unclear"
assert lib.side_score(mixed, unclear) == 4
assert lib.selection_count(
["a"],
{"a": answers},
{"a": same},
{"a": same},
) == 0
def test_fisher_yates_is_repeatable_and_shuffles_whole_vectors() -> None:
first = lib.permutation_maps(["b", "a", "c"], seed=20261012, count=3)
second = lib.permutation_maps(["b", "a", "c"], seed=20261012, count=3)
assert first == second
assert all(sorted(row) == ["a", "b", "c"] for row in first)
assigned = lib.assign_answers(
["a", "b", "c"],
["c", "a", "b"],
{"a": {"k": "yes"}, "b": {"k": "no"}, "c": {"k": "unclear"}},
)
assert assigned["a"]["k"] == "unclear"
assert assigned["b"]["k"] == "yes"
def test_window_selects_the_matching_side_and_the_head_segment() -> None:
offsets = [-1, 0, 1]
sign_at = {offset: 0 if offset < 1 else 1 for offset in offsets}
true_labels = {probe: "yes" for probe in lib.PROBES}
other_labels = {probe: "no" for probe in lib.PROBES}
predictions = {-1: true_labels, 0: true_labels, 1: other_labels}
answers = {probe: "yes" for probe in lib.PROBES}
row = lib.case_window(sign_at, predictions, answers, 1)
assert row["boundary"] is True
assert row["true_offset"] == 0
assert row["other_offset"] == 1
assert row["selected"] is True
assert row["head_hit"] is True
assert row["retained"] is True
planted = lib.plant_answers(true_labels)
assert planted["mother_more_daily_care"] == "yes"
assert lib.plant_answers({"mother_more_daily_care": "abstain", **{probe: "no" for probe in lib.PROBES if probe != "mother_more_daily_care"}})[
"mother_more_daily_care"
] == "unclear"
def test_permutation_summary_uses_the_exact_ratio() -> None:
summary = lib.permutation_summary(5, 10, [0, 1, 5, 6])
assert summary["extreme"] == 2
assert summary["p_numer"] == 3
assert summary["p_denom"] == 5
assert summary["above_null_mean"] is True
assert summary["percentile_numer"] == 2
assert lib.ratio_below(12, 1000, lib.ALPHA) is True
assert lib.ratio_below(13, 1000, lib.ALPHA) is False
assert lib.ratio_below(199, 1000, lib.ROBUST_MAX) is True
assert lib.ratio_below(200, 1000, lib.ROBUST_MAX) is False
assert lib.cell_is_significant(
{"above_null_mean": True, "p_numer": 12, "p_denom": 1000}
) is True
assert lib.cell_is_significant(
{"above_null_mean": True, "p_numer": 13, "p_denom": 1000}
) is False
def test_positive_control_detects_a_planted_difference() -> None:
sign_at = {offset: 0 if offset <= 0 else 1 for offset in range(-1, 2)}
yes_labels = {probe: "yes" for probe in lib.PROBES}
no_labels = {probe: "no" for probe in lib.PROBES}
case_ids = [f"c{index:02d}" for index in range(20)]
signs = {case_id: sign_at for case_id in case_ids}
predicted = {}
for index, case_id in enumerate(case_ids):
if index % 2 == 0:
predicted[case_id] = {-1: yes_labels, 0: yes_labels, 1: no_labels}
else:
predicted[case_id] = {-1: no_labels, 0: no_labels, 1: yes_labels}
control = lib.positive_control_cell(case_ids, signs, predicted, 1)
assert control["pipeline_exact"] is True
assert control["differing"] == 20
assert control["summary"]["observed_numer"] == 20
assert control["p_below"] is True
def test_decision_status_does_not_pass_a_small_or_blind_sample() -> None:
assert lib.decide_status(
included=77,
control_exact=True,
differing=30,
control_p_below=True,
any_robust_significant=True,
) == "pass"
assert lib.decide_status(
included=59,
control_exact=True,
differing=30,
control_p_below=True,
any_robust_significant=True,
) == "underpowered_sample"
assert lib.decide_status(
included=77,
control_exact=True,
differing=30,
control_p_below=True,
any_robust_significant=False,
) == "fail_closed"
assert lib.decide_status(
included=77,
control_exact=True,
differing=19,
control_p_below=True,
any_robust_significant=True,
) == "control_underpowered"
assert lib.decide_status(
included=77,
control_exact=False,
differing=30,
control_p_below=True,
any_robust_significant=True,
) == "control_invalid"
def test_fact_row_requires_an_opened_https_source() -> None:
row = {
"answer": "unclear",
"source_grade": "encyclopedia",
"url": "https://en.wikipedia.org/wiki/Example",
"excerpt": "The page names the parents and does not say who did the daily care.",
}
case = {"case_id": "example", "probes": {probe: dict(row) for probe in lib.PROBES}}
answers = lib.validate_fact_case(case)
assert lib.decisive_count(answers) == 0
broken = {"case_id": "example", "probes": {probe: dict(row) for probe in lib.PROBES}}
broken["probes"]["parents_long_apart"]["url"] = "http://insecure.example"
with pytest.raises(SystemExit):
lib.validate_fact_case(broken)
def test_change_count_and_canonical_bytes_are_stable() -> None:
labels = {probe: "yes" for probe in lib.PROBES}
flipped = dict(labels)
flipped["parents_long_apart"] = "no"
baseline = {"a": {0: labels, 1: labels}}
alternate = {"a": {0: labels, 1: flipped}}
assert lib.change_count(baseline, alternate, {"a": (0, 1)}) == 1
payload = {"b": 1, "a": {"d": 2, "c": 3}}
assert lib.canonical_bytes(payload) == lib.canonical_bytes(payload)
assert lib.canonical_bytes(payload).endswith(b"\n")
assert Decimal("0.0125") == lib.ALPHA
def test_production_chart_feeds_d12_without_a_second_ephemeris() -> None:
from scripts.research.d12_parent_probes_run import placement_at
birth = {
"date": "2000-01-01",
"time": "12:00",
"latitude": 0.0,
"longitude": 0.0,
"timezone_offset": 0.0,
}
placement = placement_at(datetime(2000, 1, 1, 12, 0), birth, "raman", "mean")
assert 0 <= placement.d12_lagna <= 11
assert set(lib.predict(placement, "D12", 9)) == set(lib.PROBES)
assert set(lib.predict(placement, "D1", 9)) == set(lib.PROBES)