diff --git a/pyproject.toml b/pyproject.toml index f22c5df38b..1fbac26e46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ dependencies = [ "ophyd >= 1.10.5", "ophyd-async >= 0.14.0", "bluesky >= 1.14.6", - "dls-dodal @ git+https://github.com/DiamondLightSource/dodal.git@main", + "dls-dodal @ git+https://github.com/DiamondLightSource/dodal.git@use_fastcs_eiger_for_xrc", ] diff --git a/src/mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py b/src/mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py index 465ae79ad0..f182307fd3 100644 --- a/src/mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py +++ b/src/mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py @@ -34,6 +34,7 @@ from dodal.plans.preprocessors.verify_undulator_gap import ( verify_undulator_gap_before_run_decorator, ) +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from pydantic import BaseModel from mx_bluesky.beamlines.i04.external_interaction.config_server import ( @@ -136,6 +137,7 @@ def i04_default_grid_detect_and_xray_centre( smargon: Smargon = inject("smargon"), detector_motion: DetectorMotion = inject("detector_motion"), transfocator: Transfocator = inject("transfocator"), + fastcs_eiger: FastCSEiger = inject("fastcs_eiger"), oav_config: str = OavConstants.OAV_CONFIG_JSON, udc: bool = False, ) -> MsgGenerator: @@ -152,27 +154,28 @@ def i04_default_grid_detect_and_xray_centre( """ composite = GridDetectThenXRayCentreComposite( - eiger, - synchrotron, - zocalo, - smargon, - aperture_scatterguard, - attenuator, - backlight, - beamstop, - beamsize, - dcm, - detector_motion, - zebra_fast_grid_scan, - flux, - oav, - pin_tip_detection, - s4_slit_gaps, - undulator, - xbpm_feedback, - zebra, - robot, - sample_shutter, + eiger=eiger, + synchrotron=synchrotron, + zocalo=zocalo, + smargon=smargon, + aperture_scatterguard=aperture_scatterguard, + attenuator=attenuator, + backlight=backlight, + beamstop=beamstop, + beamsize=beamsize, + dcm=dcm, + detector_motion=detector_motion, + zebra_fast_grid_scan=zebra_fast_grid_scan, + flux=flux, + oav=oav, + pin_tip_detection=pin_tip_detection, + s4_slit_gaps=s4_slit_gaps, + undulator=undulator, + xbpm_feedback=xbpm_feedback, + zebra=zebra, + robot=robot, + sample_shutter=sample_shutter, + fastcs_eiger=fastcs_eiger, ) initial_beamsize = yield from bps.rd(transfocator.current_vertical_size_rbv) @@ -214,6 +217,7 @@ def grid_detect_then_xray_centre_with_callbacks(): parameters=grid_common_params, xrc_params_type=SpecifiedThreeDGridScan, construct_beamline_specific=construct_i04_specific_features, + use_fastcs_eiger=False, oav_config=oav_config, ) @@ -271,6 +275,7 @@ def create_gridscan_callbacks() -> tuple[ def construct_i04_specific_features( xrc_composite: GridDetectThenXRayCentreComposite, xrc_parameters: SpecifiedThreeDGridScan, + _, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ ) -> BeamlineSpecificFGSFeatures: """ Get all the information needed to do the i04 XRC flyscan. diff --git a/src/mx_bluesky/common/device_setup_plans/utils.py b/src/mx_bluesky/common/device_setup_plans/utils.py index 04c3c8eeaf..36f3e3db3e 100644 --- a/src/mx_bluesky/common/device_setup_plans/utils.py +++ b/src/mx_bluesky/common/device_setup_plans/utils.py @@ -6,6 +6,7 @@ from dodal.devices.detector.detector_motion import DetectorMotion, ShutterState from dodal.devices.eiger import EigerDetector from dodal.devices.mx_phase1.beamstop import Beamstop, BeamstopPositions +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from mx_bluesky.common.device_setup_plans.position_detector import ( set_detector_z_position, @@ -15,7 +16,7 @@ def start_preparing_data_collection_then_do_plan( beamstop: Beamstop, - eiger: EigerDetector, + eiger: EigerDetector | FastCSEiger, detector_motion: DetectorMotion, detector_distance_mm: float | None, plan_to_run: Generator[Msg, None, None], @@ -32,7 +33,8 @@ def start_preparing_data_collection_then_do_plan( """ def wrapped_plan(): - yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855) + if isinstance(eiger, EigerDetector): + yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855) yield from bps.abs_set( beamstop.selected_pos, BeamstopPositions.DATA_COLLECTION, group=group ) diff --git a/src/mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py b/src/mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py index 6a84fd0383..1868623c57 100644 --- a/src/mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py +++ b/src/mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py @@ -20,6 +20,13 @@ XrcResult, get_full_processing_results, ) +from dodal.plans.configure_arm_trigger_and_disarm_detector import ( + configure_and_arm_detector, +) +from ophyd_async.core import ( + DetectorTrigger, + TriggerInfo, +) from mx_bluesky.common.experiment_plans.inner_plans.do_fgs import ( ZOCALO_STAGE_GROUP, @@ -58,7 +65,11 @@ class BeamlineSpecificFGSFeatures: get_xrc_results_from_zocalo: bool -def generic_tidy(xrc_composite: FlyScanEssentialDevices, wait=True) -> MsgGenerator: +def generic_tidy( + xrc_composite: FlyScanEssentialDevices, + use_fastcs_eiger: bool, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ + wait=True, +) -> MsgGenerator: """Tidy Zocalo and turn off Eiger dev/shm. Ran after the beamline-specific tidy plan""" LOGGER.info("Tidying up Zocalo") @@ -70,7 +81,11 @@ def generic_tidy(xrc_composite: FlyScanEssentialDevices, wait=True) -> MsgGenera LOGGER.info("Turning off Eiger dev/shm streaming") # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855) yield from bps.abs_set( - xrc_composite.eiger.odin.fan.dev_shm_enable, # type: ignore + ( + xrc_composite.eiger.odin.fan.dev_shm_enable # old eiger + if not use_fastcs_eiger + else xrc_composite.fastcs_eiger.odin.fan_dev_shm_enable # fastcs_eiger, requires https://github.com/bluesky/ophyd-async/pull/1127 + ), 0, group=group, ) @@ -135,6 +150,7 @@ def common_flyscan_xray_centre( composite: FlyScanEssentialDevices, parameters: SpecifiedThreeDGridScan, beamline_specific: BeamlineSpecificFGSFeatures, + use_fastcs_eiger: bool, # Needed until fastcs_eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ ) -> MsgGenerator: """Main entry point of the MX-Bluesky x-ray centering flyscan @@ -159,7 +175,7 @@ def common_flyscan_xray_centre( def _overall_tidy(): yield from beamline_specific.tidy_plan() - yield from generic_tidy(composite) + yield from generic_tidy(composite, use_fastcs_eiger=use_fastcs_eiger) def _decorated_flyscan(): @bpp.set_run_key_decorator(PlanNameConstants.GRIDSCAN_OUTER) @@ -184,7 +200,12 @@ def run_gridscan_and_tidy( yield from bps.stage( fgs_composite.zocalo, group=ZOCALO_STAGE_GROUP ) # connect to zocalo and make sure the queue is clear - yield from run_gridscan(fgs_composite, params, beamline_specific) + yield from run_gridscan( + fgs_composite, + params, + beamline_specific, + use_fastcs_eiger=use_fastcs_eiger, + ) LOGGER.info("Grid scan finished") @@ -193,7 +214,8 @@ def run_gridscan_and_tidy( yield from run_gridscan_and_tidy(composite, parameters, beamline_specific) - composite.eiger.set_detector_parameters(parameters.detector_params) + if not use_fastcs_eiger: + composite.eiger.set_detector_parameters(parameters.detector_params) yield from _decorated_flyscan() @@ -262,6 +284,7 @@ def run_gridscan( fgs_composite: FlyScanEssentialDevices, parameters: SpecifiedThreeDGridScan, beamline_specific: BeamlineSpecificFGSFeatures, + use_fastcs_eiger: bool, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ ): # Currently gridscan only works for omega 0, see https://github.com/DiamondLightSource/mx-bluesky/issues/410 with TRACER.start_span("moving_omega_to_0"): @@ -282,13 +305,28 @@ def run_gridscan( else: raise e + if use_fastcs_eiger: + LOGGER.info("Preparing fastCS eiger") + yield from configure_and_arm_detector( + eiger=fgs_composite.fastcs_eiger, + detector_params=parameters.detector_params, + trigger_info=TriggerInfo( + number_of_events=parameters.detector_params.num_images_per_trigger, + trigger=DetectorTrigger.EDGE_TRIGGER, + deadtime=0.0001, + ), + group=PlanGroupCheckpointConstants.GRID_READY_FOR_DC, + ) LOGGER.info("Waiting for arming to finish") yield from bps.wait(PlanGroupCheckpointConstants.GRID_READY_FOR_DC) - yield from bps.stage(fgs_composite.eiger, wait=True) + if use_fastcs_eiger: + yield from bps.kickoff(fgs_composite.fastcs_eiger, wait=True) # fastcs eiger + else: + yield from bps.stage(fgs_composite.eiger, wait=True) # old eiger yield from kickoff_and_complete_gridscan( beamline_specific.fgs_motors, - fgs_composite.eiger, + fgs_composite.fastcs_eiger if use_fastcs_eiger else fgs_composite.eiger, fgs_composite.synchrotron, [parameters.scan_points_first_grid, parameters.scan_points_second_grid], plan_during_collection=beamline_specific.read_during_collection_plan, diff --git a/src/mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py b/src/mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py index e1b53f8c83..3aef86e5af 100644 --- a/src/mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py +++ b/src/mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py @@ -8,7 +8,6 @@ from bluesky.preprocessors import subs_decorator from bluesky.utils import MsgGenerator from dodal.devices.backlight import InOut -from dodal.devices.eiger import EigerDetector from dodal.devices.oav.oav_parameters import OAVParameters from mx_bluesky.common.device_setup_plans.manipulate_sample import ( @@ -63,16 +62,18 @@ def grid_detect_then_xray_centre( parameters: GridCommon, xrc_params_type: type[SpecifiedThreeDGridScan], construct_beamline_specific: ConstructBeamlineSpecificFeatures, + use_fastcs_eiger: bool, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ oav_config: str = OavConstants.OAV_CONFIG_JSON, ) -> MsgGenerator: """ A plan which combines the collection of snapshots from the OAV and the determination of the grid dimensions to use for the following grid scan. """ - - eiger: EigerDetector = composite.eiger - - eiger.set_detector_parameters(parameters.detector_params) + if use_fastcs_eiger: + eiger = composite.fastcs_eiger + else: + eiger = composite.eiger + eiger.set_detector_parameters(parameters.detector_params) oav_params = OAVParameters("xrayCentring", oav_config) @@ -87,6 +88,7 @@ def plan_to_perform(): oav_params, xrc_params_type, construct_beamline_specific, + use_fastcs_eiger=use_fastcs_eiger, ), parameters, ) @@ -118,6 +120,7 @@ def detect_grid_and_do_gridscan( oav_params: OAVParameters, xrc_params_type: type[SpecifiedThreeDGridScan], construct_beamline_specific: ConstructBeamlineSpecificFeatures, + use_fastcs_eiger: bool, ): snapshot_template = f"{parameters.detector_params.prefix}_{parameters.detector_params.run_number}_{{angle}}" @@ -181,9 +184,13 @@ def run_grid_detection_plan( xrc_params = create_parameters_for_flyscan_xray_centre( parameters, grid_params_callback.get_grid_parameters(), xrc_params_type ) - beamline_specific = construct_beamline_specific(composite, xrc_params) + beamline_specific = construct_beamline_specific( + composite, xrc_params, use_fastcs_eiger + ) - yield from common_flyscan_xray_centre(composite, xrc_params, beamline_specific) + yield from common_flyscan_xray_centre( + composite, xrc_params, beamline_specific, use_fastcs_eiger + ) class ConstructBeamlineSpecificFeatures( @@ -193,6 +200,7 @@ def __call__( self, xrc_composite: TFlyScanEssentialDevices, xrc_parameters: TSpecifiedThreeDGridScan, + use_fastcs_eiger: bool, ) -> BeamlineSpecificFGSFeatures: ... diff --git a/src/mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py b/src/mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py index ab06f04079..5ae1935df4 100644 --- a/src/mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py +++ b/src/mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py @@ -12,6 +12,7 @@ ) from dodal.log import LOGGER from dodal.plan_stubs.check_topup import check_topup_and_wait_if_necessary +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from scanspec.core import AxesPoints, Axis from mx_bluesky.common.experiment_plans.inner_plans.read_hardware import ( @@ -28,12 +29,16 @@ def _wait_for_zocalo_to_stage_then_do_fgs( grid_scan_device: FastGridScanCommon, - detector: EigerDetector, + detector: EigerDetector | FastCSEiger, synchrotron: Synchrotron, during_collection_plan: Callable[[], MsgGenerator] | None = None, ): expected_images = yield from bps.rd(grid_scan_device.expected_images) - exposure_sec_per_image = yield from bps.rd(detector.cam.acquire_time) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855) + exposure_sec_per_image = yield from ( + bps.rd(detector.cam.acquire_time) + if isinstance(detector, EigerDetector) # old eiger + else bps.rd(detector.drv.detector.frame_time) # fastcs eiger + ) LOGGER.info("waiting for topup if necessary...") yield from check_topup_and_wait_if_necessary( synchrotron, @@ -66,7 +71,8 @@ def _wait_for_zocalo_to_stage_then_do_fgs( def kickoff_and_complete_gridscan( gridscan: FastGridScanCommon, - detector: EigerDetector, # Once Eiger inherits from StandardDetector, use that type instead + detector: EigerDetector + | FastCSEiger, # use StandardDetector once old eiger not in use synchrotron: Synchrotron, scan_points: list[AxesPoints[Axis]], plan_during_collection: Callable[[], MsgGenerator] | None = None, @@ -103,7 +109,11 @@ def kickoff_and_complete_gridscan( ) @bpp.contingency_decorator( except_plan=lambda e: (yield from bps.stop(detector)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855) - else_plan=lambda: (yield from bps.unstage(detector, wait=True)), + else_plan=lambda: ( + yield from bps.unstage(detector, wait=True) # old eiger + if isinstance(detector, EigerDetector) + else bps.complete(detector, wait=True) # fastcs eiger + ), ) def _decorated_do_fgs(): yield from _wait_for_zocalo_to_stage_then_do_fgs( diff --git a/src/mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py b/src/mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py index 6e1f02d857..ef4965ff28 100644 --- a/src/mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py +++ b/src/mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py @@ -12,6 +12,7 @@ from dodal.devices.smargon import Smargon from dodal.devices.synchrotron import Synchrotron from dodal.devices.undulator import UndulatorInKeV +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from mx_bluesky.common.parameters.constants import ( DocDescriptorNames, @@ -30,12 +31,16 @@ def read_hardware_plan( yield from bps.save() -def read_hardware_for_zocalo(detector: EigerDetector): +def read_hardware_for_zocalo(detector: EigerDetector | FastCSEiger): """ " If the RunEngine is subscribed to the ZocaloCallback, this plan will also trigger zocalo. """ yield from read_hardware_plan( - [detector.odin.file_writer.id], # type: ignore + [ + detector.odin.file_writer.id # old eiger + if isinstance(detector, EigerDetector) + else detector.odin.id # fastcs eiger + ], DocDescriptorNames.ZOCALO_HW_READ, ) diff --git a/src/mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py b/src/mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py index fa578f49a0..9f67779b0c 100644 --- a/src/mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py +++ b/src/mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py @@ -75,7 +75,10 @@ def descriptor(self, doc: EventDescriptor): def event(self, doc: Event) -> Event: event_descriptor = self.descriptors[doc["descriptor"]] if event_descriptor.get("name") == DocDescriptorNames.ZOCALO_HW_READ: - filename = doc["data"]["eiger_odin_file_writer_id"] + filename = ( + doc["data"].get("eiger_odin_file_writer_id") + or doc["data"]["fastcs_eiger-odin-id"] + ) for start_info in self.zocalo_info: start_info.filename = filename self.zocalo_interactor.run_start(start_info) diff --git a/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py b/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py index 1a065c48d7..b68a42cb86 100644 --- a/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py +++ b/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py @@ -14,7 +14,7 @@ from mx_bluesky.common.parameters.gridscan import ( SpecifiedThreeDGridScan, ) -from mx_bluesky.common.utils.log import NEXUS_LOGGER +from mx_bluesky.common.utils.log import LOGGER, NEXUS_LOGGER if TYPE_CHECKING: from event_model.documents import Event, EventDescriptor, RunStart @@ -93,9 +93,11 @@ def activity_gated_event(self, doc: Event) -> Event | None: data["flux-flux_reading"], data["attenuator-actual_transmission"], ) - vds_data_type = vds_type_based_on_bit_depth( - doc["data"]["eiger_bit_depth"] - ) + LOGGER.info(f"doc = {doc}") + bit_depth = doc["data"].get("fastcs_eiger-drv-detector-bit_depth_image") + if bit_depth is None: + bit_depth = doc["data"]["eiger_bit_depth"] + vds_data_type = vds_type_based_on_bit_depth(bit_depth) nexus_writer.create_nexus_file(vds_data_type) NEXUS_LOGGER.info(f"Nexus file created at {nexus_writer.data_filename}") diff --git a/src/mx_bluesky/common/parameters/device_composites.py b/src/mx_bluesky/common/parameters/device_composites.py index a2d96d1cc0..995a59f79c 100644 --- a/src/mx_bluesky/common/parameters/device_composites.py +++ b/src/mx_bluesky/common/parameters/device_composites.py @@ -24,6 +24,7 @@ from dodal.devices.zebra.zebra import Zebra from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter from dodal.devices.zocalo import ZocaloResults +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True}) @@ -32,6 +33,7 @@ class FlyScanEssentialDevices: synchrotron: Synchrotron zocalo: ZocaloResults smargon: Smargon + fastcs_eiger: FastCSEiger @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True}) diff --git a/src/mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py index e302c4a940..39820d895e 100755 --- a/src/mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py @@ -42,6 +42,7 @@ class SmargonSpeedError(Exception): def construct_hyperion_specific_features( xrc_composite: HyperionFlyScanXRayCentreComposite, xrc_parameters: HyperionSpecifiedThreeDGridScan, + use_fastcs_eiger: bool, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ ): """ Get all the information needed to do the Hyperion-specific parts of the XRC flyscan. @@ -59,10 +60,13 @@ def construct_hyperion_specific_features( xrc_composite.attenuator.actual_transmission, xrc_composite.flux.flux_reading, xrc_composite.dcm.energy_in_keV, - xrc_composite.eiger.bit_depth, xrc_composite.beamsize, xrc_composite.eiger.cam.roi_mode, xrc_composite.eiger.ispyb_detector_id, + xrc_composite.eiger.bit_depth, + xrc_composite.fastcs_eiger.drv.detector.bit_depth_image # fastcs eiger + if use_fastcs_eiger + else xrc_composite.eiger.bit_depth, # old eiger ] setup_trigger_plan: Callable[..., MsgGenerator] diff --git a/src/mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py index 01865f6981..b3b07ad053 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py @@ -37,6 +37,7 @@ def create_devices( def hyperion_grid_detect_then_xray_centre( composite: HyperionGridDetectThenXRayCentreComposite, parameters: GridScanWithEdgeDetect, + use_fastcs_eiger: bool = False, # Needed until fastcs eiger is always used, see https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ oav_config: str = OavConstants.OAV_CONFIG_JSON, ) -> MsgGenerator: """ @@ -54,6 +55,7 @@ def plan_to_perform(): parameters=parameters, xrc_params_type=HyperionSpecifiedThreeDGridScan, construct_beamline_specific=construct_hyperion_specific_features, + use_fastcs_eiger=use_fastcs_eiger, oav_config=oav_config, ) diff --git a/src/mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py b/src/mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py index 914d715027..ecbbaabce6 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py @@ -89,7 +89,7 @@ def plan_with_callback_subs(): try: yield from subs_wrapper( robot_load_then_xray_centre( - composite, parameters.robot_load_then_centre, oav_config_file + composite, parameters.robot_load_then_centre, True, oav_config_file ), flyscan_event_handler, ) diff --git a/src/mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py index 864f56ef9e..e1e445d5ba 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py @@ -1,11 +1,14 @@ from __future__ import annotations import json +from pathlib import Path +import bluesky.plan_stubs as bps import bluesky.preprocessors as bpp from blueapi.core import BlueskyContext from bluesky.utils import MsgGenerator -from dodal.devices.eiger import EigerDetector +from dodal.beamlines import i03 +from dodal.common.udc_directory_provider import PandASubpathProvider from dodal.devices.oav.oav_parameters import OAVParameters from mx_bluesky.common.device_setup_plans.manipulate_sample import move_phi_chi_omega @@ -72,6 +75,7 @@ def create_parameters_for_grid_detection( def pin_centre_then_flyscan_plan( composite: HyperionGridDetectThenXRayCentreComposite, parameters: PinTipCentreThenXrayCentre, + use_fastcs_eiger: bool, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): """Plan that performs a pin tip centre followed by a flyscan to determine the centres of interest""" @@ -82,6 +86,12 @@ def pin_centre_then_flyscan_plan( pin_tip_detection=composite.pin_tip_detection, ) + path_provider = i03.path_provider() + assert isinstance(path_provider, PandASubpathProvider) + yield from bps.wait_for( + [lambda: path_provider.update(directory=Path(parameters.storage_directory))] + ) + def _pin_centre_then_flyscan_plan(): yield from setup_beamline_for_oav( composite.smargon, composite.backlight, composite.aperture_scatterguard @@ -109,6 +119,7 @@ def _pin_centre_then_flyscan_plan(): oav_params, HyperionSpecifiedThreeDGridScan, construct_hyperion_specific_features, + use_fastcs_eiger, ) yield from ispyb_activation_wrapper(_pin_centre_then_flyscan_plan(), parameters) @@ -117,11 +128,11 @@ def _pin_centre_then_flyscan_plan(): def pin_tip_centre_then_xray_centre( composite: HyperionGridDetectThenXRayCentreComposite, parameters: PinTipCentreThenXrayCentre, + use_fast_eiger: bool, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ) -> MsgGenerator: """Starts preparing for collection then performs the pin tip centre and xray centre""" - eiger: EigerDetector = composite.eiger - + eiger = composite.eiger eiger.set_detector_parameters(parameters.detector_params) flyscan_event_handler = XRayCentreEventHandler() @@ -133,7 +144,9 @@ def pin_centre_flyscan_then_fetch_results() -> MsgGenerator: eiger, composite.detector_motion, parameters.detector_params.detector_distance, - pin_centre_then_flyscan_plan(composite, parameters, oav_config_file), + pin_centre_then_flyscan_plan( + composite, parameters, use_fast_eiger, oav_config_file + ), group=CONST.WAIT.GRID_READY_FOR_DC, ) diff --git a/src/mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py index 045ec7afa1..613d474342 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py @@ -34,6 +34,7 @@ from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter from dodal.devices.zocalo import ZocaloResults from dodal.log import LOGGER +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from ophyd_async.fastcs.panda import HDFPanda from mx_bluesky.common.device_setup_plans.utils import ( @@ -74,6 +75,7 @@ class RobotLoadThenCentreComposite: beamsize: BeamsizeBase detector_motion: DetectorMotion eiger: EigerDetector + fastcs_eiger: FastCSEiger zebra_fast_grid_scan: ZebraFastGridScanThreeD flux: Flux oav: OAV @@ -111,11 +113,13 @@ def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite: def _flyscan_plan_from_robot_load_params( composite: RobotLoadThenCentreComposite, params: RobotLoadThenCentre, + use_fastcs_eiger: bool, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from pin_centre_then_flyscan_plan( cast(HyperionGridDetectThenXRayCentreComposite, composite), params.pin_centre_then_xray_centre_params, + use_fastcs_eiger, oav_config_file, ) @@ -123,6 +127,7 @@ def _flyscan_plan_from_robot_load_params( def _robot_load_then_flyscan_plan( composite: RobotLoadThenCentreComposite, params: RobotLoadThenCentre, + use_fastcs_eiger: bool, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from robot_load_and_change_energy_plan( @@ -130,12 +135,15 @@ def _robot_load_then_flyscan_plan( params.robot_load_params, ) - yield from _flyscan_plan_from_robot_load_params(composite, params, oav_config_file) + yield from _flyscan_plan_from_robot_load_params( + composite, params, use_fastcs_eiger, oav_config_file + ) def robot_load_then_xray_centre( composite: RobotLoadThenCentreComposite, parameters: RobotLoadThenCentre, + use_fastcs_eiger: bool, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ) -> MsgGenerator: """Perform pin-tip detection followed by a flyscan to determine centres of interest. @@ -160,7 +168,9 @@ def robot_load_then_xray_centre( if doing_sample_load: LOGGER.info("Pin not loaded, loading and centring") - plan = _robot_load_then_flyscan_plan(composite, parameters, oav_config_file) + plan = _robot_load_then_flyscan_plan( + composite, parameters, use_fastcs_eiger, oav_config_file + ) else: # Robot load normally sets the energy so we should do this explicitly if no load is # being done @@ -172,7 +182,7 @@ def robot_load_then_xray_centre( if doing_chi_change: plan = _flyscan_plan_from_robot_load_params( - composite, parameters, oav_config_file + composite, parameters, use_fastcs_eiger, oav_config_file ) LOGGER.info("Pin already loaded but chi changed so centring") else: @@ -183,11 +193,12 @@ def robot_load_then_xray_centre( composite.dcm, parameters.detector_params ) - eiger.set_detector_parameters(detector_params) + if not use_fastcs_eiger: + eiger.set_detector_parameters(detector_params) yield from start_preparing_data_collection_then_do_plan( composite.beamstop, - eiger, + composite.fastcs_eiger if use_fastcs_eiger else eiger, composite.detector_motion, parameters.detector_distance_mm, plan, diff --git a/src/mx_bluesky/hyperion/parameters/device_composites.py b/src/mx_bluesky/hyperion/parameters/device_composites.py index 5e7b204246..3225f57b13 100644 --- a/src/mx_bluesky/hyperion/parameters/device_composites.py +++ b/src/mx_bluesky/hyperion/parameters/device_composites.py @@ -7,7 +7,6 @@ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator from dodal.devices.backlight import Backlight from dodal.devices.common_dcm import DoubleCrystalMonochromatorWithDSpacing -from dodal.devices.eiger import EigerDetector from dodal.devices.fast_grid_scan import ( PandAFastGridScan, ZebraFastGridScanThreeD, @@ -16,7 +15,6 @@ from dodal.devices.i03.beamsize import Beamsize from dodal.devices.robot import BartRobot from dodal.devices.s4_slit_gaps import S4SlitGaps -from dodal.devices.synchrotron import Synchrotron from dodal.devices.undulator import UndulatorInKeV from dodal.devices.xbpm_feedback import XBPMFeedback from dodal.devices.zebra.zebra import Zebra @@ -39,11 +37,9 @@ class HyperionFlyScanXRayCentreComposite(FlyScanEssentialDevices): aperture_scatterguard: ApertureScatterguard attenuator: BinaryFilterAttenuator dcm: DoubleCrystalMonochromatorWithDSpacing - eiger: EigerDetector flux: Flux s4_slit_gaps: S4SlitGaps undulator: UndulatorInKeV - synchrotron: Synchrotron zebra: Zebra zocalo: ZocaloResults panda: HDFPanda diff --git a/tests/conftest.py b/tests/conftest.py index 7658f546b0..472ff0625c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -75,6 +75,7 @@ ) from ophyd_async.epics.core import epics_signal_rw from ophyd_async.epics.motor import Motor +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from ophyd_async.fastcs.panda import DatasetTable, PandaHdf5DatasetType from PIL import Image from pydantic.dataclasses import dataclass @@ -410,6 +411,15 @@ def eiger(done_status): return eiger +@pytest.fixture +def fastcs_eiger(done_status): + fascs_eiger = i03.fastcs_eiger.build(connect_immediately=True, mock=True) + fascs_eiger.stage = MagicMock(return_value=done_status) + fascs_eiger.kickoff = MagicMock(return_value=done_status) + fascs_eiger.unstage = MagicMock(return_value=done_status) + return fascs_eiger + + @pytest.fixture def smargon() -> Generator[Smargon, None, None]: smargon = i03.smargon.build(connect_immediately=True, mock=True) @@ -976,6 +986,7 @@ async def hyperion_flyscan_xrc_composite( fast_grid_scan, panda_fast_grid_scan, beamsize, + fastcs_eiger: FastCSEiger, ) -> HyperionFlyScanXRayCentreComposite: fake_composite = HyperionFlyScanXRayCentreComposite( aperture_scatterguard=aperture_scatterguard, @@ -998,6 +1009,7 @@ async def hyperion_flyscan_xrc_composite( robot=i03.robot.build(connect_immediately=True, mock=True), sample_shutter=i03.sample_shutter.build(connect_immediately=True, mock=True), beamsize=beamsize, + fastcs_eiger=fastcs_eiger, ) fake_composite.eiger.stage = MagicMock(return_value=done_status) diff --git a/tests/system_tests/hyperion/external_interaction/callbacks/test_external_callbacks.py b/tests/system_tests/hyperion/external_interaction/callbacks/test_external_callbacks.py index 9c2a7b1d14..5d637d065f 100644 --- a/tests/system_tests/hyperion/external_interaction/callbacks/test_external_callbacks.py +++ b/tests/system_tests/hyperion/external_interaction/callbacks/test_external_callbacks.py @@ -161,14 +161,14 @@ async def test_external_callbacks_handle_gridscan_ispyb_and_zocalo( # Run the xray centring plan beamline_specific = construct_hyperion_specific_features( - fgs_composite_for_fake_zocalo, dummy_params + fgs_composite_for_fake_zocalo, dummy_params, False ) @ispyb_activation_decorator(dummy_params) def wrapped_xray_centre(): yield from fake_grid_snapshot_plan(smargon, oav_for_system_test) yield from common_flyscan_xray_centre( - fgs_composite_for_fake_zocalo, dummy_params, beamline_specific + fgs_composite_for_fake_zocalo, dummy_params, beamline_specific, False ) run_engine(wrapped_xray_centre()) diff --git a/tests/system_tests/hyperion/external_interaction/test_ispyb_dev_connection.py b/tests/system_tests/hyperion/external_interaction/test_ispyb_dev_connection.py index af7afa81b0..8a7663d35c 100644 --- a/tests/system_tests/hyperion/external_interaction/test_ispyb_dev_connection.py +++ b/tests/system_tests/hyperion/external_interaction/test_ispyb_dev_connection.py @@ -421,6 +421,7 @@ def test_ispyb_deposition_in_gridscan( grid_detect_then_xray_centre_parameters, HyperionSpecifiedThreeDGridScan, construct_hyperion_specific_features, + False, ) ) diff --git a/tests/unit_tests/beamlines/i04/test_i04_grid_detect_then_xray_centre_plan.py b/tests/unit_tests/beamlines/i04/test_i04_grid_detect_then_xray_centre_plan.py index e748468309..7a2498cf8d 100644 --- a/tests/unit_tests/beamlines/i04/test_i04_grid_detect_then_xray_centre_plan.py +++ b/tests/unit_tests/beamlines/i04/test_i04_grid_detect_then_xray_centre_plan.py @@ -31,6 +31,7 @@ from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter from dodal.devices.zocalo import ZocaloResults from ophyd_async.core import get_mock_put, set_mock_value +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from mx_bluesky.beamlines.i04.experiment_plans.i04_grid_detect_then_xray_centre_plan import ( DEFAULT_XRC_BEAMSIZE_MICRONS, @@ -81,6 +82,7 @@ def i04_grid_detect_then_xrc_default_params( detector_motion: DetectorMotion, transfocator: Transfocator, tmp_path, + fastcs_eiger: FastCSEiger, ): entry_params = I04AutoXrcParams( sample_id=1, @@ -116,6 +118,7 @@ def i04_grid_detect_then_xrc_default_params( smargon=smargon, detector_motion=detector_motion, transfocator=transfocator, + fastcs_eiger=fastcs_eiger, ) diff --git a/tests/unit_tests/common/experiment_plans/test_common_flyscan_xray_centre_plan.py b/tests/unit_tests/common/experiment_plans/test_common_flyscan_xray_centre_plan.py index 71055e54bc..f21aea175d 100644 --- a/tests/unit_tests/common/experiment_plans/test_common_flyscan_xray_centre_plan.py +++ b/tests/unit_tests/common/experiment_plans/test_common_flyscan_xray_centre_plan.py @@ -117,7 +117,7 @@ def test_eiger2_x_16_detector_specified( def test_when_run_gridscan_called_then_generator_returned( self, ): - plan = run_gridscan(MagicMock(), MagicMock(), MagicMock()) + plan = run_gridscan(MagicMock(), MagicMock(), MagicMock(), False) assert isinstance(plan, types.GeneratorType) def test_when_run_gridscan_called_ispyb_deposition_made_and_records_errors( @@ -138,7 +138,10 @@ def test_when_run_gridscan_called_ispyb_deposition_made_and_records_errors( run_engine( ispyb_activation_wrapper( common_flyscan_xray_centre( - fake_fgs_composite, test_fgs_params, beamline_specific + fake_fgs_composite, + test_fgs_params, + beamline_specific, + False, ), test_fgs_params, ), @@ -192,9 +195,7 @@ def test_individual_plans_triggered_once_and_only_once_in_composite_run( def wrapped_gridscan_and_move(): yield from common_flyscan_xray_centre( - fake_fgs_composite, - test_fgs_params, - beamline_specific, + fake_fgs_composite, test_fgs_params, beamline_specific, False ) run_engine(wrapped_gridscan_and_move()) @@ -257,7 +258,9 @@ def test_if_gridscan_prepare_fails_with_invalid_grid_then_sample_exception_raise with pytest.raises(WarningError): run_engine( - run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific) + run_gridscan( + fake_fgs_composite, test_fgs_params, beamline_specific, False + ) ) @patch( @@ -278,7 +281,9 @@ def test_if_gridscan_prepare_fails_with_other_exception_then_plan_re_raised( with pytest.raises(FailedStatus) as e: run_engine( - run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific) + run_gridscan( + fake_fgs_composite, test_fgs_params, beamline_specific, False + ) ) mock_kickoff_and_complete.assert_not_called() @@ -350,7 +355,7 @@ def test_when_grid_scan_ran_then_eiger_disarmed_before_zocalo_end( run_engine( ispyb_activation_wrapper( common_flyscan_xray_centre( - fake_fgs_composite, test_fgs_params, beamline_specific + fake_fgs_composite, test_fgs_params, beamline_specific, False ), test_fgs_params, ) @@ -389,7 +394,9 @@ def test_fgs_arms_eiger_without_grid_detect( beamline_specific: BeamlineSpecificFGSFeatures, ): fake_fgs_composite.eiger.unstage = MagicMock(return_value=done_status) - run_engine(run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific)) + run_engine( + run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific, False) + ) fake_fgs_composite.eiger.stage.assert_called_once() # type: ignore fake_fgs_composite.eiger.unstage.assert_called_once() @@ -441,7 +448,9 @@ def test_when_grid_scan_fails_with_exception_then_detector_disarmed_and_correct_ with pytest.raises(CompleteError): run_engine( - run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific) + run_gridscan( + fake_fgs_composite, test_fgs_params, beamline_specific, False + ) ) fake_fgs_composite.eiger.disable_roi_mode.assert_called() @@ -538,7 +547,7 @@ def test_read_hardware_during_collection_occurs_after_eiger_arm( "synchrotron-synchrotron_mode", ) msgs = sim_run_engine.simulate_plan( - run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific) + run_gridscan(fake_fgs_composite, test_fgs_params, beamline_specific, False) ) msgs = assert_message_and_return_remaining( msgs, lambda msg: msg.command == "stage" and msg.obj.name == "eiger" @@ -576,9 +585,7 @@ def test_when_gridscan_succeeds_and_results_fetched_ispyb_comment_appended_to( def _wrapped_gridscan_and_move(): run_generic_ispyb_handler_setup(ispyb_cb, test_fgs_params) yield from common_flyscan_xray_centre( - fake_fgs_composite, - test_fgs_params, - beamline_specific, + fake_fgs_composite, test_fgs_params, beamline_specific, False ) beamline_specific.get_xrc_results_from_zocalo = True @@ -677,9 +684,7 @@ def test_when_gridscan_finds_no_xtal_exception_is_raised( def wrapped_gridscan_and_move(): run_generic_ispyb_handler_setup(ispyb_cb, test_fgs_params) yield from common_flyscan_xray_centre( - fake_fgs_composite, - test_fgs_params, - beamline_specific, + fake_fgs_composite, test_fgs_params, beamline_specific, False ) mock_zocalo_trigger(fake_fgs_composite.zocalo, []) @@ -707,9 +712,7 @@ def test_dummy_result_returned_when_gridscan_finds_no_xtal_and_commissioning_mod mock_zocalo_trigger(fake_fgs_composite.zocalo, []) run_engine( common_flyscan_xray_centre( - fake_fgs_composite, - test_fgs_params, - beamline_specific, + fake_fgs_composite, test_fgs_params, beamline_specific, False ) ) diff --git a/tests/unit_tests/common/experiment_plans/test_common_grid_detect_then_xray_centre_plan.py b/tests/unit_tests/common/experiment_plans/test_common_grid_detect_then_xray_centre_plan.py index f3c676d25e..e5d4e7c48e 100644 --- a/tests/unit_tests/common/experiment_plans/test_common_grid_detect_then_xray_centre_plan.py +++ b/tests/unit_tests/common/experiment_plans/test_common_grid_detect_then_xray_centre_plan.py @@ -57,7 +57,9 @@ def _fake_flyscan(*args): def construct_beamline_specific( beamline_specific: BeamlineSpecificFGSFeatures, ) -> ConstructBeamlineSpecificFeatures: - return lambda xrc_composite, xrc_parameters: beamline_specific + return ( + lambda xrc_composite, xrc_parameters, use_fastcs_eiger: beamline_specific + ) # https://github.com/DiamondLightSource/mx-bluesky/pull/1436/ @pytest.mark.timeout(2) @@ -109,7 +111,7 @@ async def test_detect_grid_and_do_gridscan_in_real_run_engine( ) # Check we called out to underlying fast grid scan plan - mock_flyscan.assert_called_once_with(ANY, ANY, ANY) + mock_flyscan.assert_called_once_with(ANY, ANY, ANY, ANY) @patch( @@ -163,6 +165,7 @@ def test_detect_grid_and_do_gridscan_sets_up_beamline_for_oav( construct_beamline_specific=construct_beamline_specific, oav_config=test_config_files["oav_config_json"], xrc_params_type=SpecifiedThreeDGridScan, + use_fastcs_eiger=False, ), ) @@ -181,6 +184,7 @@ def _do_detect_grid_and_gridscan_then_wait_for_backlight( oav_params=OAVParameters("xrayCentring", test_config_files["oav_config_json"]), xrc_params_type=HyperionSpecifiedThreeDGridScan, construct_beamline_specific=construct_beamline_specific_xrc_features, + use_fastcs_eiger=False, ) yield from bps.wait(PlanGroupCheckpointConstants.GRID_READY_FOR_DC) @@ -209,6 +213,7 @@ def test_when_full_grid_scan_run_then_parameters_sent_to_fgs_as_expected( oav_params=oav_params, xrc_params_type=HyperionSpecifiedThreeDGridScan, construct_beamline_specific=construct_beamline_specific, + use_fastcs_eiger=False, ), test_full_grid_scan_params, ) @@ -270,6 +275,7 @@ def test_detect_grid_and_do_gridscan_does_not_activate_ispyb_callback( OAVParameters("xrayCentring", test_config_files["oav_config_json"]), xrc_params_type=HyperionSpecifiedThreeDGridScan, construct_beamline_specific=construct_beamline_specific, + use_fastcs_eiger=False, ) ) @@ -340,6 +346,7 @@ def msgs_from_simulated_grid_detect_then_xray_centre( xrc_params_type=SpecifiedThreeDGridScan, construct_beamline_specific=construct_beamline_specific, oav_config=test_config_files["oav_config_json"], + use_fastcs_eiger=False, ) ) diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index 29cc19a30f..026eacd1c1 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -36,6 +36,7 @@ init_devices, set_mock_value, ) +from ophyd_async.fastcs.eiger import EigerDetector as FastCSEiger from ophyd_async.fastcs.panda import HDFPanda from mx_bluesky.common.experiment_plans.beamstop_check import BeamstopCheckDevices @@ -342,6 +343,7 @@ async def fake_fgs_composite( smargon=smargon, synchrotron=synchrotron, zocalo=zocalo, + fastcs_eiger=i03.fastcs_eiger.build(connect_immediately=True, mock=True), ) fake_composite.eiger.stage = MagicMock(return_value=done_status) @@ -414,6 +416,7 @@ async def grid_detect_xrc_devices( beamsize: BeamsizeBase, detector_motion: DetectorMotion, eiger: EigerDetector, + fastcs_eiger: FastCSEiger, smargon: Smargon, oav: OAV, ophyd_pin_tip_detection: PinTipDetection, @@ -451,6 +454,7 @@ async def grid_detect_xrc_devices( dcm=dcm, robot=MagicMock(spec=BartRobot), sample_shutter=zebra_shutter, + fastcs_eiger=fastcs_eiger, ) @@ -462,6 +466,17 @@ async def hyperion_grid_detect_xrc_devices(grid_detect_xrc_devices): return composite +@pytest.fixture +async def hyperion_grid_detect_xrc_devices_with_fastcs_eiger( + grid_detect_xrc_devices, fastcs_eiger: FastCSEiger +): + composite = cast(HyperionGridDetectThenXRayCentreComposite, grid_detect_xrc_devices) + composite.panda = MagicMock(spec=HDFPanda) + composite.panda_fast_grid_scan = MagicMock(spec=PandAFastGridScan) + composite.fastcs_eiger = fastcs_eiger + return composite + + # See https://github.com/DiamondLightSource/dodal/issues/1455 @pytest.fixture def jungfrau(tmp_path: Path) -> CommissioningJungfrau: diff --git a/tests/unit_tests/hyperion/experiment_plans/conftest.py b/tests/unit_tests/hyperion/experiment_plans/conftest.py index 89af00b641..1c9d480356 100644 --- a/tests/unit_tests/hyperion/experiment_plans/conftest.py +++ b/tests/unit_tests/hyperion/experiment_plans/conftest.py @@ -251,6 +251,7 @@ def robot_load_composite( panda, panda_fast_grid_scan, beamsize: BeamsizeBase, + fastcs_eiger, ) -> RobotLoadThenCentreComposite: set_mock_value(dcm.energy_in_keV.user_readback, 11.105) smargon.stub_offsets.set = MagicMock(return_value=NullStatus()) @@ -286,6 +287,7 @@ def robot_load_composite( robot=robot, webcam=webcam, lower_gonio=lower_gonio, + fastcs_eiger=fastcs_eiger, ) @@ -372,5 +374,5 @@ def beamline_specific( hyperion_fgs_params: HyperionSpecifiedThreeDGridScan, ) -> BeamlineSpecificFGSFeatures: return construct_hyperion_specific_features( - hyperion_flyscan_xrc_composite, hyperion_fgs_params + hyperion_flyscan_xrc_composite, hyperion_fgs_params, False ) diff --git a/tests/unit_tests/hyperion/experiment_plans/test_hyperion_flyscan_xray_centre_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_hyperion_flyscan_xray_centre_plan.py index 3f7411618d..5ced1dadab 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_hyperion_flyscan_xray_centre_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_hyperion_flyscan_xray_centre_plan.py @@ -113,6 +113,7 @@ def test_results_adjusted_and_passed_to_move_xyz( hyperion_flyscan_xrc_composite, hyperion_fgs_params, beamline_specific, + False, ) ) @@ -170,6 +171,7 @@ async def test_when_gridscan_finished_then_dev_shm_disabled( hyperion_flyscan_xrc_composite, hyperion_fgs_params, beamline_specific, + False, ) ) @@ -206,6 +208,7 @@ def test_if_smargon_speed_over_limit_then_log_error( hyperion_flyscan_xrc_composite, fgs_params_use_panda, beamline_specific, + False, ) ) @@ -247,7 +250,10 @@ def test_flyscan_xray_centre_sets_directory_stages_arms_disarms_unstages_the_pan msgs = sim_run_engine.simulate_plan( common_flyscan_xray_centre( - fgs_composite_with_panda_pcap, fgs_params_use_panda, beamline_specific + fgs_composite_with_panda_pcap, + fgs_params_use_panda, + beamline_specific, + False, ) ) diff --git a/tests/unit_tests/hyperion/experiment_plans/test_hyperion_grid_detect_then_xray_centre_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_hyperion_grid_detect_then_xray_centre_plan.py index 9228e4c9cb..404ef0e9b5 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_hyperion_grid_detect_then_xray_centre_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_hyperion_grid_detect_then_xray_centre_plan.py @@ -34,6 +34,7 @@ def test_full_hyperion_grid_scan( plan = hyperion_grid_detect_then_xray_centre( devices, cast(GridScanWithEdgeDetect, hyperion_fgs_params), + False, test_config_files["oav_config_json"], ) assert isinstance(plan, Generator) @@ -87,6 +88,7 @@ class TestError(Exception): hyperion_grid_detect_then_xray_centre( hyperion_grid_detect_xrc_devices, test_full_grid_scan_params, + False, test_config_files["oav_config_json"], ) ) @@ -142,6 +144,7 @@ def test_hyperion_grid_detect_then_xray_centre_pauses_and_unpauses_xbpm_feedback hyperion_grid_detect_then_xray_centre( hyperion_grid_detect_xrc_devices, test_full_grid_scan_params, + False, test_config_files["oav_config_json"], ), ) @@ -221,6 +224,7 @@ def test_hyperion_grid_detect_then_xray_centre_does_undulator_check_before_colle hyperion_grid_detect_then_xray_centre( hyperion_grid_detect_xrc_devices, test_full_grid_scan_params, + False, test_config_files["oav_config_json"], ) ) diff --git a/tests/unit_tests/hyperion/experiment_plans/test_pin_centre_then_xray_centre_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_pin_centre_then_xray_centre_plan.py index 95caba4df6..1251ea56aa 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_pin_centre_then_xray_centre_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_pin_centre_then_xray_centre_plan.py @@ -111,6 +111,7 @@ def test_when_pin_centre_xray_centre_called_then_plan_runs_correctly( pin_centre_then_flyscan_plan( hyperion_grid_detect_xrc_devices, test_pin_centre_then_xray_centre_params, + False, test_config_files["oav_config_json"], ) ) @@ -240,6 +241,7 @@ def test_pin_centre_then_xray_centre_plan_activates_ispyb_callback_before_pin_ti pin_centre_then_flyscan_plan( hyperion_grid_detect_xrc_devices, test_pin_centre_then_xray_centre_params, + False, test_config_files["oav_config_json"], ) ) @@ -283,6 +285,7 @@ def test_pin_centre_then_xray_centre_plan_sets_up_backlight_and_aperture( pin_centre_then_flyscan_plan( hyperion_grid_detect_xrc_devices, test_pin_centre_then_xray_centre_params, + False, test_config_files["oav_config_json"], ) ) @@ -336,6 +339,7 @@ def test_pin_centre_then_xray_centre_plan_goes_to_the_starting_chi_and_phi( pin_centre_then_flyscan_plan( hyperion_grid_detect_xrc_devices, test_pin_centre_then_xray_centre_params, + False, test_config_files["oav_config_json"], ) ) @@ -378,7 +382,9 @@ def test_pin_tip_centre_then_xray_centre_moves_beamstop_into_place( msgs = sim_run_engine.simulate_plan( pin_tip_centre_then_xray_centre( - hyperion_grid_detect_xrc_devices, test_pin_centre_then_xray_centre_params + hyperion_grid_detect_xrc_devices, + test_pin_centre_then_xray_centre_params, + False, ) ) diff --git a/tests/unit_tests/hyperion/experiment_plans/test_robot_load_then_centre.py b/tests/unit_tests/hyperion/experiment_plans/test_robot_load_then_centre.py index 8d7c0b1b1c..ae34ddead5 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_robot_load_then_centre.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_robot_load_then_centre.py @@ -55,7 +55,7 @@ def sample_is_not_loaded(sim_run_engine, sample_is_loaded): mock_current_sample(sim_run_engine, SampleLocation(1, 1)) -def mock_pin_centre_then_flyscan_plan(_, __, ___): +def mock_pin_centre_then_flyscan_plan(_, __, ___, ____): yield from _fire_xray_centre_result_event([FLYSCAN_RESULT_MED, FLYSCAN_RESULT_LOW]) @@ -74,7 +74,9 @@ def test_when_plan_run_then_centring_plan_run_with_expected_parameters( run_engine: RunEngine, ): run_engine( - robot_load_then_xray_centre(robot_load_composite, robot_load_then_centre_params) + robot_load_then_xray_centre( + robot_load_composite, robot_load_then_centre_params, False + ) ) composite_passed = mock_centring_plan.call_args[0][0] params_passed: PinTipCentreThenXrayCentre = mock_centring_plan.call_args[0][1] @@ -107,7 +109,9 @@ def test_when_plan_run_with_requested_energy_specified_energy_set_on_eiger( sim_run_engine.add_handler_for_callback_subscribes() sim_fire_event_on_open_run(sim_run_engine, CONST.PLAN.FLYSCAN_RESULTS) sim_run_engine.simulate_plan( - robot_load_then_xray_centre(robot_load_composite, robot_load_then_centre_params) + robot_load_then_xray_centre( + robot_load_composite, robot_load_then_centre_params, False + ) ) det_params = robot_load_composite.eiger.set_detector_parameters.call_args[0][0] assert det_params.expected_energy_ev == 11100 @@ -138,8 +142,7 @@ def test_given_no_energy_supplied_when_robot_load_then_centre_current_energy_set ) sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params_no_energy, + robot_load_composite, robot_load_then_centre_params_no_energy, False ) ) det_params = robot_load_composite.eiger.set_detector_parameters.call_args[0][0] @@ -169,7 +172,9 @@ def return_not_disabled_after_reads(_): ) return sim_run_engine.simulate_plan( - robot_load_then_xray_centre(robot_load_composite, robot_load_then_centre_params) + robot_load_then_xray_centre( + robot_load_composite, robot_load_then_centre_params, False + ) ) @@ -193,7 +198,9 @@ def test_when_plan_run_then_detector_arm_started_before_wait_on_robot_load( sim_run_engine.add_handler_for_callback_subscribes() sim_fire_event_on_open_run(sim_run_engine, CONST.PLAN.FLYSCAN_RESULTS) messages = sim_run_engine.simulate_plan( - robot_load_then_xray_centre(robot_load_composite, robot_load_then_centre_params) + robot_load_then_xray_centre( + robot_load_composite, robot_load_then_centre_params, False + ) ) messages = assert_message_and_return_remaining( messages, lambda msg: msg.command == "set" and msg.obj.name == "eiger_do_arm" @@ -234,8 +241,7 @@ def test_given_sample_already_loaded_and_chi_not_changed_when_robot_load_called_ messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) @@ -269,8 +275,7 @@ def test_given_sample_already_loaded_and_chi_is_changed_when_robot_load_called_t messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) @@ -309,8 +314,7 @@ def test_given_sample_not_loaded_and_chi_not_changed_when_robot_load_called_then messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) @@ -349,8 +353,7 @@ def test_given_sample_not_loaded_and_chi_changed_when_robot_load_called_then_eig messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) @@ -389,8 +392,7 @@ def test_robot_load_then_centre_sets_energy_when_chi_change_and_no_robot_load( messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) @@ -418,8 +420,7 @@ def test_robot_load_then_centre_sets_energy_when_no_robot_load_no_chi_change( messages = sim_run_engine.simulate_plan( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) messages = assert_message_and_return_remaining( @@ -451,7 +452,9 @@ def test_robot_load_then_centre_moves_beamstop_into_place( ) msgs = sim_run_engine.simulate_plan( - robot_load_then_xray_centre(robot_load_composite, robot_load_then_centre_params) + robot_load_then_xray_centre( + robot_load_composite, robot_load_then_centre_params, False + ) ) msgs = assert_message_and_return_remaining( msgs, @@ -481,8 +484,7 @@ def test_box_size_passed_through_to_gridscan( robot_load_then_centre_params.box_size_um = 25 run_engine( robot_load_then_xray_centre( - robot_load_composite, - robot_load_then_centre_params, + robot_load_composite, robot_load_then_centre_params, False ) ) detect_grid_call = mock_detect_grid.mock_calls[0]