Files
geointel/backend/tests/test_sprint134_guided_detection_calibration_runner.py
T
JensandClaude Opus 5 2cd2c49389 calibrate a confidence threshold from one inference pass
Threshold calibration ran the model over every tile once per threshold — three
GPU passes to compare 0.50, 0.25 and 0.15 on a hundred-tile raster. The answer
is already in a single run at the lowest value: detections above a higher cut
are a subset of it, and duplicate suppression walks candidates in descending
confidence, so a lower-confidence box can never displace a higher-confidence
one. The kept set above any cut is identical whichever threshold the run used,
which is what makes one pass sufficient rather than merely cheaper.

QA now takes calibration_thresholds and reads each operating point off the same
precision/recall walk it already performs, marking the F1-optimal cut. The lab
runs inference once and fills its table from the sweep.

The contract test asserted the per-threshold loop by name, pinning the waste it
was meant to describe. It now states what calibration owes an operator: a row
per requested threshold, from one run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:37:19 +02:00

58 lines
3.0 KiB
Python

from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
def test_detection_lab_has_guided_threshold_calibration_runner() -> None:
hook = ROOT / "frontend" / "src" / "hooks" / "useDetectionWorkflow.ts"
lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
app = ROOT / "frontend" / "src" / "App.tsx"
todo = ROOT / "docs" / "TODO.md"
hook_source = hook.read_text(encoding="utf-8")
lab_source = lab.read_text(encoding="utf-8")
app_source = app.read_text(encoding="utf-8")
todo_source = todo.read_text(encoding="utf-8")
assert "interface DetectionCalibrationRunRow" in hook_source
assert "parseCalibrationThresholds" in hook_source
assert "calibrationThresholdText" in hook_source
assert "runningDetectionCalibration" in hook_source
assert "detectionCalibrationRows" in hook_source
assert "detectionCalibrationError" in hook_source
assert "runDetectionCalibration" in hook_source
assert "detectionApi.run({" in hook_source
# Every requested threshold is reported, but from one inference pass at the
# lowest cut: detections above a higher cut are a subset of it, and
# suppression walks candidates in descending confidence, so the kept set
# above a cut does not depend on the threshold the run used. Asserting the
# old per-threshold loop pinned N GPU passes that produced identical numbers.
assert "confidence_threshold: lowestThreshold" in hook_source
assert "calibration_thresholds: thresholds" in hook_source
assert "calibration_sweep" in hook_source
assert "parameters_json: { calibration: true, calibration_thresholds: thresholds }" in hook_source
assert "detectionApi.compareWithReference(result.analysis_run_id" in hook_source
assert "reference_dataset_id: detectionReferenceDatasetId" in hook_source
assert "Select a reference dataset before calibration" in hook_source
assert "Provide at least one valid threshold between 0 and 1" in hook_source
assert "Configured YOLO calibration requires a tile manifest" in hook_source
assert "Select a local model asset before calibration" in hook_source
assert "Modelkalibratie voor beheerders" in lab_source
assert "Voert het lokale model en een kwaliteitscontrole uit" in lab_source
assert "Zekerheidsdrempels" in lab_source
assert "Drempels vergelijken" in lab_source
assert "Voortgang modelkalibratie" in lab_source
assert "detectionCalibrationRows.map" in lab_source
assert "runningDetectionCalibration" in lab_source
assert "detectionCalibrationError" in lab_source
assert "onRunCalibration" in lab_source
assert "onSetCalibrationThresholdText" in lab_source
assert "calibrationThresholdText={calibrationThresholdText}" in app_source
assert "runningDetectionCalibration={runningDetectionCalibration}" in app_source
assert "detectionCalibrationRows={detectionCalibrationRows}" in app_source
assert "onRunCalibration={runDetectionCalibration}" in app_source
assert "[x] Add guided in-app detection calibration runner" in todo_source