diff --git a/src/roboqa_temporal/constants.py b/src/roboqa_temporal/constants.py new file mode 100644 index 0000000..e3b396f --- /dev/null +++ b/src/roboqa_temporal/constants.py @@ -0,0 +1,7 @@ +"""Global constants used across roboqa_temporal.""" + +# Severity bounds for anomaly scores (inclusive) +MIN_SEVERITY = 0.0 +MAX_SEVERITY = 1.0 + +__all__ = ["MIN_SEVERITY", "MAX_SEVERITY"] diff --git a/src/roboqa_temporal/detection/detector.py b/src/roboqa_temporal/detection/detector.py index 5e99dea..6ff8df6 100644 --- a/src/roboqa_temporal/detection/detector.py +++ b/src/roboqa_temporal/detection/detector.py @@ -31,6 +31,7 @@ import numpy as np from roboqa_temporal.loader.bag_loader import PointCloudFrame +from roboqa_temporal.constants import MIN_SEVERITY, MAX_SEVERITY from roboqa_temporal.detection.detectors import ( DensityDropDetector, SpatialDiscontinuityDetector, @@ -54,6 +55,12 @@ class Anomaly: description: str metadata: Dict[str, Any] = field(default_factory=dict) + def __post_init__(self) -> None: + if not (MIN_SEVERITY <= self.severity <= MAX_SEVERITY): + raise ValueError( + f"severity {self.severity} outside bounds [{MIN_SEVERITY}, {MAX_SEVERITY}]" + ) + @dataclass class DetectionResult: @@ -121,6 +128,11 @@ def __init__( threshold=temporal_threshold ) + if not self.detectors: + raise ValueError( + "No detectors enabled. Enable at least one anomaly detector or adjust configuration." + ) + def detect(self, frames: List[PointCloudFrame]) -> DetectionResult: """ Run anomaly detection on a sequence of frames. diff --git a/tests/test_edge.py b/tests/test_edge.py index 22614b0..6457a2d 100644 --- a/tests/test_edge.py +++ b/tests/test_edge.py @@ -59,19 +59,13 @@ def test_detector_with_all_detectors_disabled(): reviewer: dharinesh category: edge test """ - detector = AnomalyDetector( - enable_density_detection=False, - enable_spatial_detection=False, - enable_ghost_detection=False, - enable_temporal_detection=False, - ) - - points = np.random.rand(50, 3) - frame = PointCloudFrame(timestamp=1000.0, frame_id="test", points=points) - result = detector.detect([frame]) - - assert isinstance(result, DetectionResult) - assert len(result.detector_results) == 0 + with pytest.raises(ValueError, match="No detectors enabled"): + AnomalyDetector( + enable_density_detection=False, + enable_spatial_detection=False, + enable_ghost_detection=False, + enable_temporal_detection=False, + ) def test_detector_with_extreme_thresholds():