diff --git a/tests/test_processing.py b/tests/test_processing.py index 0f371660..35d87961 100644 --- a/tests/test_processing.py +++ b/tests/test_processing.py @@ -199,3 +199,41 @@ def test_xqrs(self): assert comparitor.sensitivity > 0.99 assert comparitor.positive_predictivity > 0.99 + + pass + + +# Module-level tests for empty-annotation edge cases (pytest collects these +# directly, unlike the lowercase class above which is skipped by default). + +def test_compare_annotations_empty_ref(): + """When reference annotations are empty, sensitivity should be NaN.""" + import math + + comparitor = processing.compare_annotations( + np.array([]), np.array([10, 20, 30]), 5 + ) + assert math.isnan(comparitor.sensitivity) + assert comparitor.positive_predictivity == 0.0 + + +def test_compare_annotations_empty_test(): + """When test annotations are empty, PPV should be NaN.""" + import math + + comparitor = processing.compare_annotations( + np.array([10, 20, 30]), np.array([]), 5 + ) + assert comparitor.sensitivity == 0.0 + assert math.isnan(comparitor.positive_predictivity) + + +def test_compare_annotations_both_empty(): + """When both annotation arrays are empty, both metrics should be NaN.""" + import math + + comparitor = processing.compare_annotations( + np.array([]), np.array([]), 5 + ) + assert math.isnan(comparitor.sensitivity) + assert math.isnan(comparitor.positive_predictivity) diff --git a/wfdb/processing/evaluate.py b/wfdb/processing/evaluate.py index 3e960286..78a8c695 100644 --- a/wfdb/processing/evaluate.py +++ b/wfdb/processing/evaluate.py @@ -123,8 +123,11 @@ def _calc_stats(self): self.fn = self.n_ref - self.tp # No tn attribute - self.sensitivity = float(self.tp) / float(self.tp + self.fn) - self.positive_predictivity = float(self.tp) / self.n_test + denom_sens = self.tp + self.fn + self.sensitivity = float(self.tp) / denom_sens if denom_sens > 0 else float("nan") + self.positive_predictivity = ( + float(self.tp) / self.n_test if self.n_test > 0 else float("nan") + ) def compare(self): """