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 #855 from DiamondLightSource/834_separate_setup_fr…
Browse files Browse the repository at this point in the history
…om_rotation_scan

834 separate setup from rotation scan
  • Loading branch information
DominicOram authored Aug 9, 2023
2 parents 104351d + 6a8be31 commit acb726f
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 137 deletions.
63 changes: 63 additions & 0 deletions src/artemis/device_setup_plans/manipulate_sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from __future__ import annotations

import bluesky.plan_stubs as bps
from dodal.devices.attenuator import Attenuator
from dodal.devices.backlight import Backlight
from dodal.devices.detector_motion import DetectorMotion
from dodal.devices.smargon import Smargon

from artemis.log import LOGGER

LOWER_DETECTOR_SHUTTER_AFTER_SCAN = True


def setup_sample_environment(
detector_motion: DetectorMotion,
backlight: Backlight,
attenuator: Attenuator,
transmission_fraction: float,
detector_distance: float,
group="setup_senv",
):
"""Move out the backlight, retract the detector shutter, and set the attenuator to
transmission."""

yield from bps.abs_set(detector_motion.shutter, 1, group=group)
yield from bps.abs_set(detector_motion.z, detector_distance, group=group)
yield from bps.abs_set(backlight.pos, backlight.OUT, group=group)
yield from bps.abs_set(attenuator, transmission_fraction, group=group)


def cleanup_sample_environment(
detector_motion: DetectorMotion,
group="cleanup_senv",
):
"""Put the detector shutter back down"""

yield from bps.abs_set(
detector_motion.shutter,
int(not LOWER_DETECTOR_SHUTTER_AFTER_SCAN),
group=group,
)


def move_x_y_z(
smargon: Smargon,
x: float | None = None,
y: float | None = None,
z: float | None = None,
wait=False,
group="move_x_y_z",
):
"""Move the x, y, and z axes of the given smargon to the specified position. All
axes are optional."""

LOGGER.info(f"Moving smargon to x, y, z: {(x,y,z)}")
if x:
yield from bps.abs_set(smargon.x, x, group=group)
if y:
yield from bps.abs_set(smargon.y, y, group=group)
if z:
yield from bps.abs_set(smargon.z, z, group=group)
if wait:
yield from bps.wait(group)
4 changes: 4 additions & 0 deletions src/artemis/device_setup_plans/setup_zebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,7 @@ def set_zebra_shutter_to_manual(

if wait:
yield from bps.wait(group)


def make_trigger_safe(zebra: Zebra, group="make_zebra_safe", wait=False):
yield from bps.abs_set(zebra.inputs.soft_in_1, 0, wait=wait)
28 changes: 2 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.manipulate_sample import move_x_y_z
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,
Expand Down Expand Up @@ -119,28 +120,6 @@ def set_aperture():
yield from set_aperture()


@bpp.set_run_key_decorator("move_xyz")
@bpp.run_decorator(md={"subplan_name": "move_xyz"})
def move_xyz(
sample_motors,
xray_centre_motor_position: np.ndarray,
md={
"plan_name": "move_xyz",
},
):
"""Move 'sample motors' to a specific motor position (e.g. a position obtained
from gridscan processing results)"""
artemis.log.LOGGER.info(f"Moving Smargon x, y, z to: {xray_centre_motor_position}")
yield from bps.mv(
sample_motors.x,
xray_centre_motor_position[0],
sample_motors.y,
xray_centre_motor_position[1],
sample_motors.z,
xray_centre_motor_position[2],
)


def wait_for_fgs_valid(fgs_motors: FastGridScan, timeout=0.5):
artemis.log.LOGGER.info("Waiting for valid fgs_params")
SLEEP_PER_CHECK = 0.1
Expand Down Expand Up @@ -254,10 +233,7 @@ def run_gridscan_and_move(
# once we have the results, go to the appropriate position
artemis.log.LOGGER.info("Moving to centre of mass.")
with TRACER.start_span("move_to_result"):
yield from move_xyz(
fgs_composite.sample_motors,
xray_centre,
)
yield from move_x_y_z(fgs_composite.sample_motors, *xray_centre, wait=True)


def get_plan(
Expand Down
95 changes: 35 additions & 60 deletions src/artemis/experiment_plans/rotation_scan_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import bluesky.plan_stubs as bps
import bluesky.preprocessors as bpp
from dodal.beamlines import i03
from dodal.devices.attenuator import Attenuator
from dodal.devices.backlight import Backlight
from dodal.devices.detector import DetectorParams
from dodal.devices.detector_motion import DetectorMotion
from dodal.devices.eiger import DetectorParams, EigerDetector
Expand All @@ -15,10 +13,16 @@
from ophyd.device import Device
from ophyd.epics_motor import EpicsMotor

from artemis.device_setup_plans.manipulate_sample import (
cleanup_sample_environment,
move_x_y_z,
setup_sample_environment,
)
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,
make_trigger_safe,
setup_zebra_for_rotation,
)
from artemis.external_interaction.callbacks.rotation.rotation_callback_collection import (
Expand Down Expand Up @@ -56,46 +60,6 @@ def create_devices() -> dict[str, Device]:
ACCELERATION_MARGIN = 1.5


def setup_sample_environment(
detector_motion: DetectorMotion,
backlight: Backlight,
attenuator: Attenuator,
transmission: float,
group="setup_senv",
):
yield from bps.abs_set(detector_motion.shutter, 1, group=group)
yield from bps.abs_set(backlight.pos, backlight.OUT, group=group)
yield from bps.abs_set(attenuator, transmission, group=group)


def cleanup_sample_environment(
zebra: Zebra,
detector_motion: DetectorMotion,
group="cleanup_senv",
):
yield from bps.abs_set(zebra.inputs.soft_in_1, 0, group=group)
yield from bps.abs_set(detector_motion.shutter, 0, group=group)


def move_x_y_z(
smargon: Smargon,
x: float | None,
y: float | None,
z: float | None,
wait=False,
group="move_x_y_z",
):
if x:
LOGGER.info(f"x: {x}, y: {y}, z: {z}")
yield from bps.abs_set(smargon.x, x, group=group)
if y:
yield from bps.abs_set(smargon.y, y, group=group)
if z:
yield from bps.abs_set(smargon.z, z, group=group)
if wait:
yield from bps.wait(group)


def move_to_start_w_buffer(
axis: EpicsMotor,
start_angle: float,
Expand Down Expand Up @@ -157,13 +121,12 @@ def rotation_scan_plan(
params: RotationInternalParameters,
smargon: Smargon,
zebra: Zebra,
backlight: Backlight,
attenuator: Attenuator,
detector_motion: DetectorMotion,
**kwargs,
):
"""A plan to collect diffraction images from a sample continuously rotating about
a fixed axis - for now this axis is limited to omega."""
a fixed axis - for now this axis is limited to omega. Only does the scan itself, no
setup tasks."""

detector_params: DetectorParams = params.artemis_params.detector_params
expt_params: RotationScanParams = params.experiment_params

Expand All @@ -173,11 +136,6 @@ def rotation_scan_plan(
exposure_time_s = detector_params.exposure_time
shutter_time_s = expt_params.shutter_opening_time_s

LOGGER.info("moving to start x, y, z if necessary")
yield from move_x_y_z(
smargon, expt_params.x, expt_params.y, expt_params.z, wait=True
)

speed_for_rotation_deg_s = image_width_deg / exposure_time_s
LOGGER.info(f"calculated speed: {speed_for_rotation_deg_s} deg/s")

Expand All @@ -197,10 +155,6 @@ def rotation_scan_plan(
f" for {shutter_time_s} s at {speed_for_rotation_deg_s} deg/s"
)

transmission = params.artemis_params.ispyb_params.transmission_fraction
yield from setup_sample_environment(
detector_motion, backlight, attenuator, transmission
)
LOGGER.info(f"moving omega to beginning, start_angle={start_angle_deg}")
yield from move_to_start_w_buffer(
smargon.omega, start_angle_deg, acceleration_offset
Expand All @@ -223,6 +177,7 @@ def rotation_scan_plan(
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_x_y_z")
yield from bps.wait("move_to_start")
yield from bps.wait("setup_zebra")

Expand Down Expand Up @@ -258,9 +213,12 @@ def rotation_scan_plan(
def cleanup_plan(
zebra: Zebra, smargon: Smargon, detector_motion: DetectorMotion, **kwargs
):
yield from cleanup_sample_environment(zebra, detector_motion)
yield from bps.abs_set(smargon.omega.velocity, DEFAULT_MAX_VELOCITY)
yield from bpp.finalize_wrapper(disarm_zebra(zebra), bps.wait("cleanup_senv"))
yield from cleanup_sample_environment(detector_motion, group="cleanup")
yield from bps.abs_set(
smargon.omega.velocity, DEFAULT_MAX_VELOCITY, group="cleanup"
)
yield from make_trigger_safe(zebra, group="cleanup")
yield from bpp.finalize_wrapper(disarm_zebra(zebra), bps.wait("cleanup"))


def get_plan(parameters: RotationInternalParameters):
Expand All @@ -283,10 +241,27 @@ def rotation_scan_plan_with_stage_and_cleanup(

@bpp.stage_decorator([eiger])
@bpp.finalize_decorator(lambda: cleanup_plan(**devices))
def rotation_with_cleanup_and_stage(params):
LOGGER.info("setting up and staging eiger...")
def rotation_with_cleanup_and_stage(params: RotationInternalParameters):
LOGGER.info("setting up sample environment...")
yield from setup_sample_environment(
devices["detector_motion"],
devices["backlight"],
devices["attenuator"],
params.artemis_params.ispyb_params.transmission_fraction,
params.artemis_params.detector_params.detector_distance,
)
LOGGER.info("moving to position (if specified)")
yield from move_x_y_z(
devices["smargon"],
params.experiment_params.x,
params.experiment_params.y,
params.experiment_params.z,
group="move_x_y_z",
)

yield from rotation_scan_plan(params, **devices)

LOGGER.info("setting up and staging eiger...")
yield from rotation_with_cleanup_and_stage(params)

yield from rotation_scan_plan_with_stage_and_cleanup(parameters)
Loading

0 comments on commit acb726f

Please sign in to comment.