Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
(#1282) Trigger snapshots after robot load
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicOram committed Apr 24, 2024
1 parent 2ea3913 commit c20a4da
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
21 changes: 21 additions & 0 deletions src/hyperion/experiment_plans/robot_load_then_centre_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dataclasses
import json
from datetime import datetime
from typing import cast

import bluesky.plan_stubs as bps
Expand All @@ -26,6 +27,7 @@
from dodal.devices.synchrotron import Synchrotron
from dodal.devices.undulator import Undulator
from dodal.devices.undulator_dcm import UndulatorDCM
from dodal.devices.webcam import Webcam
from dodal.devices.xbpm_feedback import XBPMFeedback
from dodal.devices.zebra import Zebra
from dodal.devices.zocalo import ZocaloResults
Expand Down Expand Up @@ -88,6 +90,7 @@ class RobotLoadThenCentreComposite:

# RobotLoad fields
robot: BartRobot
webcam: Webcam


def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite:
Expand Down Expand Up @@ -115,6 +118,18 @@ def wait_for_smargon_not_disabled(smargon: Smargon, timeout=60):
)


def take_robot_snapshots(oav: OAV, webcam: Webcam, directory: str):
time_now = datetime.now()
snapshot_format = f"{time_now.strftime('%H%M%S')}_{{device}}_after_load"
for device in [oav.snapshot, webcam]:
yield from bps.abs_set(
device.filename, snapshot_format.format(device=device.name)
)
yield from bps.abs_set(device.directory, directory)
yield from bps.trigger(device, group="snapshots")
yield from bps.wait("snapshots")


def prepare_for_robot_load(composite: RobotLoadThenCentreComposite):
yield from bps.abs_set(
composite.aperture_scatterguard,
Expand Down Expand Up @@ -174,8 +189,14 @@ def robot_load():

yield from bps.wait("robot_load")

yield from take_robot_snapshots(
composite.oav, composite.webcam, parameters.experiment_params.snapshot_dir
)

yield from bps.create(name=CONST.DESCRIPTORS.ROBOT_LOAD)
yield from bps.read(composite.robot.barcode)
yield from bps.read(composite.oav.snapshot)
yield from bps.read(composite.webcam)
yield from bps.save()

yield from wait_for_smargon_not_disabled(composite.smargon)
Expand Down
10 changes: 9 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from dodal.log import LOGGER as dodal_logger
from dodal.log import set_up_all_logging_handlers
from ophyd.epics_motor import EpicsMotor
from ophyd.sim import NullStatus
from ophyd.status import DeviceStatus, Status
from ophyd_async.core import set_sim_value
from ophyd_async.core.async_status import AsyncStatus
Expand Down Expand Up @@ -314,7 +315,9 @@ def synchrotron():

@pytest.fixture
def oav():
return i03.oav(fake_with_ophyd_sim=True)
oav = i03.oav(fake_with_ophyd_sim=True)
oav.snapshot.trigger = MagicMock(return_value=NullStatus())
return oav


@pytest.fixture
Expand Down Expand Up @@ -405,6 +408,11 @@ def undulator_dcm():
beamline_utils.clear_devices()


@pytest.fixture
def webcam(RE):
return i03.webcam(fake_with_ophyd_sim=True)


@pytest.fixture
def aperture_scatterguard(done_status):
AperturePositions.LARGE = SingleAperturePosition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
from bluesky.utils import Msg
from dodal.devices.aperturescatterguard import AperturePositions
from dodal.devices.eiger import EigerDetector
from dodal.devices.oav.oav_detector import OAV
from dodal.devices.smargon import Smargon, StubPosition
from dodal.devices.webcam import Webcam
from numpy import isclose
from ophyd.sim import NullStatus, instantiate_fake_device

from hyperion.experiment_plans.robot_load_then_centre_plan import (
RobotLoadThenCentreComposite,
prepare_for_robot_load,
robot_load_then_centre,
take_robot_snapshots,
)
from hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
RobotLoadISPyBCallback,
Expand All @@ -29,7 +32,7 @@

@pytest.fixture
def robot_load_composite(
smargon, dcm, robot, aperture_scatterguard
smargon, dcm, robot, aperture_scatterguard, oav, webcam
) -> RobotLoadThenCentreComposite:
composite: RobotLoadThenCentreComposite = MagicMock()
composite.smargon = smargon
Expand All @@ -39,6 +42,8 @@ def robot_load_composite(
composite.aperture_scatterguard = aperture_scatterguard
composite.smargon.stub_offsets.set = MagicMock(return_value=NullStatus())
composite.aperture_scatterguard.set = MagicMock(return_value=NullStatus())
composite.oav = oav
composite.webcam = webcam
return composite


Expand Down Expand Up @@ -336,3 +341,26 @@ def test_given_ispyb_callback_attached_when_robot_load_then_centre_plan_called_t
start_load.assert_called_once_with("cm31105", 4, "12345", 40, 3)
update_barcode.assert_called_once_with(action_id, "BARCODE")
end_load.assert_called_once_with(action_id, "success", "")


@patch("hyperion.experiment_plans.robot_load_then_centre_plan.datetime")
async def test_when_take_snapshots_called_then_filename_and_directory_set_and_device_triggered(
mock_datetime: MagicMock, oav: OAV, webcam: Webcam
):
TEST_DIRECTORY = "TEST"

mock_datetime.now.return_value.strftime.return_value = "TIME"

RE = RunEngine()
oav.snapshot.trigger = MagicMock(side_effect=oav.snapshot.trigger)
webcam.trigger = MagicMock(return_value=NullStatus())

RE(take_robot_snapshots(oav, webcam, TEST_DIRECTORY))

oav.snapshot.trigger.assert_called_once()
assert oav.snapshot.filename.get() == "TIME_oav_snapshot_after_load"
assert oav.snapshot.directory.get() == TEST_DIRECTORY

webcam.trigger.assert_called_once()
assert (await webcam.filename.get_value()) == "TIME_webcam_after_load"
assert (await webcam.directory.get_value()) == TEST_DIRECTORY

0 comments on commit c20a4da

Please sign in to comment.