Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a box width parameter that can be passed to grid detect #542

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ def run_grid_detection_plan(
oav_params,
snapshot_template,
str(snapshot_dir),
grid_width_microns=parameters.grid_width_um,
parameters.grid_width_um,
parameters.box_size_um,
)

yield from run_grid_detection_plan(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def grid_detection_plan(
snapshot_template: str,
snapshot_dir: str,
grid_width_microns: float,
box_size_um: float = 20,
box_size_um: float,
):
"""
Creates the parameters for two grids that are 90 degrees from each other and
Expand Down
3 changes: 2 additions & 1 deletion src/mx_bluesky/hyperion/parameters/gridscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def detector_params(self):
)


class GridScanWithEdgeDetect(GridCommon): ...
class GridScanWithEdgeDetect(GridCommon):
box_size_um: float = Field(default=CONST.PARAM.GRIDSCAN.BOX_WIDTH_UM)


class PinTipCentreThenXrayCentre(GridCommon):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from dodal.beamlines import i03
from dodal.devices.aperturescatterguard import ApertureValue
from dodal.devices.backlight import BacklightPosition
from dodal.devices.eiger import EigerDetector
from dodal.devices.oav.oav_detector import OAVConfigParams
from dodal.devices.oav.oav_parameters import OAVParameters
from dodal.devices.smargon import Smargon
Expand Down Expand Up @@ -132,43 +131,39 @@ async def test_detect_grid_and_do_gridscan(
mock_grid_detection_plan: MagicMock,
grid_detect_devices_with_oav_config_params: GridDetectThenXRayCentreComposite,
RE: RunEngine,
smargon: Smargon,
test_full_grid_scan_params: GridScanWithEdgeDetect,
test_config_files: dict,
):
mock_grid_detection_plan.side_effect = _fake_grid_detection

with patch.object(
grid_detect_devices_with_oav_config_params.aperture_scatterguard,
"set",
MagicMock(),
) as mock_aperture_scatterguard:
RE(
ispyb_activation_wrapper(
detect_grid_and_do_gridscan(
grid_detect_devices_with_oav_config_params,
parameters=test_full_grid_scan_params,
oav_params=OAVParameters(
"xrayCentring", test_config_files["oav_config_json"]
),
composite = grid_detect_devices_with_oav_config_params

RE(
ispyb_activation_wrapper(
detect_grid_and_do_gridscan(
composite,
parameters=test_full_grid_scan_params,
oav_params=OAVParameters(
"xrayCentring", test_config_files["oav_config_json"]
),
test_full_grid_scan_params,
)
),
test_full_grid_scan_params,
)
# Verify we called the grid detection plan
mock_grid_detection_plan.assert_called_once()
)
# Verify we called the grid detection plan
mock_grid_detection_plan.assert_called_once()

# Check backlight was moved OUT
assert (
await grid_detect_devices_with_oav_config_params.backlight.position.get_value()
== BacklightPosition.OUT
)
# Check backlight was moved OUT
assert await composite.backlight.position.get_value() == BacklightPosition.OUT

# Check aperture was changed to SMALL
mock_aperture_scatterguard.assert_called_once_with(ApertureValue.SMALL)
# Check aperture was changed to SMALL
assert (
await composite.aperture_scatterguard.selected_aperture.get_value()
== ApertureValue.SMALL
)

# Check we called out to underlying fast grid scan plan
mock_flyscan_xray_centre_plan.assert_called_once_with(ANY, ANY)
# Check we called out to underlying fast grid scan plan
mock_flyscan_xray_centre_plan.assert_called_once_with(ANY, ANY)


@patch(
Expand All @@ -182,42 +177,34 @@ async def test_detect_grid_and_do_gridscan(
def test_when_full_grid_scan_run_then_parameters_sent_to_fgs_as_expected(
mock_flyscan_xray_centre_plan: MagicMock,
mock_grid_detection_plan: MagicMock,
eiger: EigerDetector,
grid_detect_devices_with_oav_config_params: GridDetectThenXRayCentreComposite,
RE: RunEngine,
test_full_grid_scan_params: GridScanWithEdgeDetect,
test_config_files: dict,
smargon: Smargon,
):
oav_params = OAVParameters("xrayCentring", test_config_files["oav_config_json"])

mock_grid_detection_plan.side_effect = _fake_grid_detection

with patch.object(
grid_detect_devices_with_oav_config_params.aperture_scatterguard,
"set",
MagicMock(),
):
RE(
ispyb_activation_wrapper(
detect_grid_and_do_gridscan(
grid_detect_devices_with_oav_config_params,
parameters=test_full_grid_scan_params,
oav_params=oav_params,
),
test_full_grid_scan_params,
)
RE(
ispyb_activation_wrapper(
detect_grid_and_do_gridscan(
grid_detect_devices_with_oav_config_params,
parameters=test_full_grid_scan_params,
oav_params=oav_params,
),
test_full_grid_scan_params,
)
)

params: ThreeDGridScan = mock_flyscan_xray_centre_plan.call_args[0][1]
params: ThreeDGridScan = mock_flyscan_xray_centre_plan.call_args[0][1]

assert params.detector_params.num_triggers == 50
assert params.detector_params.num_triggers == 50

assert params.FGS_params.x_axis.full_steps == 10
assert params.FGS_params.y_axis.end == pytest.approx(1.511, 0.001)
assert params.FGS_params.x_axis.full_steps == 10
assert params.FGS_params.y_axis.end == pytest.approx(1.511, 0.001)

# Parameters can be serialized
params.model_dump_json()
# Parameters can be serialized
params.model_dump_json()


@patch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ def fake_devices(
yield composite, mock_image


def do_grid_and_edge_detect(composite, parameters):
yield from grid_detection_plan(
composite,
parameters=parameters,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
box_size_um=20,
)


@patch(
"dodal.common.beamlines.beamline_utils.active_device_is_same_type",
lambda a, b: True,
Expand All @@ -103,17 +114,7 @@ def test_grid_detection_plan_runs_and_triggers_snapshots(
params = OAVParameters("loopCentring", test_config_files["oav_config_json"])
composite, image = fake_devices

@bpp.run_decorator()
def decorated():
yield from grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
)

RE(decorated())
RE(bpp.run_wrapper(do_grid_and_edge_detect(composite, params)))
assert image.save.call_count == 6


Expand Down Expand Up @@ -141,15 +142,8 @@ async def test_grid_detection_plan_gives_warning_error_if_tip_not_found(
params = OAVParameters("loopCentring", test_config_files["oav_config_json"])

with pytest.raises(WarningException) as excinfo:
RE(
grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
)
)
RE(do_grid_and_edge_detect(composite, params))

assert "No pin found" in excinfo.value.args[0]


Expand Down Expand Up @@ -183,7 +177,7 @@ def decorated():
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
box_size_um=0.2,
box_size_um=box_size_um,
)

RE(decorated())
Expand Down Expand Up @@ -219,18 +213,7 @@ def test_when_grid_detection_plan_run_twice_then_values_do_not_persist_in_callba
composite, _ = fake_devices

for _ in range(2):

@bpp.run_decorator()
def decorated():
yield from grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
)

RE(decorated())
RE(bpp.run_wrapper(do_grid_and_edge_detect(composite, params)))


@patch(
Expand All @@ -251,17 +234,12 @@ def test_when_grid_detection_plan_run_then_ispyb_callback_gets_correct_values(
cb = GridscanISPyBCallback()
RE.subscribe(cb)

def decorated():
yield from grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
)

with patch.multiple(cb, activity_gated_start=DEFAULT, activity_gated_event=DEFAULT):
RE(ispyb_activation_wrapper(decorated(), test_fgs_params))
RE(
ispyb_activation_wrapper(
do_grid_and_edge_detect(composite, params), test_fgs_params
)
)

assert_event(
cb.activity_gated_start.mock_calls[0], # pyright:ignore
Expand Down Expand Up @@ -316,16 +294,11 @@ def test_when_grid_detection_plan_run_then_grid_detection_callback_gets_correct_
cb = GridDetectionCallback(composite.oav.parameters)
RE.subscribe(cb)

def decorated():
yield from grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=161.2,
RE(
ispyb_activation_wrapper(
do_grid_and_edge_detect(composite, params), test_fgs_params
)

RE(ispyb_activation_wrapper(decorated(), test_fgs_params))
)

my_grid_params = cb.get_grid_parameters()

Expand Down Expand Up @@ -366,7 +339,6 @@ def test_when_detected_grid_has_odd_y_steps_then_add_a_y_step_and_shift_grid(
):
composite, _ = fake_devices
params = OAVParameters("loopCentring", test_config_files["oav_config_json"])
grid_width_microns = 161.2
box_size_um = 20
assert composite.oav.parameters.micronsPerYPixel is not None
box_size_y_pixels = box_size_um / composite.oav.parameters.micronsPerYPixel
Expand Down Expand Up @@ -400,15 +372,7 @@ def record_set(msg: Msg):

sim_run_engine.add_handler("set", record_set)
sim_run_engine.add_handler("read", handle_read)
sim_run_engine.simulate_plan(
grid_detection_plan(
composite,
parameters=params,
snapshot_dir="tmp",
snapshot_template="test_{angle}",
grid_width_microns=grid_width_microns,
)
)
sim_run_engine.simulate_plan(do_grid_and_edge_detect(composite, params))

expected_min_y = initial_min_y - box_size_y_pixels / 2 if odd else initial_min_y
expected_y_steps = 2
Expand Down
Loading