From 8a855ee8a651a4475a92ab237b8ddd9efed49761 Mon Sep 17 00:00:00 2001 From: Joeran Bosma Date: Thu, 31 Oct 2024 15:51:57 +0100 Subject: [PATCH] Allow evaluating predictions with only background In the previous implementation, having no lesion candidates broke the evaluation. Added tests for having zero or one lesion candidate. --- setup.py | 2 +- src/picai_eval/metrics.py | 9 +++++-- tests/Development-README.md | 4 ++-- tests/test_calculate_counts.py | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 tests/test_calculate_counts.py diff --git a/setup.py b/setup.py index 56990f3..f58a41d 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,7 @@ def run(self): long_description = fh.read() setuptools.setup( - version='1.4.9', # also update version in metrics.py -> version + version='1.4.10', # also update version in metrics.py -> version author_email='Joeran.Bosma@radboudumc.nl', long_description=long_description, long_description_content_type="text/markdown", diff --git a/src/picai_eval/metrics.py b/src/picai_eval/metrics.py index b5c9636..8bdff90 100644 --- a/src/picai_eval/metrics.py +++ b/src/picai_eval/metrics.py @@ -247,8 +247,13 @@ def calculate_counts(self, subject_list: Optional[List[str]] = None) -> "Dict[st TP[i] = tp # extend curve to infinity - TP[-1] = TP[-2] - FP[-1] = np.inf + if len(TP) >= 2: + TP[-1] = TP[-2] + FP[-1] = np.inf + else: + # no lesions detected + TP = np.array([0, 0]) + FP = np.array([0, np.inf]) return { 'TP': TP, diff --git a/tests/Development-README.md b/tests/Development-README.md index 7dd3210..9e2d533 100644 --- a/tests/Development-README.md +++ b/tests/Development-README.md @@ -29,5 +29,5 @@ AutoPEP8 for formatting (this can be done automatically on save, see e.g. https: # Push release to PyPI 1. Increase version in setup.py, and set below 2. Build: `python -m build` -3. Test package distribution: `python -m twine upload --repository testpypi dist/*1.4.9*` -4. Distribute package to PyPI: `python -m twine upload dist/*1.4.9*` +3. Test package distribution: `python -m twine upload --repository testpypi dist/*1.4.10*` +4. Distribute package to PyPI: `python -m twine upload dist/*1.4.10*` diff --git a/tests/test_calculate_counts.py b/tests/test_calculate_counts.py new file mode 100644 index 0000000..b724cf4 --- /dev/null +++ b/tests/test_calculate_counts.py @@ -0,0 +1,44 @@ +import numpy as np + +from picai_eval import Metrics + + +def test_calculate_counts(): + """ + Test the lesion TPR and FPR function + """ + lesion_results = { + "0": [(0, 0, 0.)], + "1": [(0, 0, 0.)], + "2": [(1, 1, 0.)], + "3": [(1, 0, 0.), (1, 0, 0.)], + "4": [(0, 0, 0.)], + "5": [(1, 0, 0.), (1, 0, 0.)], + } + metrics = Metrics(lesion_results=lesion_results) + np.testing.assert_allclose(metrics.lesion_TPR, [0.2, 0.2]) + np.testing.assert_allclose(metrics.lesion_FPR, [0.0, np.inf]) + assert metrics.AP == 0.2 + + +def test_calculate_counts_empty(): + """ + Test the lesion TPR and FPR function + """ + lesion_results = { + "0": [(0, 0, 0.)], + "1": [(0, 0, 0.)], + "2": [(1, 0, 0.)], + "3": [(1, 0, 0.), (1, 0, 0.)], + "4": [(0, 0, 0.)], + "5": [(1, 0, 0.), (1, 0, 0.)], + } + metrics = Metrics(lesion_results=lesion_results) + np.testing.assert_allclose(metrics.lesion_TPR, [0., 0.0]) + np.testing.assert_allclose(metrics.lesion_FPR, [0.0, np.inf]) + assert metrics.AP == 0.0 + + +if __name__ == "__main__": + test_calculate_counts() + test_calculate_counts_empty()