Skip to content

Commit

Permalink
(DiamondLightSource/hyperion#1282) Write robot load snapshots into ispyb
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicOram committed Apr 24, 2024
1 parent bc1399d commit 1a20ea4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ def activity_gated_event(self, doc: Event) -> Event | None:
self.action_id is not None
), "ISPyB Robot load callback event called unexpectedly"
barcode = doc["data"]["robot-barcode"]
self.expeye.update_barcode(self.action_id, barcode)
oav_snapshot = doc["data"]["oav_snapshot_last_saved_path"]
webcam_snapshot = doc["data"]["webcam-last_saved_path"]
# I03 uses oav/webcam snapshots in place of before/after snapshots
self.expeye.update_barcode_and_snapshots(
self.action_id, barcode, oav_snapshot, webcam_snapshot
)

return super().activity_gated_event(doc)

Expand Down
18 changes: 15 additions & 3 deletions src/hyperion/external_interaction/ispyb/exp_eye_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,28 @@ def start_load(
response = self._send_and_get_response(url, data, post)
return response["robotActionId"]

def update_barcode(self, action_id: RobotActionID, barcode: str):
"""Update the barcode of an existing robot action.
def update_barcode_and_snapshots(
self,
action_id: RobotActionID,
barcode: str,
snapshot_before_path: str,
snapshot_after_path: str,
):
"""Update the barcode and snapshots of an existing robot action.
Args:
action_id (RobotActionID): The id of the action to update
barcode (str): The barcode to give the action
snapshot_before_path (str): Path to the snapshot before robot load
snapshot_after_path (str): Path to the snapshot after robot load
"""
url = self.base_url + self.UPDATE_ROBOT_ACTION.format(action_id=action_id)

data = {"sampleBarcode": barcode}
data = {
"sampleBarcode": barcode,
"xtalSnapshotBefore": snapshot_before_path,
"xtalSnapshotAfter": snapshot_after_path,
}
self._send_and_get_response(url, data, patch)

def end_load(self, action_id: RobotActionID, status: str, reason: str):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from dodal.devices.webcam import Webcam
from numpy import isclose
from ophyd.sim import NullStatus, instantiate_fake_device
from ophyd_async.core import set_sim_value

from hyperion.experiment_plans.robot_load_then_centre_plan import (
RobotLoadThenCentreComposite,
Expand Down Expand Up @@ -310,7 +311,7 @@ def test_when_prepare_for_robot_load_called_then_moves_as_expected(
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.end_load"
)
@patch(
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.update_barcode"
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.update_barcode_and_snapshots"
)
@patch(
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.start_load"
Expand All @@ -325,11 +326,15 @@ def test_when_prepare_for_robot_load_called_then_moves_as_expected(
def test_given_ispyb_callback_attached_when_robot_load_then_centre_plan_called_then_ispyb_deposited(
mock_centring_plan: MagicMock,
start_load: MagicMock,
update_barcode: MagicMock,
update_barcode_and_snapshots: MagicMock,
end_load: MagicMock,
robot_load_composite: RobotLoadThenCentreComposite,
robot_load_then_centre_params: RobotLoadThenCentreInternalParameters,
):
robot_load_composite.oav.snapshot.last_saved_path.put("test_oav_snapshot") # type: ignore
set_sim_value(robot_load_composite.webcam.last_saved_path, "test_webcam_snapshot")
robot_load_composite.webcam.trigger = MagicMock(return_value=NullStatus())

RE = RunEngine()
RE.subscribe(RobotLoadISPyBCallback())

Expand All @@ -339,7 +344,9 @@ def test_given_ispyb_callback_attached_when_robot_load_then_centre_plan_called_t
RE(robot_load_then_centre(robot_load_composite, robot_load_then_centre_params))

start_load.assert_called_once_with("cm31105", 4, "12345", 40, 3)
update_barcode.assert_called_once_with(action_id, "BARCODE")
update_barcode_and_snapshots.assert_called_once_with(
action_id, "BARCODE", "test_oav_snapshot", "test_webcam_snapshot"
)
end_load.assert_called_once_with(action_id, "success", "")


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import bluesky.preprocessors as bpp
import pytest
from bluesky.run_engine import RunEngine
from dodal.devices.oav.oav_detector import OAV
from dodal.devices.robot import BartRobot
from dodal.devices.webcam import Webcam
from ophyd_async.core import set_sim_value

from hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
RobotLoadISPyBCallback,
Expand Down Expand Up @@ -100,26 +103,35 @@ def test_given_end_called_but_no_start_then_exception_raised(end_load):
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.start_load"
)
@patch(
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.update_barcode"
"hyperion.external_interaction.callbacks.robot_load.ispyb_callback.ExpeyeInteraction.update_barcode_and_snapshots"
)
def test_given_plan_reads_barcode_then_data_put_in_ispyb(
update_barcode: MagicMock,
update_barcode_and_snapshots: MagicMock,
start_load: MagicMock,
end_load: MagicMock,
robot: BartRobot,
oav: OAV,
webcam: Webcam,
):
RE = RunEngine()
RE.subscribe(RobotLoadISPyBCallback())
start_load.return_value = ACTION_ID

oav.snapshot.last_saved_path.put("test_oav_snapshot") # type: ignore
set_sim_value(webcam.last_saved_path, "test_webcam_snapshot")

@bpp.run_decorator(md=metadata)
def my_plan():
yield from bps.create(name=CONST.DESCRIPTORS.ROBOT_LOAD)
yield from bps.read(robot.barcode)
yield from bps.read(oav.snapshot)
yield from bps.read(webcam)
yield from bps.save()

RE(my_plan())

start_load.assert_called_once_with("cm31105", 4, SAMPLE_ID, SAMPLE_PUCK, SAMPLE_PIN)
update_barcode.assert_called_once_with(ACTION_ID, "BARCODE")
update_barcode_and_snapshots.assert_called_once_with(
ACTION_ID, "BARCODE", "test_oav_snapshot", "test_webcam_snapshot"
)
end_load.assert_called_once_with(ACTION_ID, "success", "")
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,15 @@ def test_when_update_barcode_called_with_success_then_correct_expected_url_poste
mock_patch,
):
expeye_interactor = ExpeyeInteraction()
expeye_interactor.update_barcode(3, "test")
expeye_interactor.update_barcode_and_snapshots(
3, "test", "/tmp/before.jpg", "/tmp/after.jpg"
)

mock_patch.assert_called_once()
assert mock_patch.call_args.args[0] == "http://blah/core/robot-actions/3"
expected_data = {
"sampleBarcode": "test",
"xtalSnapshotBefore": "/tmp/before.jpg",
"xtalSnapshotAfter": "/tmp/after.jpg",
}
assert mock_patch.call_args.kwargs["json"] == expected_data

0 comments on commit 1a20ea4

Please sign in to comment.