From 79cf3f721f6d267ba6e6c8f4cb433f56ebf5efbd Mon Sep 17 00:00:00 2001 From: Cammille Carinan <cammille.carinan@xfel.eu> Date: Tue, 18 May 2021 11:03:20 +0200 Subject: [PATCH] Rename methods, fix and test finite_array --- src/toolbox_scs/base/knife_edge.py | 25 ++++---- src/toolbox_scs/base/tests/test_knife_edge.py | 57 +++++++++++++++---- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/toolbox_scs/base/knife_edge.py b/src/toolbox_scs/base/knife_edge.py index c2dfc35..3ccac7e 100644 --- a/src/toolbox_scs/base/knife_edge.py +++ b/src/toolbox_scs/base/knife_edge.py @@ -6,7 +6,9 @@ from scipy.optimize import curve_fit def knife_edge(positions, intensities, axisRange=None, p0=None): popt, pcov = knife_edge_base(positions, intensities, axisRange=axisRange, p0=p0) - width, std = popt[1], pcov[1, 1]**0.5 + width, std = 0, 0 + if popt is not None and pcov is not None: + width, std = popt[1], pcov[1, 1]**0.5 return width, std @@ -36,7 +38,7 @@ def prepare_arrays(positions: np.ndarray, intensities: np.ndarray, axisRange=None): # Slice if axisRange is not None: - slice_ = range_slice(positions, *axisRange) + slice_ = range_mask(positions, *axisRange) positions = positions[slice_] intensities = intensities[slice_] @@ -46,33 +48,28 @@ def prepare_arrays(positions: np.ndarray, intensities: np.ndarray, intensities = intensities.flatten() assert positions.shape == intensities.shape - # Clean both arrays by only getting finite values and sorting - positions, intensities = finite_arrays(positions, wrt=intensities) - intensities, positions = sort_arrays(intensities, wrt=positions) + # Clean both arrays by only getting finite values + positions, intensities = finite_array(positions, wrt=intensities) + intensities, positions = finite_array(intensities, wrt=positions) return positions, intensities -def sort_arrays(array, *, wrt=None): - index = np.argsort(wrt) - return array[index], wrt[index] - - -def finite_arrays(array, *, wrt=None): +def finite_array(array, *, wrt): index = np.isfinite(wrt) return array[index], wrt[index] -def range_slice(array, minimum=None, maximum=None): +def range_mask(array, minimum=None, maximum=None): default = np.ones(array.shape, dtype=np.bool) min_slice, max_slice = default, default if minimum is not None: - if minimum > array[-1]: + if minimum > np.nanmax(array): raise ValueError('The range minimum is too large.') min_slice = array >= minimum if maximum is not None: - if maximum < array[0]: + if maximum < np.nanmin(array): raise ValueError('The range maximum is too small.') max_slice = array <= maximum diff --git a/src/toolbox_scs/base/tests/test_knife_edge.py b/src/toolbox_scs/base/tests/test_knife_edge.py index 9f20a73..4699597 100644 --- a/src/toolbox_scs/base/tests/test_knife_edge.py +++ b/src/toolbox_scs/base/tests/test_knife_edge.py @@ -1,45 +1,80 @@ import numpy as np import pytest -from ..knife_edge import range_slice +from ..knife_edge import prepare_arrays, range_mask -def test_range_slice(): +def test_range_mask(): arr = np.array([1, 2, 3, 4, 5]) # Exact - slice_ = range_slice(arr, minimum=2, maximum=4) + slice_ = range_mask(arr, minimum=2, maximum=4) np.testing.assert_array_equal(slice_, [False, True, True, True, False]) # Range exceeds the closest values - slice_ = range_slice(arr, minimum=1.75, maximum=4.25) + slice_ = range_mask(arr, minimum=1.75, maximum=4.25) np.testing.assert_array_equal(slice_, [False, True, True, True, False]) # Range misses the closest values - slice_ = range_slice(arr, minimum=2.25, maximum=3.75) + slice_ = range_mask(arr, minimum=2.25, maximum=3.75) np.testing.assert_array_equal(slice_, [False, False, True, False, False]) # Equidistant - slice_ = range_slice(arr, minimum=2.5, maximum=4.5) + slice_ = range_mask(arr, minimum=2.5, maximum=4.5) np.testing.assert_array_equal(slice_, [False, False, True, True, False]) # Out of bounds, valid minimum - slice_ = range_slice(arr, minimum=0) + slice_ = range_mask(arr, minimum=0) np.testing.assert_array_equal(slice_, [True, True, True, True, True]) # Out of bounds, invalid minimum with pytest.raises(ValueError): - range_slice(arr, minimum=6) + range_mask(arr, minimum=6) # Out of bounds, valid maximum - slice_ = range_slice(arr, maximum=6) + slice_ = range_mask(arr, maximum=6) np.testing.assert_array_equal(slice_, [True, True, True, True, True]) # Out of bounds, invalid minimum with pytest.raises(ValueError): - range_slice(arr, maximum=0) + range_mask(arr, maximum=0) # with NaNs arr = np.array([1, np.nan, 3, np.nan, 5]) - slice_ = range_slice(arr, minimum=3) + slice_ = range_mask(arr, minimum=3) np.testing.assert_array_equal(slice_, [False, False, True, False, True]) + + +def test_prepare_arrays(): + # Setup test values + trains, pulses = 5, 10 + size = trains * pulses + motor = np.arange(trains) + signal = np.random.randint(100, size=(trains, pulses)) + + # Test finite motor and signal values + positions, intensities = prepare_arrays(motor, signal) + assert positions.shape == (size,) + assert intensities.shape == (size,) + + # Test finite motors and signals with NaNs + signal_nan = with_values(signal, value=np.nan, num=20) + positions, intensities = prepare_arrays(motor, signal_nan) + assert positions.shape == (size-20,) + assert np.isfinite(positions).all() + assert intensities.shape == (size-20,) + assert np.isfinite(intensities).all() + + # Test finite signals and motors with NaNs + motor_nan = with_values(motor, value=np.nan, num=3) + positions, intensities = prepare_arrays(motor_nan, signal) + assert positions.shape == ((trains-3) * pulses,) + assert np.isfinite(positions).all() + assert intensities.shape == ((trains-3) * pulses,) + assert np.isfinite(intensities).all() + + +def with_values(array, value, num=5): + copy = array.astype(np.float) + copy.ravel()[np.random.choice(copy.size, num, replace=False)] = value + return copy -- GitLab