From bc888aa9499d6654fab6bb400e7e1cf16e102c36 Mon Sep 17 00:00:00 2001 From: Joep Vanlier Date: Wed, 25 Dec 2024 17:42:39 +0100 Subject: [PATCH] find_beads: handle failure to estimate background --- changelog.md | 1 + lumicks/pylake/detail/bead_cropping.py | 6 +++++- lumicks/pylake/detail/tests/test_bead_crop.py | 5 ++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index c50ca4131..e076affe2 100644 --- a/changelog.md +++ b/changelog.md @@ -30,6 +30,7 @@ #### Bug fixes * Ensure that operators such as (e.g. `+`, `-`, `/`) work on [`Slice`](https://lumicks-pylake.readthedocs.io/en/latest/_api/lumicks.pylake.channel.Slice.html) with all types that are convertible to scalars. Previously these failed with zero dimensional numpy arrays and other convertible objects. +* Fixed a bug where bead edge determination could fail with an unhandled exception when determining the background failed rather than issued the expected `RuntimeError`. ## v1.5.3 | 2024-10-29 diff --git a/lumicks/pylake/detail/bead_cropping.py b/lumicks/pylake/detail/bead_cropping.py index 2f1f95802..9f9cfb4fc 100644 --- a/lumicks/pylake/detail/bead_cropping.py +++ b/lumicks/pylake/detail/bead_cropping.py @@ -5,7 +5,11 @@ def _guess_background(data): """Determine background level by determining most prominent mode""" import scipy.stats - kde_estimate = scipy.stats.gaussian_kde(data, 0.02) + try: + kde_estimate = scipy.stats.gaussian_kde(data, 0.02) + except np.linalg.LinAlgError: + return np.median(data) # Use the median count as fallback + interpolated_kde = np.arange(min(data), np.max(data)) return interpolated_kde[np.argmax(kde_estimate.pdf(interpolated_kde))] diff --git a/lumicks/pylake/detail/tests/test_bead_crop.py b/lumicks/pylake/detail/tests/test_bead_crop.py index 4f2eb01d6..1046b93ef 100644 --- a/lumicks/pylake/detail/tests/test_bead_crop.py +++ b/lumicks/pylake/detail/tests/test_bead_crop.py @@ -46,7 +46,10 @@ def test_bead_cropping_allow_negative_beads(filename, ref_edges, ref_edges_no_ne def test_bead_cropping_failure(): mock = np.zeros((100, 1)) - mock[50] = 1 # Standard deviation of the data should not be zero or the KDE estimate fails. + with pytest.raises(RuntimeError, match="Did not find two beads"): + find_beads_brightness(mock, bead_diameter_pixels=1, plot=True) + + mock[50] = 1 with pytest.raises(RuntimeError, match="Did not find two beads"): find_beads_brightness(mock, bead_diameter_pixels=1, plot=True)