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

Commit

Permalink
Merge pull request #711 from DiamondLightSource/368_generalise_ispyb_…
Browse files Browse the repository at this point in the history
…handling

368 generalise ispyb handling to rotation scans
  • Loading branch information
dperl-dls authored Jul 27, 2023
2 parents 3ea6e6f + 2f3a95f commit 997ea2e
Show file tree
Hide file tree
Showing 33 changed files with 1,342 additions and 449 deletions.
29 changes: 29 additions & 0 deletions src/artemis/device_setup_plans/read_hardware_for_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from __future__ import annotations

import bluesky.plan_stubs as bps
from dodal.beamlines.i03 import Attenuator, Flux, S4SlitGaps, Synchrotron, Undulator

import artemis.log
from artemis.parameters.constants import ISPYB_PLAN_NAME


def read_hardware_for_ispyb(
undulator: Undulator,
synchrotron: Synchrotron,
s4_slit_gaps: S4SlitGaps,
attenuator: Attenuator,
flux: Flux,
):
artemis.log.LOGGER.info(
"Reading status of beamline parameters for ispyb deposition."
)
yield from bps.create(
name=ISPYB_PLAN_NAME
) # gives name to event *descriptor* document
yield from bps.read(undulator.gap)
yield from bps.read(synchrotron.machine_status.synchrotron_mode)
yield from bps.read(s4_slit_gaps.xgap)
yield from bps.read(s4_slit_gaps.ygap)
yield from bps.read(attenuator.actual_transmission)
yield from bps.read(flux.flux_reading)
yield from bps.save()
29 changes: 3 additions & 26 deletions src/artemis/experiment_plans/fast_grid_scan_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from dodal.devices.fast_grid_scan import set_fast_grid_scan_params

import artemis.log
from artemis.device_setup_plans.read_hardware_for_setup import read_hardware_for_ispyb
from artemis.device_setup_plans.setup_zebra import (
set_zebra_shutter_to_manual,
setup_zebra_for_fgs,
Expand All @@ -40,7 +41,7 @@
get_beamline_parameters,
get_beamline_prefixes,
)
from artemis.parameters.constants import ISPYB_PLAN_NAME, SIM_BEAMLINE
from artemis.parameters.constants import SIM_BEAMLINE
from artemis.tracing import TRACER

if TYPE_CHECKING:
Expand Down Expand Up @@ -74,9 +75,7 @@ def __init__(
fake_with_ophyd_sim=fake, aperture_positions=aperture_positions
)
self.backlight = i03.backlight(fake_with_ophyd_sim=fake)
self.eiger = i03.eiger(
wait_for_connection=False, fake_with_ophyd_sim=fake, params=detector_params
)
self.eiger = i03.eiger(fake_with_ophyd_sim=fake, params=detector_params)
self.fast_grid_scan = i03.fast_grid_scan(fake_with_ophyd_sim=fake)
self.flux = i03.flux(fake_with_ophyd_sim=fake)
self.s4_slit_gaps = i03.s4_slit_gaps(fake_with_ophyd_sim=fake)
Expand Down Expand Up @@ -130,28 +129,6 @@ def set_aperture():
yield from set_aperture()


def read_hardware_for_ispyb(
undulator: Undulator,
synchrotron: Synchrotron,
s4_slit_gaps: S4SlitGaps,
attenuator: Attenuator,
flux: Flux,
):
artemis.log.LOGGER.info(
"Reading status of beamline parameters for ispyb deposition."
)
yield from bps.create(
name=ISPYB_PLAN_NAME
) # gives name to event *descriptor* document
yield from bps.read(undulator.gap)
yield from bps.read(synchrotron.machine_status.synchrotron_mode)
yield from bps.read(s4_slit_gaps.xgap)
yield from bps.read(s4_slit_gaps.ygap)
yield from bps.read(attenuator.actual_transmission)
yield from bps.read(flux.flux_reading)
yield from bps.save()


@bpp.set_run_key_decorator("move_xyz")
@bpp.run_decorator(md={"subplan_name": "move_xyz"})
def move_xyz(
Expand Down
37 changes: 25 additions & 12 deletions src/artemis/experiment_plans/rotation_scan_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
from dodal.devices.eiger import DetectorParams, EigerDetector
from dodal.devices.smargon import Smargon
from dodal.devices.zebra import RotationDirection, Zebra
from ophyd.device import Device
from ophyd.epics_motor import EpicsMotor

from artemis.device_setup_plans.read_hardware_for_setup import read_hardware_for_ispyb
from artemis.device_setup_plans.setup_zebra import (
arm_zebra,
disarm_zebra,
Expand All @@ -34,17 +36,14 @@


def create_devices() -> dict[str, Device]:
eiger = i03.eiger(wait_for_connection=False)
smargon = i03.smargon()
zebra = i03.zebra()
detector_motion = i03.detector_motion()
backlight = i03.backlight()
"""Ensures necessary devices have been instantiated and returns a dict with
references to them"""
return {
"eiger": eiger,
"smargon": smargon,
"zebra": zebra,
"detector_motion": detector_motion,
"backlight": backlight,
"eiger": i03.eiger(),
"smargon": i03.smargon(),
"zebra": i03.zebra(),
"detector_motion": i03.detector_motion(),
"backlight": i03.backlight(),
}


Expand Down Expand Up @@ -97,11 +96,14 @@ def move_to_end_w_buffer(axis: EpicsMotor, scan_width: float, wait: float = True


def set_speed(axis: EpicsMotor, image_width, exposure_time, wait=True):
speed_for_rotation = image_width / exposure_time
yield from bps.abs_set(
axis.velocity, image_width / exposure_time, group="set_speed", wait=True
axis.velocity, speed_for_rotation, group="set_speed", wait=wait
)


@bpp.set_run_key_decorator("rotation_scan_main")
@bpp.run_decorator(md={"subplan_name": "rotation_scan_main"})
def rotation_scan_plan(
params: RotationInternalParameters,
eiger: EigerDetector,
Expand All @@ -125,7 +127,16 @@ def rotation_scan_plan(
yield from setup_sample_environment(detector_motion, backlight)
LOGGER.info(f"moving omega to beginning, start_angle={start_angle}")
yield from move_to_start_w_buffer(smargon.omega, start_angle)
LOGGER.info("wait for any previous moves...")

# get some information for the ispyb deposition and trigger the callback
yield from read_hardware_for_ispyb(
i03.undulator(),
i03.synchrotron(),
i03.s4_slit_gaps(),
i03.attenuator(),
i03.flux(),
)

LOGGER.info(
f"setting up zebra w: start_angle={start_angle}, scan_width={scan_width}"
)
Expand All @@ -140,6 +151,8 @@ def rotation_scan_plan(
),
group="setup_zebra",
)

LOGGER.info("wait for any previous moves...")
# wait for all the setup tasks at once
yield from bps.wait("setup_senv")
yield from bps.wait("move_to_start")
Expand Down
30 changes: 29 additions & 1 deletion src/artemis/experiment_plans/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from artemis.external_interaction.callbacks.rotation.rotation_callback_collection import (
RotationCallbackCollection,
)
from artemis.external_interaction.ispyb.store_in_ispyb import Store3DGridscanInIspyb
from artemis.external_interaction.system_tests.conftest import TEST_RESULT_LARGE
from artemis.parameters.external_parameters import from_file as raw_params_from_file
from artemis.parameters.internal_parameters import InternalParameters
Expand Down Expand Up @@ -76,6 +77,31 @@ def detector_motion():
return i03.detector_motion(fake_with_ophyd_sim=True)


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


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


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


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


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


@pytest.fixture
def aperture_scatterguard():
return i03.aperture_scatterguard(
Expand Down Expand Up @@ -150,7 +176,7 @@ def mock_subscriptions(test_fgs_params):
subscriptions.zocalo_handler.zocalo_interactor.wait_for_result.return_value = (
TEST_RESULT_LARGE
)
subscriptions.ispyb_handler.ispyb = MagicMock()
subscriptions.ispyb_handler.ispyb = MagicMock(spec=Store3DGridscanInIspyb)
subscriptions.ispyb_handler.ispyb.begin_deposition = lambda: [[0, 0], 0, 0]

return subscriptions
Expand All @@ -160,6 +186,8 @@ def mock_subscriptions(test_fgs_params):
def mock_rotation_subscriptions(test_rotation_params):
with patch(
"artemis.external_interaction.callbacks.rotation.rotation_callback_collection.RotationNexusFileHandlerCallback"
), patch(
"artemis.external_interaction.callbacks.rotation.rotation_callback_collection.RotationISPyBHandlerCallback"
):
subscriptions = RotationCallbackCollection.from_params(test_rotation_params)
return subscriptions
50 changes: 49 additions & 1 deletion src/artemis/experiment_plans/tests/test_fast_grid_scan_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
from artemis.external_interaction.callbacks.logging_callback import (
VerbosePlanExecutionLoggingCallback,
)
from artemis.external_interaction.ispyb.store_in_ispyb import Store3DGridscanInIspyb
from artemis.external_interaction.system_tests.conftest import (
TEST_RESULT_LARGE,
TEST_RESULT_MEDIUM,
TEST_RESULT_SMALL,
)
from artemis.log import set_up_logging_handlers
from artemis.parameters import external_parameters
from artemis.parameters.constants import ISPYB_PLAN_NAME
from artemis.parameters.plan_specific.fgs_internal_params import FGSInternalParameters


Expand Down Expand Up @@ -91,7 +93,7 @@ def test_read_hardware_for_ispyb_updates_from_ophyd_devices(
fake_fgs_composite.flux.flux_reading.sim_put(flux_test_value)

test_ispyb_callback = FGSISPyBHandlerCallback(test_fgs_params)
test_ispyb_callback.ispyb = MagicMock()
test_ispyb_callback.ispyb = MagicMock(spec=Store3DGridscanInIspyb)
RE.subscribe(test_ispyb_callback)

def standalone_read_hardware_for_ispyb(und, syn, slits, attn, fl):
Expand Down Expand Up @@ -135,6 +137,22 @@ def test_results_adjusted_and_passed_to_move_xyz(
set_up_logging_handlers(logging_level="INFO", dev_mode=True)
RE.subscribe(VerbosePlanExecutionLoggingCallback())

mock_subscriptions.ispyb_handler.descriptor(
{"uid": "123abc", "name": ISPYB_PLAN_NAME}
)
mock_subscriptions.ispyb_handler.event(
{
"descriptor": "123abc",
"data": {
"undulator_gap": 0,
"synchrotron_machine_status_synchrotron_mode": 0,
"s4_slit_gaps_xgap": 0,
"s4_slit_gaps_ygap": 0,
"attenuator_actual_transmission": 0,
},
}
)

mock_subscriptions.zocalo_handler.zocalo_interactor.wait_for_result.return_value = (
TEST_RESULT_LARGE
)
Expand Down Expand Up @@ -214,6 +232,21 @@ def test_individual_plans_triggered_once_and_only_once_in_composite_run(
test_fgs_params: FGSInternalParameters,
RE: RunEngine,
):
mock_subscriptions.ispyb_handler.descriptor(
{"uid": "123abc", "name": ISPYB_PLAN_NAME}
)
mock_subscriptions.ispyb_handler.event(
{
"descriptor": "123abc",
"data": {
"undulator_gap": 0,
"synchrotron_machine_status_synchrotron_mode": 0,
"s4_slit_gaps_xgap": 0,
"s4_slit_gaps_ygap": 0,
"attenuator_actual_transmission": 0,
},
}
)
set_up_logging_handlers(logging_level="INFO", dev_mode=True)
RE.subscribe(VerbosePlanExecutionLoggingCallback())

Expand Down Expand Up @@ -248,6 +281,21 @@ def test_logging_within_plan(
test_fgs_params: FGSInternalParameters,
RE: RunEngine,
):
mock_subscriptions.ispyb_handler.descriptor(
{"uid": "123abc", "name": ISPYB_PLAN_NAME}
)
mock_subscriptions.ispyb_handler.event(
{
"descriptor": "123abc",
"data": {
"undulator_gap": 0,
"synchrotron_machine_status_synchrotron_mode": 0,
"s4_slit_gaps_xgap": 0,
"s4_slit_gaps_ygap": 0,
"attenuator_actual_transmission": 0,
},
}
)
set_up_logging_handlers(logging_level="INFO", dev_mode=True)
RE.subscribe(VerbosePlanExecutionLoggingCallback())

Expand Down
Loading

0 comments on commit 997ea2e

Please sign in to comment.