batdetect2/tests/utils.py
2026-06-22 20:29:25 -06:00

58 lines
1.6 KiB
Python

import numpy as np
from soundevent.geometry import compute_bounds
from batdetect2.postprocess.types import ClipDetections
def assert_clip_detections_equal(
detections: ClipDetections,
other: ClipDetections,
) -> None:
"""Assert two clip-detection objects are numerically equivalent."""
assert detections.clip.recording.path == other.clip.recording.path
assert detections.clip.start_time == other.clip.start_time
assert detections.clip.end_time == other.clip.end_time
assert len(detections.detections) == len(other.detections)
sorted_detections = sorted(
detections.detections,
key=lambda det: (
compute_bounds(det.geometry)[0],
compute_bounds(det.geometry)[1],
),
)
sorted_other = sorted(
other.detections,
key=lambda det: (
compute_bounds(det.geometry)[0],
compute_bounds(det.geometry)[1],
),
)
for det, other_det in zip(
sorted_detections,
sorted_other,
strict=True,
):
np.testing.assert_allclose(
np.array(compute_bounds(det.geometry)),
np.array(compute_bounds(other_det.geometry)),
atol=2e-2,
)
assert np.isclose(
det.detection_score,
other_det.detection_score,
atol=1e-6,
)
np.testing.assert_allclose(
det.class_scores,
other_det.class_scores,
atol=1e-6,
)
np.testing.assert_allclose(
det.features,
other_det.features,
atol=2e-6,
)