diff --git a/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py b/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py index 0e08c8a..4bacdc7 100644 --- a/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py +++ b/src/ibex_bluesky_core/callbacks/fitting/fitting_utils.py @@ -331,14 +331,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])