From f8494531949876d959ddce4d513efe02c8a22806 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Wed, 20 Nov 2024 13:09:51 +0000 Subject: [PATCH] Avoid zero division --- src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py | 7 +++++-- tests/callbacks/fitting/test_fitting_methods.py | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py b/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py index d60a7ff..25e0cda 100644 --- a/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py +++ b/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py @@ -332,14 +332,17 @@ def guess( # Guessing. gradient of linear-slope part of function dy = np.gradient(y) # Return array of differences in y max_dy = np.max(dy) # Return max y difference, this will always be on the upwards slope - dx = x[1] - x[0] # Find x step + dx = abs(x[1] - x[0]) # Find x step gradient = max_dy / dx d2y = np.diff(dy) # Double differentiate y to find how gradients change inflection0 = x[np.argmax(d2y)] # Where there is positive gradient change background = min(y) # The lowest y value is the background - inflections_diff = -(background - y[np.argmax(y)]) / gradient + if gradient != 0.0: + inflections_diff = -(background - y[np.argmax(y)]) / gradient + else: + inflections_diff = dx # Fallback case, guess one x step # As linear, using y - y1 = m(x - x1) -> x = (y - y1) / gradient - x1 # The highest y value + slightly more to account for further convergence diff --git a/tests/callbacks/fitting/test_fitting_methods.py b/tests/callbacks/fitting/test_fitting_methods.py index e9be85a..c7fbc9d 100644 --- a/tests/callbacks/fitting/test_fitting_methods.py +++ b/tests/callbacks/fitting/test_fitting_methods.py @@ -447,6 +447,13 @@ def test_guess_inflections_diff(self): assert 3.0 == pytest.approx(outp["inflections_diff"].value, rel=1e-2) + def test_guess_inflections_diff_with_all_zero_data(self): + x = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0]) + y = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) + outp = SlitScan.guess()(x, y) + + assert 1.0 == pytest.approx(outp["inflections_diff"].value, rel=1e-2) + def test_guess_height_above_inflection1(self): x = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0]) y = np.array([1.0, 1.0, 2.0, 3.0, 4.0, 4.0])