Files
geointel/backend/tests/test_segmentation_postprocessing_config.py
T
Jens faeb58ef6d
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
Initial public release
2026-08-31 21:56:53 +02:00

62 lines
2.1 KiB
Python

"""Segmentation must honour the same post-processing configuration as detection.
Segmentation reuses the detection suppressor but passed only the IoU threshold,
so it silently fell back to the hardcoded containment constant while detection
read a configured one. A deployment tuning containment for a promoted model
changed detection behaviour and left segmentation on the old value.
"""
from __future__ import annotations
import pytest
from shapely.geometry import box
from app.core.config import Settings
def test_segmentation_has_its_own_containment_setting() -> None:
settings = Settings(_env_file=None)
assert settings.segmentation_containment_nms_threshold == pytest.approx(0.85)
def test_the_setting_is_independent_of_the_detection_one() -> None:
"""Masks and boxes overlap differently; one value need not fit both."""
settings = Settings(
_env_file=None,
yolo_containment_nms_threshold=0.7,
segmentation_containment_nms_threshold=0.95,
)
assert settings.yolo_containment_nms_threshold == pytest.approx(0.7)
assert settings.segmentation_containment_nms_threshold == pytest.approx(0.95)
def test_the_configured_value_reaches_the_suppressor() -> None:
from app.services.detection_service import DetectionService
def candidate(name: str, geometry, confidence: float):
return {
"class_name": "building",
"confidence": confidence,
"geometry": geometry,
"bbox": [0.0, 0.0, 1.0, 1.0],
"source_tile_path": f"/tiles/{name}.tif",
"properties": {"name": name},
}
outer = candidate("outer", box(0, 0, 10, 10), 0.9)
# Containment 0.9, IoU 0.09: only the containment rule can act on this pair.
mostly_nested = candidate("mostly", box(8.2, 1, 10.2, 6), 0.5)
strict = DetectionService._suppress_duplicate_candidates(
[outer, mostly_nested], iou_threshold=0.5, containment_threshold=0.95
)
loose = DetectionService._suppress_duplicate_candidates(
[outer, mostly_nested], iou_threshold=0.5, containment_threshold=0.7
)
assert len(strict) == 2
assert len(loose) == 1