feat(perception): mine native fisheye risk cases

This commit is contained in:
DCCONSTRUCTIONS
2026-08-26 10:15:43 +03:00
parent 385082c8ca
commit c05db1fbe0
4 changed files with 1032 additions and 0 deletions
@@ -0,0 +1,90 @@
from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
import pytest
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
RUNNER_PATH = (
REPOSITORY_ROOT / "experiments" / "perception" / "run_m48q_native_risk_case_mining_worker.py"
)
SPEC = importlib.util.spec_from_file_location("m48q_case_mining", RUNNER_PATH)
assert SPEC is not None and SPEC.loader is not None
MODULE = importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name] = MODULE
SPEC.loader.exec_module(MODULE)
def candidate(sequence: int, *buckets: str):
return MODULE.FrameCandidate(
sequence=sequence,
frame_id=f"frame-{sequence:06d}",
evidence_time_ns=sequence * 1_000_000,
proposals=(),
native_count=0,
legacy_count=0,
matched_count=0,
buckets=frozenset(buckets),
)
def test_selection_is_deterministic_balanced_and_separated() -> None:
candidates = [
candidate(sequence, "person" if sequence % 2 == 0 else "vehicle")
for sequence in range(0, 400, 5)
]
quotas = {"person": 3, "vehicle": 3}
first = MODULE.select_cases(
candidates,
bucket_quotas=quotas,
minimum_sequence_separation=10,
)
second = MODULE.select_cases(
candidates,
bucket_quotas=quotas,
minimum_sequence_separation=10,
)
assert [item.sequence for item in first] == [item.sequence for item in second]
assert len(first) == 6
assert all(
abs(left.sequence - right.sequence) >= 10
for index, left in enumerate(first)
for right in first[index + 1 :]
)
def test_selection_refuses_missing_bucket_coverage() -> None:
with pytest.raises(MODULE.M48QCaseMiningError, match="animal produced 0/1"):
MODULE.select_cases(
[candidate(0, "person")],
bucket_quotas={"animal": 1},
minimum_sequence_separation=1,
)
def test_profile_freezes_raw_raster_and_false_authority() -> None:
import json
profile = json.loads(
(
REPOSITORY_ROOT / "config" / "perception" / "m48q-native-risk-case-mining-v1.json"
).read_text("utf-8")
)
assert profile["source"] == {
"source_id": "RAVNOVES00",
"frame_count": 4489,
"raster_width": 800,
"raster_height": 600,
"video_sha256": "cadd1696ff000904eb78633a0a8418104b8024f178b91f3421789021ccb160e8",
"geometric_resampling": False,
"rectification": False,
"warp": False,
}
assert sum(profile["selection"]["bucket_quotas"].values()) == 24
assert profile["scope"]["quality_evaluated"] is False
assert profile["authority"] == MODULE.FALSE_AUTHORITY