Skip to content
Merged
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
1 change: 0 additions & 1 deletion src/i19_bluesky/parameters/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class DetectorType(StrEnum):


class VisitParameters(BaseModel):
hutch: HutchName
visit: Path
dataset: str
filename_prefix: str
Expand Down
8 changes: 8 additions & 0 deletions src/i19_bluesky/parameters/devices_composites.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import pydantic
from dodal.devices.beamlines.i19.access_controlled.energy_device import (
AccessControlledEnergyComposite,
)
from dodal.devices.beamlines.i19.access_controlled.shutter import (
AccessControlledShutter,
)
from dodal.devices.beamlines.i19.backlight import BacklightPosition
from dodal.devices.beamlines.i19.diffractometer import (
FourCircleDiffractometer,
Expand All @@ -20,6 +26,8 @@ class SerialCollectionEh2PandaComposite:
panda: HDFPanda
eiger: EigerDetector
serial_stages: XYZPhiStage
shutter: AccessControlledShutter
energy_device: AccessControlledEnergyComposite


@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
Expand Down
2 changes: 2 additions & 0 deletions src/i19_bluesky/parameters/serial_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from i19_bluesky.parameters.components import (
DetectorType,
HutchName,
PandaRotationParams,
RotationAxis,
VisitParameters,
Expand Down Expand Up @@ -57,6 +58,7 @@ def split_wells_per_run(self) -> list[dict]:
class SerialExperimentEh2(SerialExperiment):
aperture_request: PinColRequest
detector_type: DetectorType
hutch: HutchName = HutchName.EH2

@property
def zebra_rotation_params(self) -> ZebraRotationParams:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def write_eiger_params(
energy: float,
wavelength: float,
eiger: EigerDetector,
wait: bool,
wait: bool = True,
group: str = "eiger_metadata",
):
beam_centre = calculate_beam_centre_from_lut(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
from i19_bluesky.parameters.serial_parameters import SerialExperimentEh2
from i19_bluesky.serial.device_setup_plans.diffractometer_plans import (
move_sample_stage_back,
setup_sample_stage,
)
from i19_bluesky.serial.example_zebra_plans.zebra_collection_setup_plan import (
setup_zebra_for_collection,
)
from i19_bluesky.serial.run_panda_plans.panda_serial_collection import (
setup_sample_stage,
)

RAMP = 0.5

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from i19_bluesky.log import LOGGER
from i19_bluesky.parameters.components import PandaRotationParams
from i19_bluesky.serial.panda_setup_plans.panda_stubs import (
from i19_bluesky.serial.panda_plans.panda_stubs import (
DeviceSettingsConstants,
arm_panda,
generate_panda_seq_table,
Expand Down
44 changes: 3 additions & 41 deletions src/i19_bluesky/serial/run_panda_plans/panda_serial_collection.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import bluesky.plan_stubs as bps
from bluesky.utils import MsgGenerator
from dodal.devices.beamlines.i19.diffractometer import (
FourCircleDiffractometer,
)
from dodal.devices.motors import XYZPhiStage
from ophyd_async.fastcs.eiger import EigerDetector
from ophyd_async.fastcs.panda import HDFPanda

from i19_bluesky.log import LOGGER
from i19_bluesky.parameters.devices_composites import SerialCollectionEh2PandaComposite
from i19_bluesky.parameters.serial_parameters import SerialExperimentEh2
from i19_bluesky.serial.device_setup_plans.diffractometer_plans import (
move_sample_stage_back,
move_stage_x_and_z,
setup_sample_stage,
)
from i19_bluesky.serial.panda_setup_plans.panda_setup_plans import (
reset_panda,
from i19_bluesky.serial.panda_plans.panda_setup_plans import (
setup_panda_for_rotation,
)
from i19_bluesky.serial.panda_setup_plans.panda_stubs import arm_panda, disarm_panda
from i19_bluesky.serial.panda_plans.panda_stubs import arm_panda


def trigger_panda(
def trigger_panda_collection(
parameters: SerialExperimentEh2,
devices: SerialCollectionEh2PandaComposite,
) -> MsgGenerator:
Expand All @@ -41,10 +32,6 @@ def trigger_panda(
panda (HDFPanda): The fastcs PandA ophyd device.
eiger (EigerDetector): The eiger detector device
"""
yield from setup_sample_stage(
parameters.panda_rotation_params,
devices.serial_stages,
)
yield from setup_panda_for_rotation(
parameters.panda_rotation_params,
devices.panda,
Expand Down Expand Up @@ -76,28 +63,3 @@ def trigger_panda(
parameters.panda_rotation_params.scan_start_deg,
wait=True,
)


def end_run(
rot_axis_start: float,
panda: HDFPanda,
eiger: EigerDetector,
serial_stages: XYZPhiStage,
):
LOGGER.info("Disarm eiger")
yield from bps.trigger(eiger.detector.disarm)
LOGGER.info("Disarm panda")
yield from disarm_panda(panda)
yield from reset_panda(panda)
yield from move_sample_stage_back(serial_stages, rot_axis_start)


def run_on_collection_abort(
panda: HDFPanda,
eiger: EigerDetector,
diffractometer: FourCircleDiffractometer,
) -> MsgGenerator:
LOGGER.warning("ABORT")
yield from bps.abs_set(diffractometer.phi.motor_stop, 1, wait=True)
yield from bps.trigger(eiger.detector.disarm)
yield from disarm_panda(panda)
83 changes: 56 additions & 27 deletions src/i19_bluesky/serial/run_panda_plans/run_serial_with_panda.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,70 @@
import bluesky.plan_stubs as bps
import bluesky.preprocessors as bpp
from bluesky.utils import MsgGenerator
from dodal.common import inject
from dodal.devices.beamlines.i19.access_controlled.shutter import (
AccessControlledShutter,
)
from dodal.devices.beamlines.i19.diffractometer import (
FourCircleDiffractometer,
)
from dodal.devices.motors import XYZPhiStage
from ophyd_async.fastcs.eiger import EigerDetector
from ophyd_async.fastcs.panda import HDFPanda

from i19_bluesky.log import LOGGER
from i19_bluesky.parameters.devices_composites import SerialCollectionEh2PandaComposite
from i19_bluesky.parameters.serial_parameters import SerialExperimentEh2
from i19_bluesky.plans.optics_hutch_control_plans import close_experiment_shutter
from i19_bluesky.serial.device_setup_plans.diffractometer_plans import (
move_sample_stage_back,
)
from i19_bluesky.serial.panda_plans.panda_setup_plans import reset_panda
from i19_bluesky.serial.panda_plans.panda_stubs import disarm_panda
from i19_bluesky.serial.run_panda_plans.panda_serial_collection import (
end_run,
run_on_collection_abort,
trigger_panda,
trigger_panda_collection,
)
from i19_bluesky.serial.setup_beamline_plans.setup_beamline_pre_collection import (
setup_beamline_before_collection,
from i19_bluesky.serial.setup_beamline_plans.setup_beamline import (
setup_eh2_serial_collection,
)


def setup_then_trigger_panda(
def main_collection_plan(
parameters: SerialExperimentEh2,
devices: SerialCollectionEh2PandaComposite,
) -> MsgGenerator:
"""Run primary setup processes then trigger PandA to collect data from experiment.
Has contingencies to abort if any stage produces errors, before moving the
diffractometer to its starting position. Designed to be called with BlueAPI.

Args:
parameters (SerialExperimentEh2): SerialExperimentEh2 object
devices (SerialCollectionEh2PandaComposite): SerialCollectionEh2PandaComposite
object
"""

yield from setup_beamline_before_collection(
parameters.aperture_request,
parameters.detector_distance_mm,
parameters.two_theta_deg,
devices.backlight,
devices.pincol,
devices.diffractometer,
)
yield from trigger_panda(parameters, devices)
"""Run a small rotative serial crystallography collection using the PandA to trigger
the detector."""
yield from setup_eh2_serial_collection(parameters, devices)
yield from trigger_panda_collection(parameters, devices)


def run_on_collection_end(
rot_axis_start: float,
panda: HDFPanda,
eiger: EigerDetector,
serial_stages: XYZPhiStage,
shutter: AccessControlledShutter,
):
LOGGER.info("Disarm eiger")
yield from bps.trigger(eiger.detector.disarm)
LOGGER.info("Disarm panda")
yield from disarm_panda(panda)
yield from reset_panda(panda)
yield from move_sample_stage_back(serial_stages, rot_axis_start)
LOGGER.info("Close experiment shutter")
yield from close_experiment_shutter(shutter)


def run_on_collection_abort(
panda: HDFPanda,
eiger: EigerDetector,
diffractometer: FourCircleDiffractometer,
) -> MsgGenerator:
LOGGER.warning("ABORT")
yield from bps.abs_set(diffractometer.phi.motor_stop, 1, wait=True)
yield from bps.trigger(eiger.detector.disarm)
yield from disarm_panda(panda)


@bpp.run_decorator()
Expand All @@ -45,18 +73,19 @@ def run_serial_with_panda(
devices: SerialCollectionEh2PandaComposite = inject(),
) -> MsgGenerator:
yield from bpp.contingency_wrapper(
setup_then_trigger_panda(parameters, devices),
main_collection_plan(parameters, devices),
except_plan=lambda: (
yield from run_on_collection_abort(
devices.panda, devices.eiger, devices.diffractometer
)
),
final_plan=lambda: (
yield from end_run(
yield from run_on_collection_end(
parameters.rot_axis_start,
devices.panda,
devices.eiger,
devices.serial_stages,
devices.shutter,
)
),
auto_raise=False,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import bluesky.plan_stubs as bps
from bluesky.utils import MsgGenerator
from dodal.devices.beamlines.i19.backlight import BacklightPosition
from dodal.devices.beamlines.i19.diffractometer import (
Expand All @@ -11,12 +12,45 @@
from i19_bluesky.eh2.backlight_plan import move_backlight_out
from i19_bluesky.eh2.pincol_control_plans import move_pin_col_to_requested_in_position
from i19_bluesky.log import LOGGER
from i19_bluesky.parameters.devices_composites import SerialCollectionEh2PandaComposite
from i19_bluesky.parameters.serial_parameters import SerialExperimentEh2
from i19_bluesky.plans.optics_hutch_control_plans import open_experiment_shutter
from i19_bluesky.serial.device_setup_plans.diffractometer_plans import (
move_detector_stage,
setup_sample_stage,
)
from i19_bluesky.serial.device_setup_plans.eiger_metadata import write_eiger_params


def setup_beamline_before_collection(
def setup_eh2_serial_collection(
parameters: SerialExperimentEh2,
devices: SerialCollectionEh2PandaComposite,
) -> MsgGenerator:
# Open shutter
yield from open_experiment_shutter(devices.shutter)
# Set up eiger - TO BE ADDED - IN SEPARATE BRANCH
# Read energy and wavelength from dcm to then set up eiger
energ_in_kev = yield from bps.rd(devices.energy_device.energy_in_kev)
wavelength_in_a = yield from bps.rd(devices.energy_device.wavelength_in_a)
yield from write_eiger_params(
parameters, energ_in_kev, wavelength_in_a, devices.eiger
)
# Set up beamline for collection
yield from setup_beamline_for_collection(
parameters.aperture_request,
parameters.detector_distance_mm,
parameters.two_theta_deg,
devices.backlight,
devices.pincol,
devices.diffractometer,
)
# Set up sample stage
yield from setup_sample_stage(
parameters.panda_rotation_params, devices.serial_stages
)


def setup_beamline_for_collection(
aperture_request: PinColRequest,
detector_distance_mm: float,
two_theta_deg: float,
Expand Down
4 changes: 1 addition & 3 deletions tests/unit_tests/parameters/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import pytest

from i19_bluesky.parameters.components import (
HutchName,
PandaRotationParams,
RotationParams,
VisitParameters,
Expand All @@ -24,13 +23,12 @@ def test_validate_visit_parameters_model(hutch):

def test_visit_parameters():
model = {
"hutch": HutchName.EH2,
"visit": "/tmp/foo",
"dataset": "bar",
"filename_prefix": "some_file",
}

params = VisitParameters(**model)
params = VisitParameters(**model) # type: ignore

assert isinstance(params.visit, Path)
assert params.collection_directory == Path("/tmp/foo/bar")
Expand Down
Loading
Loading