Skip to content

Commit

Permalink
Fix the bounds checking for returned zocalo results (#1004)
Browse files Browse the repository at this point in the history
Co-authored-by: Dominic Oram <[email protected]>
  • Loading branch information
rtuck99 and DominicOram authored Jan 27, 2025
1 parent 497f390 commit aab178f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 55 deletions.
15 changes: 13 additions & 2 deletions src/dodal/devices/fast_grid_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,19 @@ def end(self):
# refering to the first position
return self.steps_to_motor_position(self.full_steps - 1)

def is_within(self, steps):
return 0 <= steps <= self.full_steps
def is_within(self, steps: float):
"""
Determine whether a single axis coordinate is within the grid.
The coordinate is from a continuous coordinate space based on the
XRC grid where the origin corresponds to the centre of the first grid box.
Args:
steps: The coordinate to check
Returns:
True if the coordinate falls within the grid.
"""
return -0.5 <= steps <= self.full_steps - 0.5


class GridScanParamsCommon(AbstractExperimentWithBeamParams):
Expand Down
105 changes: 52 additions & 53 deletions tests/devices/unit_tests/test_gridscan.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from asyncio import TimeoutError, wait_for
from contextlib import nullcontext
from dataclasses import dataclass

import numpy as np
Expand All @@ -12,6 +13,7 @@

from dodal.devices.fast_grid_scan import (
FastGridScanCommon,
GridScanParamsCommon,
PandAFastGridScan,
PandAGridScanParams,
ZebraFastGridScan,
Expand Down Expand Up @@ -246,63 +248,62 @@ def panda_grid_scan_params():
)


@pytest.mark.parametrize(
"grid_position",
[
(np.array([-1, 2, 4])),
(np.array([11, 2, 4])),
(np.array([1, 17, 4])),
(np.array([1, 5, 22])),
],
)
def test_given_x_y_z_out_of_range_then_converting_to_motor_coords_raises(
zebra_grid_scan_params: ZebraGridScanParams,
panda_grid_scan_params: PandAGridScanParams,
grid_position,
):
with pytest.raises(IndexError):
zebra_grid_scan_params.grid_position_to_motor_position(grid_position)
with pytest.raises(IndexError):
panda_grid_scan_params.grid_position_to_motor_position(grid_position)


def test_given_x_y_z_of_origin_when_get_motor_positions_then_initial_positions_returned(
zebra_grid_scan_params: ZebraGridScanParams,
panda_grid_scan_params: PandAGridScanParams,
):
motor_positions = [
zebra_grid_scan_params.grid_position_to_motor_position(np.array([0, 0, 0])),
panda_grid_scan_params.grid_position_to_motor_position(np.array([0, 0, 0])),
]
assert [np.allclose(position, np.array([0, 1, 4])) for position in motor_positions]
@pytest.fixture(params=["zebra_grid_scan_params", "panda_grid_scan_params"])
def common_grid_scan_params(request):
return request.getfixturevalue(request.param)


@pytest.mark.parametrize(
"grid_position, expected_x, expected_y, expected_z",
"grid_position, expected",
[
(np.array([1, 1, 1]), 0.3, 1.2, 4.1),
(np.array([2, 11, 16]), 0.6, 3.2, 5.6),
(np.array([6, 5, 5]), 1.8, 2.0, 4.5),
[np.array([-1, 2, 4]), pytest.raises(IndexError)],
[np.array([11, 2, 4]), pytest.raises(IndexError)],
[np.array([1, 17, 4]), pytest.raises(IndexError)],
[np.array([1, 5, 22]), pytest.raises(IndexError)],
[np.array([0, 0, 0]), nullcontext(np.array([0, 1, 4]))],
[np.array([1, 1, 1]), nullcontext(np.array([0.3, 1.2, 4.1]))],
[np.array([2, 11, 16]), nullcontext(np.array([0.6, 3.2, 5.6]))],
[np.array([6, 5, 5]), nullcontext(np.array([1.8, 2.0, 4.5]))],
[np.array([-0.51, 5, 5]), pytest.raises(IndexError)],
[
np.array([-0.5, 5, 5]),
nullcontext(np.array([-0.5 * 0.3, 1 + 5 * 0.2, 4 + 5 * 0.1])),
],
[np.array([5, -0.51, 5]), pytest.raises(IndexError)],
[
np.array([5, -0.5, 5]),
nullcontext(np.array([5 * 0.3, 1 - 0.5 * 0.2, 4 + 5 * 0.1])),
],
[np.array([5, 5, -0.51]), pytest.raises(IndexError)],
[
np.array([5, 5, -0.5]),
nullcontext(np.array([5 * 0.3, 1 + 5 * 0.2, 4 - 0.5 * 0.1])),
],
[np.array([9.51, 5, 5]), pytest.raises(IndexError)],
[
np.array([9.5, 5, 5]),
nullcontext(np.array([9.5 * 0.3, 1 + 5 * 0.2, 4 + 5 * 0.1])),
],
[np.array([5, 14.51, 5]), pytest.raises(IndexError)],
[
np.array([5, 14.5, 5]),
nullcontext(np.array([5 * 0.3, 1 + 14.5 * 0.2, 4 + 5 * 0.1])),
],
[np.array([5, 5, 19.51]), pytest.raises(IndexError)],
[
np.array([5, 5, 19.5]),
nullcontext(np.array([5 * 0.3, 1 + 5 * 0.2, 4 + 19.5 * 0.1])),
],
],
)
def test_given_various_x_y_z_when_get_motor_positions_then_expected_positions_returned(
zebra_grid_scan_params: ZebraGridScanParams,
panda_grid_scan_params: PandAGridScanParams,
grid_position,
expected_x,
expected_y,
expected_z,
def test_given_x_y_z_out_of_range_then_converting_to_motor_coords_raises(
common_grid_scan_params: GridScanParamsCommon, grid_position, expected
):
motor_positions = [
zebra_grid_scan_params.grid_position_to_motor_position(grid_position),
panda_grid_scan_params.grid_position_to_motor_position(grid_position),
]
[
np.testing.assert_allclose(
position, np.array([expected_x, expected_y, expected_z])
with expected as expected_value:
motor_position = common_grid_scan_params.grid_position_to_motor_position(
grid_position
)
for position in motor_positions
]
assert np.allclose(motor_position, expected_value)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -333,11 +334,9 @@ def kickoff_and_complete(device: FastGridScanCommon):


def test_given_x_y_z_steps_when_full_number_calculated_then_answer_is_as_expected(
zebra_grid_scan_params: ZebraGridScanParams,
panda_grid_scan_params: PandAGridScanParams,
common_grid_scan_params: GridScanParamsCommon,
):
assert zebra_grid_scan_params.get_num_images() == 350
assert panda_grid_scan_params.get_num_images() == 350
assert common_grid_scan_params.get_num_images() == 350


@pytest.mark.parametrize(
Expand Down

0 comments on commit aab178f

Please sign in to comment.