From 53f0d07df80b4839b215d88cb3e3cddcfcc05c16 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Tue, 14 Jan 2025 10:43:40 +0000 Subject: [PATCH 01/10] Get Hyperion parameters to correctly pass features to its subsequent parameter models --- src/mx_bluesky/common/parameters/gridscan.py | 13 -------- .../common/parameters/robot_load.py | 14 +++++++++ .../experiment_plans/experiment_registry.py | 5 ++-- .../robot_load_then_centre_plan.py | 10 +++---- .../hyperion/parameters/components.py | 5 ++-- .../hyperion/parameters/gridscan.py | 23 ++++++++------ .../parameters/load_centre_collect.py | 10 +++---- .../hyperion/parameters/robot_load.py | 23 ++++++++++++++ .../hyperion/parameters/rotation.py | 4 +-- .../test_robot_load_then_centre.py | 30 +++++++++---------- .../parameters/test_parameter_model.py | 4 +-- 11 files changed, 85 insertions(+), 56 deletions(-) create mode 100644 src/mx_bluesky/hyperion/parameters/robot_load.py diff --git a/src/mx_bluesky/common/parameters/gridscan.py b/src/mx_bluesky/common/parameters/gridscan.py index 7e791d3a7..4f3aed4b7 100644 --- a/src/mx_bluesky/common/parameters/gridscan.py +++ b/src/mx_bluesky/common/parameters/gridscan.py @@ -27,7 +27,6 @@ GridscanParamConstants, HardwareConstants, ) -from mx_bluesky.common.parameters.robot_load import RobotLoadAndEnergyChange class GridCommon( @@ -73,20 +72,8 @@ def detector_params(self): **optional_args, ) - -class RobotLoadThenCentre(GridCommon): - thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM) - def robot_load_params(self): - my_params = self.model_dump() - return RobotLoadAndEnergyChange(**my_params) - - def pin_centre_then_xray_centre_params(self): - my_params = self.model_dump() - del my_params["thawing_time"] - return PinTipCentreThenXrayCentre(**my_params) - class GridScanWithEdgeDetect(GridCommon): box_size_um: float = Field(default=GridscanParamConstants.BOX_WIDTH_UM) diff --git a/src/mx_bluesky/common/parameters/robot_load.py b/src/mx_bluesky/common/parameters/robot_load.py index f522050fa..dea7fa917 100644 --- a/src/mx_bluesky/common/parameters/robot_load.py +++ b/src/mx_bluesky/common/parameters/robot_load.py @@ -8,9 +8,23 @@ WithVisit, ) from mx_bluesky.common.parameters.constants import HardwareConstants +from mx_bluesky.common.parameters.gridscan import GridCommon, PinTipCentreThenXrayCentre class RobotLoadAndEnergyChange( MxBlueskyParameters, WithSample, WithSnapshot, WithOptionalEnergyChange, WithVisit ): thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) + + +class RobotLoadThenCentre(GridCommon): + thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) + + def robot_load_params(self): + my_params = self.model_dump() + return RobotLoadAndEnergyChange(**my_params) + + def pin_centre_then_xray_centre_params(self): + my_params = self.model_dump() + del my_params["thawing_time"] + return PinTipCentreThenXrayCentre(**my_params) diff --git a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py index af165dfa9..52d32ed6a 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py +++ b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py @@ -8,7 +8,6 @@ from mx_bluesky.common.parameters.gridscan import ( GridScanWithEdgeDetect, PinTipCentreThenXrayCentre, - RobotLoadThenCentre, ) from mx_bluesky.hyperion.experiment_plans import ( grid_detect_then_xray_centre_plan, @@ -44,7 +43,7 @@ class ExperimentRegistryEntry(TypedDict): | RotationScan | MultiRotationScan | PinTipCentreThenXrayCentre - | RobotLoadThenCentre + | HyperionThreeDGridScan | LoadCentreCollect ] callbacks_factory: CallbacksFactory @@ -73,7 +72,7 @@ class ExperimentRegistryEntry(TypedDict): }, "robot_load_then_centre": { "setup": robot_load_then_centre_plan.create_devices, - "param_type": RobotLoadThenCentre, + "param_type": HyperionThreeDGridScan, "callbacks_factory": create_robot_load_and_centre_callbacks, }, "multi_rotation_scan": { 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 8e37c5193..c4a1c9864 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 @@ -37,7 +37,6 @@ from ophyd_async.fastcs.panda import HDFPanda from mx_bluesky.common.parameters.constants import OavConstants -from mx_bluesky.common.parameters.gridscan import RobotLoadThenCentre from mx_bluesky.hyperion.device_setup_plans.utils import ( fill_in_energy_if_not_supplied, start_preparing_data_collection_then_do_plan, @@ -64,6 +63,7 @@ set_energy_plan, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True}) @@ -113,7 +113,7 @@ def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite: def _flyscan_plan_from_robot_load_params( composite: RobotLoadThenCentreComposite, - params: RobotLoadThenCentre, + params: HyperionRobotLoadThenCentre, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from pin_centre_then_flyscan_plan( @@ -124,7 +124,7 @@ def _flyscan_plan_from_robot_load_params( def _robot_load_then_flyscan_plan( composite: RobotLoadThenCentreComposite, - params: RobotLoadThenCentre, + params: HyperionRobotLoadThenCentre, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from robot_load_and_change_energy_plan( @@ -137,7 +137,7 @@ def _robot_load_then_flyscan_plan( def robot_load_then_centre( composite: RobotLoadThenCentreComposite, - parameters: RobotLoadThenCentre, + parameters: HyperionRobotLoadThenCentre, ) -> MsgGenerator: """Perform pin-tip detection followed by a flyscan to determine centres of interest. Performs a robot load if necessary. Centre on the best diffracting centre. @@ -158,7 +158,7 @@ def robot_load_then_centre( def robot_load_then_xray_centre( composite: RobotLoadThenCentreComposite, - parameters: RobotLoadThenCentre, + parameters: HyperionRobotLoadThenCentre, ) -> MsgGenerator: """Perform pin-tip detection followed by a flyscan to determine centres of interest. Performs a robot load if necessary.""" diff --git a/src/mx_bluesky/hyperion/parameters/components.py b/src/mx_bluesky/hyperion/parameters/components.py index 98076c218..77dde7f4d 100644 --- a/src/mx_bluesky/hyperion/parameters/components.py +++ b/src/mx_bluesky/hyperion/parameters/components.py @@ -1,7 +1,8 @@ -from pydantic import BaseModel, Field +from pydantic import Field +from mx_bluesky.common.parameters.components import WithPandaGridScan from mx_bluesky.hyperion.external_interaction.config_server import HyperionFeatureFlags -class WithHyperionFeatures(BaseModel): +class WithHyperionUDCFeatures(WithPandaGridScan): features: HyperionFeatureFlags = Field(default=HyperionFeatureFlags()) diff --git a/src/mx_bluesky/hyperion/parameters/gridscan.py b/src/mx_bluesky/hyperion/parameters/gridscan.py index 77e6b12ef..1b1ea6827 100644 --- a/src/mx_bluesky/hyperion/parameters/gridscan.py +++ b/src/mx_bluesky/hyperion/parameters/gridscan.py @@ -8,21 +8,16 @@ ZebraGridScanParams, ) -from mx_bluesky.common.parameters.components import ( - WithPandaGridScan, -) from mx_bluesky.common.parameters.gridscan import ( + GridScanWithEdgeDetect, + PinTipCentreThenXrayCentre, ThreeDGridScan, ) -from mx_bluesky.hyperion.parameters.components import WithHyperionFeatures +from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures from mx_bluesky.hyperion.parameters.constants import CONST, I03Constants -class HyperionThreeDGridScan( - ThreeDGridScan, - WithPandaGridScan, - WithHyperionFeatures, -): +class HyperionThreeDGridScan(ThreeDGridScan, WithHyperionUDCFeatures): """Hyperion's 3D grid scan varies from the common class due to: optionally using a PandA, optionally using dev_shm for GPU analysis, and using a config server for features""" # These detector params only exist so that we can properly select enable_dev_shm. Remove in @@ -103,3 +98,13 @@ def panda_FGS_params(self) -> PandAGridScanParams: class OddYStepsException(Exception): ... + + +class HyperionPinTipCentreThenXrayCentre( + PinTipCentreThenXrayCentre, WithHyperionUDCFeatures +): ... + + +class HyperionGridScanWithEdgeDetect( + GridScanWithEdgeDetect, WithHyperionUDCFeatures +): ... diff --git a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py index 73d6b2774..cdc74ce4d 100644 --- a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py +++ b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py @@ -8,8 +8,8 @@ WithSample, WithVisit, ) -from mx_bluesky.common.parameters.gridscan import ( - RobotLoadThenCentre, +from mx_bluesky.hyperion.parameters.robot_load import ( + HyperionRobotLoadThenCentre, ) from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan @@ -28,7 +28,7 @@ class LoadCentreCollect( """Experiment parameters to perform the combined robot load, pin-tip centre and rotation scan operations.""" - robot_load_then_centre: RobotLoadThenCentre + robot_load_then_centre: HyperionRobotLoadThenCentre multi_rotation_scan: MultiRotationScan @model_validator(mode="before") @@ -36,7 +36,7 @@ class LoadCentreCollect( def validate_model(cls, values): allowed_keys = ( LoadCentreCollect.model_fields.keys() - | RobotLoadThenCentre.model_fields.keys() + | HyperionRobotLoadThenCentre.model_fields.keys() | MultiRotationScan.model_fields.keys() ) @@ -66,7 +66,7 @@ def validate_model(cls, values): ) new_robot_load_then_centre_params = construct_from_values( - values, values["robot_load_then_centre"], RobotLoadThenCentre + values, values["robot_load_then_centre"], HyperionRobotLoadThenCentre ) new_multi_rotation_scan_params = construct_from_values( values, values["multi_rotation_scan"], MultiRotationScan diff --git a/src/mx_bluesky/hyperion/parameters/robot_load.py b/src/mx_bluesky/hyperion/parameters/robot_load.py new file mode 100644 index 000000000..0e97568b6 --- /dev/null +++ b/src/mx_bluesky/hyperion/parameters/robot_load.py @@ -0,0 +1,23 @@ +from pydantic import Field + +from mx_bluesky.common.parameters.constants import HardwareConstants +from mx_bluesky.common.parameters.robot_load import ( + RobotLoadAndEnergyChange, + RobotLoadThenCentre, +) +from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures +from mx_bluesky.hyperion.parameters.gridscan import HyperionPinTipCentreThenXrayCentre + + +class HyperionRobotLoadThenCentre(RobotLoadThenCentre, WithHyperionUDCFeatures): + thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) + tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM) + + def robot_load_params(self): + my_params = self.model_dump() + return RobotLoadAndEnergyChange(**my_params) + + def pin_centre_then_xray_centre_params(self): + my_params = self.model_dump() + del my_params["thawing_time"] + return HyperionPinTipCentreThenXrayCentre(**my_params) diff --git a/src/mx_bluesky/hyperion/parameters/rotation.py b/src/mx_bluesky/hyperion/parameters/rotation.py index 97bf8808a..dd63e7b26 100644 --- a/src/mx_bluesky/hyperion/parameters/rotation.py +++ b/src/mx_bluesky/hyperion/parameters/rotation.py @@ -26,7 +26,7 @@ SplitScan, WithScan, ) -from mx_bluesky.hyperion.parameters.components import WithHyperionFeatures +from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures from mx_bluesky.hyperion.parameters.constants import ( CONST, I03Constants, @@ -53,7 +53,7 @@ class RotationScanPerSweep(OptionalGonioAngleStarts, OptionalXyzStarts): nexus_vds_start_img: int = Field(default=0, ge=0) -class RotationExperiment(DiffractionExperimentWithSample, WithHyperionFeatures): +class RotationExperiment(DiffractionExperimentWithSample, WithHyperionUDCFeatures): shutter_opening_time_s: float = Field(default=CONST.I03.SHUTTER_TIME_S) rotation_increment_deg: float = Field(default=0.1, gt=0) ispyb_experiment_type: IspybExperimentType = Field( 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 a65e7fd80..76a3b9f73 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 @@ -10,7 +10,6 @@ from mx_bluesky.common.parameters.gridscan import ( PinTipCentreThenXrayCentre, - RobotLoadThenCentre, ) from mx_bluesky.hyperion.device_setup_plans.check_beamstop import BeamstopException from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( @@ -24,6 +23,7 @@ robot_load_then_centre, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre from ....conftest import assert_none_matching, raw_params_from_file from .conftest import FLYSCAN_RESULT_LOW, FLYSCAN_RESULT_MED, sim_fire_event_on_open_run @@ -34,7 +34,7 @@ def robot_load_then_centre_params(): params = raw_params_from_file( "tests/test_data/parameter_json_files/good_test_robot_load_and_centre_params.json" ) - return RobotLoadThenCentre(**params) + return HyperionRobotLoadThenCentre(**params) @pytest.fixture @@ -76,7 +76,7 @@ def test_robot_load_then_centre_centres_on_the_first_flyscan_result( mock_change_aperture_then_move_to_xtal: MagicMock, mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, ): RE = RunEngine() @@ -100,7 +100,7 @@ def test_robot_load_then_centre_centres_on_the_first_flyscan_result( def test_when_plan_run_then_centring_plan_run_with_expected_parameters( mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, ): RE = RunEngine() @@ -129,7 +129,7 @@ def test_when_plan_run_then_centring_plan_run_with_expected_parameters( def test_when_plan_run_with_requested_energy_specified_energy_set_on_eiger( mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, ): robot_load_composite.eiger.set_detector_parameters = MagicMock() @@ -154,7 +154,7 @@ def test_when_plan_run_with_requested_energy_specified_energy_set_on_eiger( ) def test_given_no_energy_supplied_when_robot_load_then_centre_current_energy_set_on_eiger( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params_no_energy: RobotLoadThenCentre, + robot_load_then_centre_params_no_energy: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, ): robot_load_composite.eiger.set_detector_parameters = MagicMock() @@ -216,7 +216,7 @@ def dummy_robot_load_plan(*args, **kwargs): ) def test_when_plan_run_then_detector_arm_started_before_wait_on_robot_load( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine, ): sim_run_engine.add_handler_for_callback_subscribes() @@ -264,7 +264,7 @@ def mock_current_sample(sim_run_engine: RunEngineSimulator, sample: SampleLocati ) def test_given_sample_already_loaded_and_chi_not_changed_when_robot_load_called_then_eiger_not_staged_and_centring_not_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_loaded, ): @@ -314,7 +314,7 @@ def test_given_sample_already_loaded_and_chi_not_changed_when_robot_load_called_ ) def test_given_sample_already_loaded_and_chi_is_changed_when_robot_load_called_then_eiger_staged_and_centring_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_loaded, ): @@ -373,7 +373,7 @@ def test_given_sample_already_loaded_and_chi_is_changed_when_robot_load_called_t ) def test_given_sample_not_loaded_and_chi_not_changed_when_robot_load_called_then_eiger_staged_before_robot_and_centring_run_after( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_not_loaded, ): @@ -416,7 +416,7 @@ def test_given_sample_not_loaded_and_chi_not_changed_when_robot_load_called_then ) def test_given_sample_not_loaded_and_chi_changed_when_robot_load_called_then_eiger_staged_before_robot_and_centring_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_not_loaded, ): @@ -465,7 +465,7 @@ def test_given_sample_not_loaded_and_chi_changed_when_robot_load_called_then_eig def test_robot_load_then_centre_sets_energy_when_chi_change_and_no_robot_load( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sample_is_loaded, ): robot_load_then_centre_params.chi_start_deg = 30 @@ -494,7 +494,7 @@ def test_robot_load_then_centre_sets_energy_when_chi_change_and_no_robot_load( def test_robot_load_then_centre_sets_energy_when_no_robot_load_no_chi_change( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, sample_is_loaded, ): robot_load_then_centre_params.chi_start_deg = None @@ -511,7 +511,7 @@ def test_robot_load_then_centre_sets_energy_when_no_robot_load_no_chi_change( def test_tip_offset_um_passed_to_pin_tip_centre_plan( - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, ): robot_load_then_centre_params.tip_offset_um = 100 assert ( @@ -523,7 +523,7 @@ def test_tip_offset_um_passed_to_pin_tip_centre_plan( def test_robot_load_then_centre_fails_with_exception_when_no_beamstop( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: RobotLoadThenCentre, + robot_load_then_centre_params: HyperionRobotLoadThenCentre, ): sim_run_engine.add_read_handler_for( robot_load_composite.beamstop.selected_pos, BeamstopPositions.UNKNOWN diff --git a/tests/unit_tests/hyperion/parameters/test_parameter_model.py b/tests/unit_tests/hyperion/parameters/test_parameter_model.py index 7124ee86f..c2faa0c89 100644 --- a/tests/unit_tests/hyperion/parameters/test_parameter_model.py +++ b/tests/unit_tests/hyperion/parameters/test_parameter_model.py @@ -7,11 +7,11 @@ from pydantic import ValidationError from mx_bluesky.common.parameters.constants import GridscanParamConstants -from mx_bluesky.common.parameters.gridscan import RobotLoadThenCentre from mx_bluesky.hyperion.parameters.gridscan import ( HyperionThreeDGridScan, OddYStepsException, ) +from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre from mx_bluesky.hyperion.parameters.rotation import RotationScan from ....conftest import raw_params_from_file @@ -84,7 +84,7 @@ def test_robot_load_then_centre_params(): "storage_directory": "/tmp/dls/i03/data/2024/cm31105-4/xraycentring/123456/", } params["detector_distance_mm"] = 200 - test_params = RobotLoadThenCentre(**params) + test_params = HyperionRobotLoadThenCentre(**params) assert test_params.detector_params From 8aadf2e0a54e8fd7daaf8f638220820d61e1e6b9 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Tue, 14 Jan 2025 11:36:34 +0000 Subject: [PATCH 02/10] Fixes and tests --- .../common/parameters/components.py | 2 +- .../good_test_load_centre_collect_params.json | 4 +- .../parameters/test_parameter_model.py | 55 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/mx_bluesky/common/parameters/components.py b/src/mx_bluesky/common/parameters/components.py index d239cf494..8e9da1ae0 100644 --- a/src/mx_bluesky/common/parameters/components.py +++ b/src/mx_bluesky/common/parameters/components.py @@ -29,7 +29,7 @@ GridscanParamConstants, ) -PARAMETER_VERSION = Version.parse("5.2.0") +PARAMETER_VERSION = Version.parse("5.3.0") class RotationAxis(StrEnum): diff --git a/tests/test_data/parameter_json_files/good_test_load_centre_collect_params.json b/tests/test_data/parameter_json_files/good_test_load_centre_collect_params.json index 4b064ebef..fcd8dddb4 100644 --- a/tests/test_data/parameter_json_files/good_test_load_centre_collect_params.json +++ b/tests/test_data/parameter_json_files/good_test_load_centre_collect_params.json @@ -15,7 +15,9 @@ "exposure_time_s": 0.004, "use_roi_mode": false, "demand_energy_ev": 11100, - "run_number": 0 + "run_number": 0, + "features": {"use_panda_for_gridscan": false, "compare_cpu_and_gpu_zocalo": true}, + "panda_runup_distance_mm": 0.17 }, "multi_rotation_scan": { "comment": "Rotation", diff --git a/tests/unit_tests/hyperion/parameters/test_parameter_model.py b/tests/unit_tests/hyperion/parameters/test_parameter_model.py index c2faa0c89..bc09c091d 100644 --- a/tests/unit_tests/hyperion/parameters/test_parameter_model.py +++ b/tests/unit_tests/hyperion/parameters/test_parameter_model.py @@ -6,17 +6,36 @@ from dodal.devices.aperturescatterguard import ApertureValue from pydantic import ValidationError +from mx_bluesky.common.external_interaction.callbacks.common.grid_detection_callback import ( + GridParamUpdate, +) from mx_bluesky.common.parameters.constants import GridscanParamConstants +from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import ( + create_parameters_for_flyscan_xray_centre, +) +from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan import ( + create_parameters_for_grid_detection, +) from mx_bluesky.hyperion.parameters.gridscan import ( HyperionThreeDGridScan, OddYStepsException, ) +from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre from mx_bluesky.hyperion.parameters.rotation import RotationScan from ....conftest import raw_params_from_file +@pytest.fixture +def load_centre_collect_params_with_panda(): + params = raw_params_from_file( + "tests/test_data/parameter_json_files/good_test_load_centre_collect_params.json" + ) + params["robot_load_then_centre"]["features"]["use_panda_for_gridscan"] = True + return LoadCentreCollect(**params) + + @pytest.fixture def minimal_3d_gridscan_params(): return { @@ -36,6 +55,22 @@ def minimal_3d_gridscan_params(): } +def get_empty_grid_parameters() -> GridParamUpdate: + return { + "x_start_um": 1, + "y_start_um": 1, + "y2_start_um": 1, + "z_start_um": 1, + "z2_start_um": 1, + "x_steps": 1, + "y_steps": 1, + "z_steps": 1, + "x_step_size_um": 1, + "y_step_size_um": 1, + "z_step_size_um": 1, + } + + def test_minimal_3d_gridscan_params(minimal_3d_gridscan_params): test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) assert {"sam_x", "sam_y", "sam_z"} == set(test_params.scan_points.keys()) @@ -154,3 +189,23 @@ def test_gpu_enabled_if_use_gpu_or_compare_gpu_enabled(_, minimal_3d_gridscan_pa } grid_scan = HyperionThreeDGridScan(**minimal_3d_gridscan_params) assert grid_scan.detector_params.enable_dev_shm + + +def test_hyperion_params_correctly_carried_through_UDC_parameter_models( + load_centre_collect_params_with_panda: LoadCentreCollect, +): + robot_load_then_centre_params = ( + load_centre_collect_params_with_panda.robot_load_then_centre + ) + pin_tip_then_xrc_params = ( + robot_load_then_centre_params.pin_centre_then_xray_centre_params() + ) + grid_detect_then_xrc_params = create_parameters_for_grid_detection( + pin_tip_then_xrc_params + ) + flyscan_xrc_params = create_parameters_for_flyscan_xray_centre( + grid_detect_then_xrc_params, get_empty_grid_parameters() + ) + assert flyscan_xrc_params.panda_runup_distance_mm == 0.17 + assert flyscan_xrc_params.features.use_panda_for_gridscan + assert flyscan_xrc_params.features.compare_cpu_and_gpu_zocalo From e24002346cca6ac68625251a192fa23f1976ae6e Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Tue, 14 Jan 2025 11:36:52 +0000 Subject: [PATCH 03/10] Forgot to commit this file --- src/mx_bluesky/hyperion/parameters/load_centre_collect.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py index cdc74ce4d..fe94409c6 100644 --- a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py +++ b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py @@ -8,6 +8,7 @@ WithSample, WithVisit, ) +from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures from mx_bluesky.hyperion.parameters.robot_load import ( HyperionRobotLoadThenCentre, ) @@ -23,7 +24,11 @@ def construct_from_values(parent_context: dict, child_dict: dict, t: type[T]) -> class LoadCentreCollect( - MxBlueskyParameters, WithVisit, WithSample, WithCentreSelection + MxBlueskyParameters, + WithVisit, + WithSample, + WithCentreSelection, + WithHyperionUDCFeatures, ): """Experiment parameters to perform the combined robot load, pin-tip centre and rotation scan operations.""" From 8648ef4d6e9958cd8020e56d3d4e9705623aa6e6 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Tue, 14 Jan 2025 12:06:45 +0000 Subject: [PATCH 04/10] Revert accidental changes to experiemnt registry --- .../hyperion/experiment_plans/experiment_registry.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py index 52d32ed6a..659dc5e12 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py +++ b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py @@ -24,6 +24,7 @@ ) from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect +from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan, RotationScan @@ -43,8 +44,8 @@ class ExperimentRegistryEntry(TypedDict): | RotationScan | MultiRotationScan | PinTipCentreThenXrayCentre - | HyperionThreeDGridScan | LoadCentreCollect + | HyperionRobotLoadThenCentre ] callbacks_factory: CallbacksFactory @@ -72,7 +73,7 @@ class ExperimentRegistryEntry(TypedDict): }, "robot_load_then_centre": { "setup": robot_load_then_centre_plan.create_devices, - "param_type": HyperionThreeDGridScan, + "param_type": HyperionRobotLoadThenCentre, "callbacks_factory": create_robot_load_and_centre_callbacks, }, "multi_rotation_scan": { From 5bf4f72c23b1fab6dd228d3e107b31abc75c65ef Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Wed, 15 Jan 2025 16:51:18 +0000 Subject: [PATCH 05/10] Refactor parameters --- .../callbacks/xray_centre/ispyb_callback.py | 9 ++- .../callbacks/xray_centre/nexus_callback.py | 13 ++-- .../common/parameters/components.py | 1 + src/mx_bluesky/common/parameters/gridscan.py | 51 ++------------ .../common/parameters/robot_load.py | 30 -------- .../change_aperture_then_move_plan.py | 4 +- .../experiment_plans/experiment_registry.py | 20 +++--- .../flyscan_xray_centre_plan.py | 24 +++---- .../grid_detect_then_xray_centre_plan.py | 8 +-- .../pin_centre_then_xray_centre_plan.py | 8 +-- .../robot_load_and_change_energy.py | 2 +- .../robot_load_then_centre_plan.py | 14 ++-- .../callbacks/__main__.py | 10 ++- .../callbacks/common/callback_util.py | 22 ++++-- .../hyperion/parameters/gridscan.py | 61 +++++++++++++--- .../parameters/load_centre_collect.py | 8 +-- .../hyperion/parameters/robot_load.py | 69 ++++++++++++++++--- tests/conftest.py | 14 ++-- .../experiment_plans/test_fgs_plan.py | 16 ++--- .../callbacks/test_external_callbacks.py | 4 +- .../hyperion/external_interaction/conftest.py | 4 +- .../test_ispyb_dev_connection.py | 8 ++- .../test_load_centre_collect_full_plan.py | 21 ++++-- .../test_zocalo_system.py | 4 +- .../callbacks/ispyb/conftest.py | 4 +- .../xray_centre/test_ispyb_callback.py | 17 +++-- .../xray_centre/test_ispyb_handler.py | 29 +++++--- .../xray_centre/test_ispyb_mapping.py | 6 +- .../xray_centre/test_nexus_handler.py | 21 ++++-- .../test_manipulate_sample.py | 6 +- .../hyperion/experiment_plans/conftest.py | 4 +- .../test_change_aperture_then_move_plan.py | 4 +- .../test_flyscan_xray_centre_plan.py | 56 ++++++++------- .../test_grid_detect_then_xray_centre_plan.py | 8 +-- .../test_grid_detection_plan.py | 11 +-- .../test_load_centre_collect_full_plan.py | 2 +- .../test_pin_centre_then_xray_centre_plan.py | 6 +- .../test_robot_load_and_change_energy.py | 2 +- .../test_robot_load_then_centre.py | 38 +++++----- .../hyperion/external_interaction/conftest.py | 4 +- .../nexus/test_write_nexus.py | 24 ++++--- .../parameters/test_parameter_model.py | 38 +++++----- tests/unit_tests/hyperion/test_main_system.py | 6 +- 43 files changed, 406 insertions(+), 305 deletions(-) delete mode 100644 src/mx_bluesky/common/parameters/robot_load.py diff --git a/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py b/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py index 82d79af25..c0a0d5d7d 100644 --- a/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +++ b/src/mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py @@ -2,7 +2,7 @@ from collections.abc import Callable, Sequence from time import time -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, TypeVar import numpy as np from bluesky import preprocessors as bpp @@ -64,6 +64,9 @@ def ispyb_activation_wrapper(plan_generator: MsgGenerator, parameters): ) +T = TypeVar("T", bound="GridCommon") + + class GridscanISPyBCallback(BaseISPyBCallback): """Callback class to handle the deposition of experiment parameters into the ISPyB database. Listens for 'event' and 'descriptor' documents. Creates the ISpyB entry on @@ -81,12 +84,14 @@ class GridscanISPyBCallback(BaseISPyBCallback): def __init__( self, + param_type: type[T], *, emit: Callable[..., Any] | None = None, ) -> None: super().__init__(emit=emit) self.ispyb: StoreInIspyb self.ispyb_ids: IspybIds = IspybIds() + self.param_type = param_type self._start_of_fgs_uid: str | None = None self._processing_start_time: float | None = None @@ -101,7 +106,7 @@ def activity_gated_start(self, doc: RunStart): ) mx_bluesky_parameters = doc.get("mx_bluesky_parameters") assert isinstance(mx_bluesky_parameters, str) - self.params = GridCommon.model_validate_json(mx_bluesky_parameters) + self.params = self.param_type.model_validate_json(mx_bluesky_parameters) self.ispyb = StoreInIspyb(self.ispyb_config) data_collection_group_info = populate_data_collection_group(self.params) 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 9c5e8cce0..968e0d439 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 @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, TypeVar from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import ( PlanReactiveCallback, @@ -11,12 +11,16 @@ ) from mx_bluesky.common.external_interaction.nexus.write_nexus import NexusWriter from mx_bluesky.common.parameters.constants import DocDescriptorNames, PlanNameConstants -from mx_bluesky.common.parameters.gridscan import ThreeDGridScan +from mx_bluesky.common.parameters.gridscan import ( + SpecifiedThreeDGridScan, +) from mx_bluesky.common.utils.log import NEXUS_LOGGER if TYPE_CHECKING: from event_model.documents import Event, EventDescriptor, RunStart +T = TypeVar("T", bound="SpecifiedThreeDGridScan") + class GridscanNexusFileCallback(PlanReactiveCallback): """Callback class to handle the creation of Nexus files based on experiment \ @@ -35,8 +39,9 @@ class GridscanNexusFileCallback(PlanReactiveCallback): See: https://blueskyproject.io/bluesky/callbacks.html#ways-to-invoke-callbacks """ - def __init__(self) -> None: + def __init__(self, param_type: type[T]) -> None: super().__init__(NEXUS_LOGGER) + self.param_type = param_type self.run_start_uid: str | None = None self.nexus_writer_1: NexusWriter | None = None self.nexus_writer_2: NexusWriter | None = None @@ -50,7 +55,7 @@ def activity_gated_start(self, doc: RunStart): NEXUS_LOGGER.info( f"Nexus writer received start document with experiment parameters {mx_bluesky_parameters}" ) - parameters = ThreeDGridScan.model_validate_json(mx_bluesky_parameters) + parameters = self.param_type.model_validate_json(mx_bluesky_parameters) d_size = parameters.detector_params.detector_size_constants.det_size_pixels grid_n_img_1 = parameters.scan_indices[1] grid_n_img_2 = parameters.num_images - grid_n_img_1 diff --git a/src/mx_bluesky/common/parameters/components.py b/src/mx_bluesky/common/parameters/components.py index 8e9da1ae0..b0dbd3b6e 100644 --- a/src/mx_bluesky/common/parameters/components.py +++ b/src/mx_bluesky/common/parameters/components.py @@ -151,6 +151,7 @@ class DiffractionExperiment( transmission_frac: float = Field(default=0.1) ispyb_experiment_type: IspybExperimentType storage_directory: str + use_roi_mode: bool = Field(default=GridscanParamConstants.USE_ROI) @model_validator(mode="before") @classmethod diff --git a/src/mx_bluesky/common/parameters/gridscan.py b/src/mx_bluesky/common/parameters/gridscan.py index 4f3aed4b7..13f72d0ab 100644 --- a/src/mx_bluesky/common/parameters/gridscan.py +++ b/src/mx_bluesky/common/parameters/gridscan.py @@ -1,11 +1,6 @@ from __future__ import annotations -import os - from dodal.devices.aperturescatterguard import ApertureValue -from dodal.devices.detector import ( - DetectorParams, -) from dodal.devices.fast_grid_scan import ( ZebraGridScanParams, ) @@ -23,73 +18,37 @@ XyzStarts, ) from mx_bluesky.common.parameters.constants import ( - DetectorParamConstants, GridscanParamConstants, HardwareConstants, ) +"""Parameter models in this file are abstract. They should be inherited by a top-level model""" + class GridCommon( DiffractionExperimentWithSample, OptionalGonioAngleStarts, ): + """Parameters used in every MX diffraction experiment using grids. This model should be used by plans which have no knowledge of the grid specifications - i.e before automatic grid detection has completed""" + grid_width_um: float = Field(default=GridscanParamConstants.WIDTH_UM) exposure_time_s: float = Field(default=GridscanParamConstants.EXPOSURE_TIME_S) - use_roi_mode: bool = Field(default=GridscanParamConstants.USE_ROI) ispyb_experiment_type: IspybExperimentType = Field( default=IspybExperimentType.GRIDSCAN_3D ) selected_aperture: ApertureValue | None = Field(default=ApertureValue.SMALL) - @property - def detector_params(self): - self.det_dist_to_beam_converter_path = ( - self.det_dist_to_beam_converter_path - or DetectorParamConstants.BEAM_XY_LUT_PATH - ) - optional_args = {} - if self.run_number: - optional_args["run_number"] = self.run_number - assert self.detector_distance_mm is not None, ( - "Detector distance must be filled before generating DetectorParams" - ) - os.makedirs(self.storage_directory, exist_ok=True) - return DetectorParams( - detector_size_constants=DetectorParamConstants.DETECTOR, - expected_energy_ev=self.demand_energy_ev, - exposure_time=self.exposure_time_s, - directory=self.storage_directory, - prefix=self.file_name, - detector_distance=self.detector_distance_mm, - omega_start=self.omega_start_deg or 0, - omega_increment=0, - num_images_per_trigger=1, - num_triggers=self.num_images, - use_roi_mode=self.use_roi_mode, - det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path, - trigger_mode=self.trigger_mode, - **optional_args, - ) - tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM) -class GridScanWithEdgeDetect(GridCommon): - box_size_um: float = Field(default=GridscanParamConstants.BOX_WIDTH_UM) - - -class PinTipCentreThenXrayCentre(GridCommon): - tip_offset_um: float = 0 - - class SpecifiedGrid(XyzStarts, WithScan): """A specified grid is one which has defined values for the start position, grid and box sizes, etc., as opposed to parameters for a plan which will create those parameters at some point (e.g. through optical pin detection).""" -class ThreeDGridScan( +class SpecifiedThreeDGridScan( GridCommon, SpecifiedGrid, SplitScan, diff --git a/src/mx_bluesky/common/parameters/robot_load.py b/src/mx_bluesky/common/parameters/robot_load.py deleted file mode 100644 index dea7fa917..000000000 --- a/src/mx_bluesky/common/parameters/robot_load.py +++ /dev/null @@ -1,30 +0,0 @@ -from pydantic import Field - -from mx_bluesky.common.parameters.components import ( - MxBlueskyParameters, - WithOptionalEnergyChange, - WithSample, - WithSnapshot, - WithVisit, -) -from mx_bluesky.common.parameters.constants import HardwareConstants -from mx_bluesky.common.parameters.gridscan import GridCommon, PinTipCentreThenXrayCentre - - -class RobotLoadAndEnergyChange( - MxBlueskyParameters, WithSample, WithSnapshot, WithOptionalEnergyChange, WithVisit -): - thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) - - -class RobotLoadThenCentre(GridCommon): - thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) - - def robot_load_params(self): - my_params = self.model_dump() - return RobotLoadAndEnergyChange(**my_params) - - def pin_centre_then_xray_centre_params(self): - my_params = self.model_dump() - del my_params["thawing_time"] - return PinTipCentreThenXrayCentre(**my_params) diff --git a/src/mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py b/src/mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py index 930f4428b..6ccf4636d 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py @@ -8,14 +8,14 @@ from mx_bluesky.common.utils.tracing import TRACER from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_x_y_z from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan def change_aperture_then_move_to_xtal( best_hit: XRayCentreResult, smargon: Smargon, aperture_scatterguard: ApertureScatterguard, - parameters: HyperionThreeDGridScan | None = None, + parameters: HyperionSpecifiedThreeDGridScan | None = None, ): """For the given x-ray centring result, * Change the aperture so that the beam size is comparable to the crystal size diff --git a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py index 659dc5e12..54503feb7 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py +++ b/src/mx_bluesky/hyperion/experiment_plans/experiment_registry.py @@ -5,10 +5,6 @@ import mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan as flyscan_xray_centre_plan import mx_bluesky.hyperion.experiment_plans.rotation_scan_plan as rotation_scan_plan -from mx_bluesky.common.parameters.gridscan import ( - GridScanWithEdgeDetect, - PinTipCentreThenXrayCentre, -) from mx_bluesky.hyperion.experiment_plans import ( grid_detect_then_xray_centre_plan, load_centre_collect_full_plan, @@ -22,9 +18,13 @@ create_robot_load_and_centre_callbacks, create_rotation_callbacks, ) -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import ( + GridScanWithEdgeDetect, + HyperionSpecifiedThreeDGridScan, + PinTipCentreThenXrayCentre, +) from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect -from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan, RotationScan @@ -39,13 +39,13 @@ def do_nothing(): class ExperimentRegistryEntry(TypedDict): setup: Callable param_type: type[ - HyperionThreeDGridScan + HyperionSpecifiedThreeDGridScan | GridScanWithEdgeDetect | RotationScan | MultiRotationScan | PinTipCentreThenXrayCentre | LoadCentreCollect - | HyperionRobotLoadThenCentre + | RobotLoadThenCentre ] callbacks_factory: CallbacksFactory @@ -53,7 +53,7 @@ class ExperimentRegistryEntry(TypedDict): PLAN_REGISTRY: dict[str, ExperimentRegistryEntry] = { "flyscan_xray_centre": { "setup": flyscan_xray_centre_plan.create_devices, - "param_type": HyperionThreeDGridScan, + "param_type": HyperionSpecifiedThreeDGridScan, "callbacks_factory": create_gridscan_callbacks, }, "grid_detect_then_xray_centre": { @@ -73,7 +73,7 @@ class ExperimentRegistryEntry(TypedDict): }, "robot_load_then_centre": { "setup": robot_load_then_centre_plan.create_devices, - "param_type": HyperionRobotLoadThenCentre, + "param_type": RobotLoadThenCentre, "callbacks_factory": create_robot_load_and_centre_callbacks, }, "multi_rotation_scan": { diff --git a/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py index cdd845906..daf8a9126 100755 --- a/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py @@ -79,7 +79,7 @@ ) from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from mx_bluesky.hyperion.utils.context import device_composite_from_context ZOCALO_MIN_TOTAL_COUNT_THRESHOLD = 3 @@ -133,7 +133,7 @@ def create_devices(context: BlueskyContext) -> FlyScanXRayCentreComposite: def flyscan_xray_centre_no_move( - composite: FlyScanXRayCentreComposite, parameters: HyperionThreeDGridScan + composite: FlyScanXRayCentreComposite, parameters: HyperionSpecifiedThreeDGridScan ) -> MsgGenerator: """Perform a flyscan and determine the centres of interest""" parameters.features.update_self_from_server() @@ -161,7 +161,7 @@ def flyscan_xray_centre_no_move( ) def run_gridscan_and_fetch_and_tidy( fgs_composite: FlyScanXRayCentreComposite, - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, feature_controlled: _FeatureControlled, ) -> MsgGenerator: yield from run_gridscan_and_fetch_results( @@ -175,7 +175,7 @@ def run_gridscan_and_fetch_and_tidy( def flyscan_xray_centre( composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, ) -> MsgGenerator: """Create the plan to run the grid scan based on provided parameters. @@ -183,7 +183,7 @@ def flyscan_xray_centre( at any point in it. Args: - parameters (ThreeDGridScan): The parameters to run the scan. + parameters (SpecifiedThreeDGridScan): The parameters to run the scan. Returns: Generator: The plan for the gridscan @@ -214,7 +214,7 @@ def flyscan_and_fetch_results() -> MsgGenerator: @bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_AND_MOVE}) def run_gridscan_and_fetch_results( fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, feature_controlled: _FeatureControlled, ) -> MsgGenerator: """A multi-run plan which runs a gridscan, gets the results from zocalo @@ -269,7 +269,7 @@ def run_gridscan_and_fetch_results( def _xrc_result_in_boxes_to_result_in_mm( - xrc_result: XrcResult, parameters: HyperionThreeDGridScan + xrc_result: XrcResult, parameters: HyperionSpecifiedThreeDGridScan ) -> XRayCentreResult: fgs_params = parameters.FGS_params xray_centre = fgs_params.grid_position_to_motor_position( @@ -311,7 +311,7 @@ def empty_plan(): @bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_MAIN}) def run_gridscan( fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, feature_controlled: _FeatureControlled, md={ # noqa "plan_name": CONST.PLAN.GRIDSCAN_MAIN, @@ -391,7 +391,7 @@ class _ExtraSetup(Protocol): def __call__( self, fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, ) -> MsgGenerator: ... setup_trigger: _ExtraSetup @@ -402,7 +402,7 @@ def __call__( def _get_feature_controlled( fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, ): if parameters.features.use_panda_for_gridscan: return _FeatureControlled( @@ -451,7 +451,7 @@ def _panda_tidy(fgs_composite: FlyScanXRayCentreComposite): def _zebra_triggering_setup( fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, ): yield from setup_zebra_for_gridscan( fgs_composite.zebra, fgs_composite.sample_shutter, wait=True @@ -460,7 +460,7 @@ def _zebra_triggering_setup( def _panda_triggering_setup( fgs_composite: FlyScanXRayCentreComposite, - parameters: HyperionThreeDGridScan, + parameters: HyperionSpecifiedThreeDGridScan, ): LOGGER.info("Setting up Panda for flyscan") diff --git a/src/mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py index 0077af952..a149fe45c 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py @@ -39,7 +39,6 @@ ispyb_activation_wrapper, ) from mx_bluesky.common.parameters.constants import OavConstants -from mx_bluesky.common.parameters.gridscan import GridScanWithEdgeDetect from mx_bluesky.common.utils.log import LOGGER from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import ( move_aperture_if_required, @@ -63,7 +62,8 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.gridscan import ( - HyperionThreeDGridScan, + GridScanWithEdgeDetect, + HyperionSpecifiedThreeDGridScan, ) from mx_bluesky.hyperion.utils.context import device_composite_from_context @@ -103,10 +103,10 @@ def create_devices(context: BlueskyContext) -> GridDetectThenXRayCentreComposite def create_parameters_for_flyscan_xray_centre( grid_scan_with_edge_params: GridScanWithEdgeDetect, grid_parameters: GridParamUpdate, -) -> HyperionThreeDGridScan: +) -> HyperionSpecifiedThreeDGridScan: params_json = grid_scan_with_edge_params.model_dump() params_json.update(grid_parameters) - flyscan_xray_centre_parameters = HyperionThreeDGridScan(**params_json) + flyscan_xray_centre_parameters = HyperionSpecifiedThreeDGridScan(**params_json) LOGGER.info(f"Parameters for FGS: {flyscan_xray_centre_parameters}") return flyscan_xray_centre_parameters 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 6306f7886..487d2ec65 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 @@ -12,10 +12,6 @@ ispyb_activation_wrapper, ) from mx_bluesky.common.parameters.constants import OavConstants -from mx_bluesky.common.parameters.gridscan import ( - GridScanWithEdgeDetect, - PinTipCentreThenXrayCentre, -) from mx_bluesky.common.utils.log import LOGGER from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_phi_chi_omega from mx_bluesky.hyperion.device_setup_plans.utils import ( @@ -39,6 +35,10 @@ pin_tip_centre_plan, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.gridscan import ( + GridScanWithEdgeDetect, + PinTipCentreThenXrayCentre, +) from mx_bluesky.hyperion.utils.context import device_composite_from_context diff --git a/src/mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py b/src/mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py index bcc206ea6..ccd3c9ff0 100644 --- a/src/mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +++ b/src/mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py @@ -24,13 +24,13 @@ from dodal.devices.xbpm_feedback import XBPMFeedback from dodal.plan_stubs.motor_utils import MoveTooLarge, home_and_reset_wrapper -from mx_bluesky.common.parameters.robot_load import RobotLoadAndEnergyChange from mx_bluesky.common.utils.log import LOGGER from mx_bluesky.hyperion.experiment_plans.set_energy_plan import ( SetEnergyComposite, set_energy_plan, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True}) 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 c4a1c9864..12ca0fb04 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 @@ -63,7 +63,7 @@ set_energy_plan, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True}) @@ -113,23 +113,23 @@ def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite: def _flyscan_plan_from_robot_load_params( composite: RobotLoadThenCentreComposite, - params: HyperionRobotLoadThenCentre, + params: RobotLoadThenCentre, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from pin_centre_then_flyscan_plan( cast(GridDetectThenXRayCentreComposite, composite), - params.pin_centre_then_xray_centre_params(), + params.pin_centre_then_xray_centre_params, ) def _robot_load_then_flyscan_plan( composite: RobotLoadThenCentreComposite, - params: HyperionRobotLoadThenCentre, + params: RobotLoadThenCentre, oav_config_file: str = OavConstants.OAV_CONFIG_JSON, ): yield from robot_load_and_change_energy_plan( cast(RobotLoadAndEnergyChangeComposite, composite), - params.robot_load_params(), + params.robot_load_params, ) yield from _flyscan_plan_from_robot_load_params(composite, params, oav_config_file) @@ -137,7 +137,7 @@ def _robot_load_then_flyscan_plan( def robot_load_then_centre( composite: RobotLoadThenCentreComposite, - parameters: HyperionRobotLoadThenCentre, + parameters: RobotLoadThenCentre, ) -> MsgGenerator: """Perform pin-tip detection followed by a flyscan to determine centres of interest. Performs a robot load if necessary. Centre on the best diffracting centre. @@ -158,7 +158,7 @@ def robot_load_then_centre( def robot_load_then_xray_centre( composite: RobotLoadThenCentreComposite, - parameters: HyperionRobotLoadThenCentre, + parameters: RobotLoadThenCentre, ) -> MsgGenerator: """Perform pin-tip detection followed by a flyscan to determine centres of interest. Performs a robot load if necessary.""" diff --git a/src/mx_bluesky/hyperion/external_interaction/callbacks/__main__.py b/src/mx_bluesky/hyperion/external_interaction/callbacks/__main__.py index 02d2ab1af..8f2bb3b5a 100644 --- a/src/mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +++ b/src/mx_bluesky/hyperion/external_interaction/callbacks/__main__.py @@ -39,6 +39,10 @@ ) from mx_bluesky.hyperion.parameters.cli import parse_callback_dev_mode_arg from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + HyperionSpecifiedThreeDGridScan, +) LIVENESS_POLL_SECONDS = 1 ERROR_LOG_BUFFER_LINES = 5000 @@ -47,8 +51,10 @@ def setup_callbacks(): zocalo = ZocaloCallback() return [ - GridscanNexusFileCallback(), - GridscanISPyBCallback(emit=zocalo), + GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan), + GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams, emit=zocalo + ), RotationNexusFileCallback(), RotationISPyBCallback(emit=zocalo), LogUidTaggingCallback(), diff --git a/src/mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py b/src/mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py index 63595b49e..bf8e02501 100644 --- a/src/mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +++ b/src/mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py @@ -23,6 +23,10 @@ from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import ( SampleHandlingCallback, ) +from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + HyperionSpecifiedThreeDGridScan, +) CallbacksFactory = Callable[[], tuple[CallbackBase, ...]] @@ -31,8 +35,10 @@ def create_robot_load_and_centre_callbacks() -> tuple[ GridscanNexusFileCallback, GridscanISPyBCallback, RobotLoadISPyBCallback ]: return ( - GridscanNexusFileCallback(), - GridscanISPyBCallback(emit=ZocaloCallback()), + GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan), + GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback() + ), RobotLoadISPyBCallback(), ) @@ -41,8 +47,10 @@ def create_gridscan_callbacks() -> tuple[ GridscanNexusFileCallback, GridscanISPyBCallback ]: return ( - GridscanNexusFileCallback(), - GridscanISPyBCallback(emit=ZocaloCallback()), + GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan), + GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback() + ), ) @@ -61,8 +69,10 @@ def create_load_centre_collect_callbacks() -> tuple[ SampleHandlingCallback, ]: return ( - GridscanNexusFileCallback(), - GridscanISPyBCallback(emit=ZocaloCallback()), + GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan), + GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback() + ), RobotLoadISPyBCallback(), RotationNexusFileCallback(), RotationISPyBCallback(emit=ZocaloCallback()), diff --git a/src/mx_bluesky/hyperion/parameters/gridscan.py b/src/mx_bluesky/hyperion/parameters/gridscan.py index 1b1ea6827..97a3240cf 100644 --- a/src/mx_bluesky/hyperion/parameters/gridscan.py +++ b/src/mx_bluesky/hyperion/parameters/gridscan.py @@ -7,18 +7,55 @@ PandAGridScanParams, ZebraGridScanParams, ) +from pydantic import Field +from mx_bluesky.common.parameters.constants import GridscanParamConstants from mx_bluesky.common.parameters.gridscan import ( - GridScanWithEdgeDetect, - PinTipCentreThenXrayCentre, - ThreeDGridScan, + GridCommon, + SpecifiedThreeDGridScan, ) from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures from mx_bluesky.hyperion.parameters.constants import CONST, I03Constants -class HyperionThreeDGridScan(ThreeDGridScan, WithHyperionUDCFeatures): - """Hyperion's 3D grid scan varies from the common class due to: optionally using a PandA, optionally using dev_shm for GPU analysis, and using a config server for features""" +class GridCommonWithHyperionDetectorParams(GridCommon, WithHyperionUDCFeatures): + """Used by models which require detector parameters but have no specifications of the grid""" + + # These detector params only exist so that we can properly select enable_dev_shm. Remove in + # https://github.com/DiamondLightSource/hyperion/issues/1395""" + @property + def detector_params(self): + self.det_dist_to_beam_converter_path = ( + self.det_dist_to_beam_converter_path + or CONST.PARAM.DETECTOR.BEAM_XY_LUT_PATH + ) + optional_args = {} + if self.run_number: + optional_args["run_number"] = self.run_number + assert self.detector_distance_mm is not None, ( + "Detector distance must be filled before generating DetectorParams" + ) + return DetectorParams( + detector_size_constants=I03Constants.DETECTOR, + expected_energy_ev=self.demand_energy_ev, + exposure_time=self.exposure_time_s, + directory=self.storage_directory, + prefix=self.file_name, + detector_distance=self.detector_distance_mm, + omega_start=self.omega_start_deg or 0, + omega_increment=0, + num_images_per_trigger=1, + num_triggers=self.num_images, + use_roi_mode=self.use_roi_mode, + det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path, + trigger_mode=self.trigger_mode, + enable_dev_shm=self.features.compare_cpu_and_gpu_zocalo, + **optional_args, + ) + + +class HyperionSpecifiedThreeDGridScan(SpecifiedThreeDGridScan, WithHyperionUDCFeatures): + """Hyperion's 3D grid scan deviates from the common class due to: optionally using a PandA, optionally using dev_shm for GPU analysis, and using a config server for features""" # These detector params only exist so that we can properly select enable_dev_shm. Remove in # https://github.com/DiamondLightSource/hyperion/issues/1395""" @@ -100,11 +137,13 @@ def panda_FGS_params(self) -> PandAGridScanParams: class OddYStepsException(Exception): ... -class HyperionPinTipCentreThenXrayCentre( - PinTipCentreThenXrayCentre, WithHyperionUDCFeatures -): ... +class PinTipCentreThenXrayCentre( + GridCommonWithHyperionDetectorParams, WithHyperionUDCFeatures +): + tip_offset_um: float = 0 -class HyperionGridScanWithEdgeDetect( - GridScanWithEdgeDetect, WithHyperionUDCFeatures -): ... +class GridScanWithEdgeDetect( + GridCommonWithHyperionDetectorParams, WithHyperionUDCFeatures +): + box_size_um: float = Field(default=GridscanParamConstants.BOX_WIDTH_UM) diff --git a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py index fe94409c6..7874ee82d 100644 --- a/src/mx_bluesky/hyperion/parameters/load_centre_collect.py +++ b/src/mx_bluesky/hyperion/parameters/load_centre_collect.py @@ -10,7 +10,7 @@ ) from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures from mx_bluesky.hyperion.parameters.robot_load import ( - HyperionRobotLoadThenCentre, + RobotLoadThenCentre, ) from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan @@ -33,7 +33,7 @@ class LoadCentreCollect( """Experiment parameters to perform the combined robot load, pin-tip centre and rotation scan operations.""" - robot_load_then_centre: HyperionRobotLoadThenCentre + robot_load_then_centre: RobotLoadThenCentre multi_rotation_scan: MultiRotationScan @model_validator(mode="before") @@ -41,7 +41,7 @@ class LoadCentreCollect( def validate_model(cls, values): allowed_keys = ( LoadCentreCollect.model_fields.keys() - | HyperionRobotLoadThenCentre.model_fields.keys() + | RobotLoadThenCentre.model_fields.keys() | MultiRotationScan.model_fields.keys() ) @@ -71,7 +71,7 @@ def validate_model(cls, values): ) new_robot_load_then_centre_params = construct_from_values( - values, values["robot_load_then_centre"], HyperionRobotLoadThenCentre + values, values["robot_load_then_centre"], RobotLoadThenCentre ) new_multi_rotation_scan_params = construct_from_values( values, values["multi_rotation_scan"], MultiRotationScan diff --git a/src/mx_bluesky/hyperion/parameters/robot_load.py b/src/mx_bluesky/hyperion/parameters/robot_load.py index 0e97568b6..c39030521 100644 --- a/src/mx_bluesky/hyperion/parameters/robot_load.py +++ b/src/mx_bluesky/hyperion/parameters/robot_load.py @@ -1,23 +1,74 @@ +from dodal.devices.detector.detector import DetectorParams from pydantic import Field -from mx_bluesky.common.parameters.constants import HardwareConstants -from mx_bluesky.common.parameters.robot_load import ( - RobotLoadAndEnergyChange, - RobotLoadThenCentre, +from mx_bluesky.common.parameters.components import ( + MxBlueskyParameters, + WithOptionalEnergyChange, + WithSample, + WithSnapshot, + WithVisit, +) +from mx_bluesky.common.parameters.constants import ( + HardwareConstants, ) from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures -from mx_bluesky.hyperion.parameters.gridscan import HyperionPinTipCentreThenXrayCentre +from mx_bluesky.hyperion.parameters.constants import CONST, I03Constants +from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + PinTipCentreThenXrayCentre, +) + + +class RobotLoadAndEnergyChange( + MxBlueskyParameters, WithSample, WithSnapshot, WithOptionalEnergyChange, WithVisit +): + thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) -class HyperionRobotLoadThenCentre(RobotLoadThenCentre, WithHyperionUDCFeatures): +class RobotLoadThenCentre( + GridCommonWithHyperionDetectorParams, WithHyperionUDCFeatures +): thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM) - def robot_load_params(self): + # These detector params only exist so that we can properly select enable_dev_shm. Remove in + # https://github.com/DiamondLightSource/hyperion/issues/1395""" + @property + def detector_params(self) -> DetectorParams: + self.det_dist_to_beam_converter_path = ( + self.det_dist_to_beam_converter_path + or CONST.PARAM.DETECTOR.BEAM_XY_LUT_PATH + ) + optional_args = {} + if self.run_number: + optional_args["run_number"] = self.run_number + assert self.detector_distance_mm is not None, ( + "Detector distance must be filled before generating DetectorParams" + ) + return DetectorParams( + detector_size_constants=I03Constants.DETECTOR, + expected_energy_ev=self.demand_energy_ev, + exposure_time=self.exposure_time_s, + directory=self.storage_directory, + prefix=self.file_name, + detector_distance=self.detector_distance_mm, + omega_start=self.omega_start_deg or 0, + omega_increment=0, + num_images_per_trigger=1, + num_triggers=self.num_images, + use_roi_mode=self.use_roi_mode, + det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path, + trigger_mode=self.trigger_mode, + enable_dev_shm=self.features.compare_cpu_and_gpu_zocalo, + ) + + @property + def robot_load_params(self) -> RobotLoadAndEnergyChange: my_params = self.model_dump() return RobotLoadAndEnergyChange(**my_params) - def pin_centre_then_xray_centre_params(self): + @property + def pin_centre_then_xray_centre_params(self) -> PinTipCentreThenXrayCentre: my_params = self.model_dump() del my_params["thawing_time"] - return HyperionPinTipCentreThenXrayCentre(**my_params) + return PinTipCentreThenXrayCentre(**my_params) diff --git a/tests/conftest.py b/tests/conftest.py index 151e93624..f08f070e1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -83,7 +83,6 @@ PlanNameConstants, TriggerConstants, ) -from mx_bluesky.common.parameters.gridscan import GridScanWithEdgeDetect from mx_bluesky.common.utils.log import ( ALL_LOGGERS, ISPYB_ZOCALO_CALLBACK_LOGGER, @@ -100,7 +99,8 @@ ) from mx_bluesky.hyperion.external_interaction.config_server import HyperionFeatureFlags from mx_bluesky.hyperion.parameters.gridscan import ( - HyperionThreeDGridScan, + GridScanWithEdgeDetect, + HyperionSpecifiedThreeDGridScan, ) from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan, RotationScan @@ -247,7 +247,7 @@ def beamline_parameters(): @pytest.fixture def test_fgs_params(): - return HyperionThreeDGridScan( + return HyperionSpecifiedThreeDGridScan( **raw_params_from_file( "tests/test_data/parameter_json_files/good_test_parameters.json" ) @@ -255,7 +255,7 @@ def test_fgs_params(): @pytest.fixture -def test_panda_fgs_params(test_fgs_params: HyperionThreeDGridScan): +def test_panda_fgs_params(test_fgs_params: HyperionSpecifiedThreeDGridScan): test_fgs_params.features.use_panda_for_gridscan = True return test_fgs_params @@ -793,7 +793,7 @@ def panda_fast_grid_scan(RE): @pytest.fixture async def fake_fgs_composite( smargon: Smargon, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, RE: RunEngine, done_status, attenuator, @@ -1160,7 +1160,7 @@ class OavGridSnapshotTestEvents: def dummy_params(): - dummy_params = HyperionThreeDGridScan(**default_raw_gridscan_params()) + dummy_params = HyperionSpecifiedThreeDGridScan(**default_raw_gridscan_params()) return dummy_params @@ -1169,7 +1169,7 @@ def dummy_params_2d(): "tests/test_data/parameter_json_files/test_gridscan_param_defaults.json" ) raw_params["z_steps"] = 1 - return HyperionThreeDGridScan(**raw_params) + return HyperionSpecifiedThreeDGridScan(**raw_params) class TestData(OavGridSnapshotTestEvents): diff --git a/tests/system_tests/hyperion/experiment_plans/test_fgs_plan.py b/tests/system_tests/hyperion/experiment_plans/test_fgs_plan.py index 79ed76711..115e05226 100644 --- a/tests/system_tests/hyperion/experiment_plans/test_fgs_plan.py +++ b/tests/system_tests/hyperion/experiment_plans/test_fgs_plan.py @@ -36,7 +36,7 @@ create_gridscan_callbacks, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from tests.conftest import default_raw_gridscan_params from ..external_interaction.conftest import ( # noqa @@ -47,7 +47,7 @@ @pytest.fixture def params(): - params = HyperionThreeDGridScan(**default_raw_gridscan_params()) + params = HyperionSpecifiedThreeDGridScan(**default_raw_gridscan_params()) params.beamline = CONST.SIM.BEAMLINE yield params @@ -151,7 +151,7 @@ def read_run(u, s, g, r, a, f, dcm, ap_sg, sm): async def test_xbpm_feedback_decorator( RE: RunEngine, fxc_composite: FlyScanXRayCentreComposite, - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, callbacks: tuple[GridscanNexusFileCallback, GridscanISPyBCallback], ): # This test is currently kind of more a unit test since we are faking XBPM feedback @@ -189,7 +189,7 @@ def test_full_plan_tidies_at_end( kickoff: MagicMock, wait: MagicMock, fxc_composite: FlyScanXRayCentreComposite, - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, RE: RunEngine, callbacks: tuple[GridscanNexusFileCallback, GridscanISPyBCallback], ): @@ -224,7 +224,7 @@ def test_full_plan_tidies_at_end_when_plan_fails( kickoff: MagicMock, wait: MagicMock, fxc_composite: FlyScanXRayCentreComposite, - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, RE: RunEngine, ): class _Exception(Exception): ... @@ -244,7 +244,7 @@ def test_GIVEN_scan_invalid_WHEN_plan_run_THEN_ispyb_entry_made_but_no_zocalo_en RE: RunEngine, fxc_composite: FlyScanXRayCentreComposite, fetch_comment: Callable, # noqa - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, callbacks: tuple[GridscanNexusFileCallback, GridscanISPyBCallback], ): _, ispyb_cb = callbacks @@ -274,7 +274,7 @@ async def test_complete_xray_centre_plan_with_no_callbacks_falls_back_to_centre( RE: RunEngine, fxc_composite: FlyScanXRayCentreComposite, zocalo_env: None, # noqa - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, callbacks, done_status, ): @@ -308,7 +308,7 @@ async def test_complete_xray_centre_plan_with_callbacks_moves_to_centre( RE: RunEngine, fxc_composite: FlyScanXRayCentreComposite, zocalo_env: None, # noqa - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, callbacks, 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 20b930e9e..4b08a7243 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 @@ -32,7 +32,7 @@ rotation_scan, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from mx_bluesky.hyperion.parameters.rotation import RotationScan from .....conftest import fake_read @@ -139,7 +139,7 @@ def plan(): async def test_external_callbacks_handle_gridscan_ispyb_and_zocalo( RE_with_external_callbacks: RunEngine, zocalo_env, # noqa - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, fgs_composite_for_fake_zocalo: FlyScanXRayCentreComposite, done_status, zocalo_device: ZocaloResults, diff --git a/tests/system_tests/hyperion/external_interaction/conftest.py b/tests/system_tests/hyperion/external_interaction/conftest.py index d630f86d1..f5b876450 100644 --- a/tests/system_tests/hyperion/external_interaction/conftest.py +++ b/tests/system_tests/hyperion/external_interaction/conftest.py @@ -52,7 +52,7 @@ RotationScanComposite, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from ....conftest import fake_read, pin_tip_edge_data, raw_params_from_file @@ -222,7 +222,7 @@ def fetch_blsample(sqlalchemy_sessionmaker) -> Callable[[int], BLSample]: @pytest.fixture def dummy_params(): - dummy_params = HyperionThreeDGridScan( + dummy_params = HyperionSpecifiedThreeDGridScan( **raw_params_from_file( "tests/test_data/parameter_json_files/test_gridscan_param_defaults.json" ) 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 fc2f1479f..88dc311d0 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 @@ -46,7 +46,7 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.gridscan import ( - HyperionThreeDGridScan, + HyperionSpecifiedThreeDGridScan, ) from mx_bluesky.hyperion.parameters.rotation import RotationScan @@ -125,7 +125,7 @@ def grid_detect_then_xray_centre_parameters(): def scan_xy_data_info_for_update( data_collection_group_id, - dummy_params: HyperionThreeDGridScan, + dummy_params: HyperionSpecifiedThreeDGridScan, scan_data_info_for_begin, ): scan_data_info_for_update = deepcopy(scan_data_info_for_begin) @@ -153,7 +153,9 @@ def scan_xy_data_info_for_update( def scan_data_infos_for_update_3d( - ispyb_ids, scan_xy_data_info_for_update, dummy_params: HyperionThreeDGridScan + ispyb_ids, + scan_xy_data_info_for_update, + dummy_params: HyperionSpecifiedThreeDGridScan, ): xz_data_collection_info = populate_xz_data_collection_info( dummy_params.detector_params diff --git a/tests/system_tests/hyperion/external_interaction/test_load_centre_collect_full_plan.py b/tests/system_tests/hyperion/external_interaction/test_load_centre_collect_full_plan.py index be5a0697a..7ead04bcd 100644 --- a/tests/system_tests/hyperion/external_interaction/test_load_centre_collect_full_plan.py +++ b/tests/system_tests/hyperion/external_interaction/test_load_centre_collect_full_plan.py @@ -37,6 +37,7 @@ SampleHandlingCallback, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.gridscan import GridCommonWithHyperionDetectorParams from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect from ...conftest import ( @@ -221,7 +222,9 @@ def test_execute_load_centre_collect_full( fetch_datacollection_ids_for_group_id: Callable[..., Any], fetch_blsample: Callable[[int], BLSample], ): - ispyb_gridscan_cb = GridscanISPyBCallback() + ispyb_gridscan_cb = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_rotation_cb = RotationISPyBCallback() robot_load_cb = RobotLoadISPyBCallback() # robot_load_cb.expeye = MagicMock() @@ -353,7 +356,9 @@ def test_load_centre_collect_updates_bl_sample_status_pin_tip_detection_fail( fetch_blsample: Callable[..., Any], ): robot_load_cb = RobotLoadISPyBCallback() - ispyb_gridscan_cb = GridscanISPyBCallback() + ispyb_gridscan_cb = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) sample_handling_cb = SampleHandlingCallback() RE.subscribe(robot_load_cb) RE.subscribe(ispyb_gridscan_cb) @@ -406,7 +411,9 @@ def test_load_centre_collect_updates_bl_sample_status_grid_detection_fail_tip_no fetch_blsample: Callable[..., Any], ): robot_load_cb = RobotLoadISPyBCallback() - ispyb_gridscan_cb = GridscanISPyBCallback() + ispyb_gridscan_cb = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) sample_handling_cb = SampleHandlingCallback() RE.subscribe(robot_load_cb) RE.subscribe(ispyb_gridscan_cb) @@ -454,7 +461,9 @@ def test_load_centre_collect_updates_bl_sample_status_gridscan_no_diffraction( fetch_blsample: Callable[..., Any], ): robot_load_cb = RobotLoadISPyBCallback() - ispyb_gridscan_cb = GridscanISPyBCallback() + ispyb_gridscan_cb = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) sample_handling_cb = SampleHandlingCallback() RE.subscribe(robot_load_cb) RE.subscribe(ispyb_gridscan_cb) @@ -481,7 +490,9 @@ def test_load_centre_collect_updates_bl_sample_status_rotation_failure( fetch_blsample: Callable[..., Any], ): robot_load_cb = RobotLoadISPyBCallback() - ispyb_gridscan_cb = GridscanISPyBCallback() + ispyb_gridscan_cb = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) sample_handling_cb = SampleHandlingCallback() RE.subscribe(robot_load_cb) RE.subscribe(ispyb_gridscan_cb) diff --git a/tests/system_tests/hyperion/external_interaction/test_zocalo_system.py b/tests/system_tests/hyperion/external_interaction/test_zocalo_system.py index 9d3b73af5..2b0451eb7 100644 --- a/tests/system_tests/hyperion/external_interaction/test_zocalo_system.py +++ b/tests/system_tests/hyperion/external_interaction/test_zocalo_system.py @@ -19,7 +19,7 @@ create_gridscan_callbacks, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from tests.conftest import create_dummy_scan_spec """ @@ -60,7 +60,7 @@ def fake_fgs_plan(): @pytest.fixture def run_zocalo_with_dev_ispyb( - dummy_params: HyperionThreeDGridScan, + dummy_params: HyperionSpecifiedThreeDGridScan, dummy_ispyb_3d, RE: RunEngine, zocalo_device: ZocaloResults, diff --git a/tests/unit_tests/common/external_interaction/callbacks/ispyb/conftest.py b/tests/unit_tests/common/external_interaction/callbacks/ispyb/conftest.py index caae596ac..fe5423529 100644 --- a/tests/unit_tests/common/external_interaction/callbacks/ispyb/conftest.py +++ b/tests/unit_tests/common/external_interaction/callbacks/ispyb/conftest.py @@ -10,7 +10,7 @@ ) from mx_bluesky.common.external_interaction.ispyb.ispyb_store import StoreInIspyb from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from ......conftest import ( TEST_DATA_COLLECTION_GROUP_ID, @@ -22,7 +22,7 @@ @pytest.fixture def dummy_params(): - dummy_params = HyperionThreeDGridScan(**default_raw_gridscan_params()) + dummy_params = HyperionSpecifiedThreeDGridScan(**default_raw_gridscan_params()) dummy_params.sample_id = TEST_SAMPLE_ID dummy_params.run_number = 0 return dummy_params diff --git a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_callback.py b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_callback.py index cec1799c2..28e96cb3a 100644 --- a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_callback.py +++ b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_callback.py @@ -3,6 +3,7 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import ( GridscanISPyBCallback, ) +from mx_bluesky.hyperion.parameters.gridscan import GridCommonWithHyperionDetectorParams from .....conftest import ( EXPECTED_START_TIME, @@ -56,7 +57,9 @@ ) class TestXrayCentreISPyBCallback: def test_activity_gated_start_3d(self, mock_ispyb_conn): - callback = GridscanISPyBCallback() + callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) callback.activity_gated_start(TestData.test_gridscan3d_start_document) # pyright: ignore mx_acq = mx_acquisition_from_conn(mock_ispyb_conn) assert_upsert_call_with( @@ -82,7 +85,9 @@ def test_activity_gated_start_3d(self, mock_ispyb_conn): mx_acq.upsert_data_collection.upsert_dc_grid.assert_not_called() def test_hardware_read_event_3d(self, mock_ispyb_conn): - callback = GridscanISPyBCallback() + callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) callback.activity_gated_start(TestData.test_gridscan3d_start_document) # pyright: ignore mx_acq = mx_acquisition_from_conn(mock_ispyb_conn) mx_acq.upsert_data_collection_group.reset_mock() @@ -113,7 +118,9 @@ def test_hardware_read_event_3d(self, mock_ispyb_conn): ) def test_flux_read_events_3d(self, mock_ispyb_conn): - callback = GridscanISPyBCallback() + callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) callback.activity_gated_start(TestData.test_gridscan3d_start_document) # pyright: ignore mx_acq = mx_acquisition_from_conn(mock_ispyb_conn) callback.activity_gated_descriptor( @@ -166,7 +173,9 @@ def test_flux_read_events_3d(self, mock_ispyb_conn): mx_acq.upsert_dc_grid.assert_not_called() def test_activity_gated_event_oav_snapshot_triggered(self, mock_ispyb_conn): - callback = GridscanISPyBCallback() + callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) callback.activity_gated_start(TestData.test_gridscan3d_start_document) # pyright: ignore mx_acq = mx_acquisition_from_conn(mock_ispyb_conn) mx_acq.upsert_data_collection_group.reset_mock() diff --git a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_handler.py b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_handler.py index 7578060f7..e090b6355 100644 --- a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_handler.py +++ b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_handler.py @@ -12,6 +12,7 @@ ) from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER from mx_bluesky.hyperion.external_interaction.callbacks.__main__ import setup_logging +from mx_bluesky.hyperion.parameters.gridscan import GridCommonWithHyperionDetectorParams from .....conftest import TestData @@ -52,7 +53,9 @@ class TestXrayCentreIspybHandler: def test_fgs_failing_results_in_bad_run_status_in_ispyb( self, ): - ispyb_handler = GridscanISPyBCallback() + ispyb_handler = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_handler.activity_gated_start(td.test_gridscan3d_start_document) ispyb_handler.activity_gated_descriptor( td.test_descriptor_document_pre_data_collection @@ -79,7 +82,9 @@ def test_fgs_failing_results_in_bad_run_status_in_ispyb( def test_fgs_raising_no_exception_results_in_good_run_status_in_ispyb( self, ): - ispyb_handler = GridscanISPyBCallback() + ispyb_handler = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_handler.activity_gated_start(td.test_gridscan3d_start_document) ispyb_handler.activity_gated_descriptor( td.test_descriptor_document_pre_data_collection @@ -111,12 +116,14 @@ def test_given_ispyb_callback_started_writing_to_ispyb_when_messages_logged_then gelf_handler: MagicMock = next( filter( lambda h: isinstance(h, GELFTCPHandler), - ISPYB_ZOCALO_CALLBACK_LOGGER.handlers, - ) # type: ignore + ISPYB_ZOCALO_CALLBACK_LOGGER.handlers, # type: ignore + ) ) gelf_handler.emit = MagicMock() - ispyb_handler = GridscanISPyBCallback() + ispyb_handler = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_handler.activity_gated_start(td.test_gridscan3d_start_document) ispyb_handler.activity_gated_descriptor( td.test_descriptor_document_pre_data_collection @@ -141,12 +148,14 @@ def test_given_ispyb_callback_finished_writing_to_ispyb_when_messages_logged_the gelf_handler: MagicMock = next( filter( lambda h: isinstance(h, GELFTCPHandler), - ISPYB_ZOCALO_CALLBACK_LOGGER.handlers, - ) # type: ignore + ISPYB_ZOCALO_CALLBACK_LOGGER.handlers, # type: ignore + ) ) gelf_handler.emit = MagicMock() - ispyb_handler = GridscanISPyBCallback() + ispyb_handler = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_handler.activity_gated_start(td.test_gridscan3d_start_document) ispyb_handler.activity_gated_descriptor( td.test_descriptor_document_pre_data_collection @@ -171,7 +180,9 @@ def test_given_ispyb_callback_finished_writing_to_ispyb_when_messages_logged_the def test_given_fgs_plan_finished_when_zocalo_results_event_then_expected_comment_deposited( self, mock_time ): - ispyb_handler = GridscanISPyBCallback() + ispyb_handler = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) ispyb_handler.activity_gated_start(td.test_gridscan3d_start_document) # type:ignore diff --git a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_mapping.py b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_mapping.py index 03c2a6588..69e9bc255 100644 --- a/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_mapping.py +++ b/tests/unit_tests/common/external_interaction/xray_centre/test_ispyb_mapping.py @@ -9,7 +9,7 @@ DataCollectionGridInfo, Orientation, ) -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from .....conftest import ( TEST_SAMPLE_ID, @@ -19,7 +19,7 @@ @pytest.fixture def dummy_params(): - dummy_params = HyperionThreeDGridScan(**default_raw_gridscan_params()) + dummy_params = HyperionSpecifiedThreeDGridScan(**default_raw_gridscan_params()) dummy_params.sample_id = TEST_SAMPLE_ID dummy_params.run_number = 0 return dummy_params @@ -67,7 +67,7 @@ def test_ispyb_deposition_rounds_position_to_int( ) def test_ispyb_deposition_rounds_box_size_int( bottom_right_from_top_left: MagicMock, - dummy_params: HyperionThreeDGridScan, + dummy_params: HyperionSpecifiedThreeDGridScan, raw, rounded, ): diff --git a/tests/unit_tests/common/external_interaction/xray_centre/test_nexus_handler.py b/tests/unit_tests/common/external_interaction/xray_centre/test_nexus_handler.py index acb940d99..350c8c4e5 100644 --- a/tests/unit_tests/common/external_interaction/xray_centre/test_nexus_handler.py +++ b/tests/unit_tests/common/external_interaction/xray_centre/test_nexus_handler.py @@ -8,6 +8,7 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import ( GridscanNexusFileCallback, ) +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from .....conftest import TestData @@ -23,7 +24,9 @@ def nexus_writer(): def test_writers_not_sDTypeLikeetup_on_plan_start_doc( nexus_writer: MagicMock, ): - nexus_handler = GridscanNexusFileCallback() + nexus_handler = GridscanNexusFileCallback( + param_type=HyperionSpecifiedThreeDGridScan + ) nexus_writer.assert_not_called() nexus_handler.activity_gated_start(TestData.test_start_document) nexus_writer.assert_not_called() @@ -36,7 +39,9 @@ def test_writers_dont_create_on_init_but_do_on_during_collection_read_event( mock_nexus_writer: MagicMock, ): mock_nexus_writer.side_effect = [MagicMock(), MagicMock()] - nexus_handler = GridscanNexusFileCallback() + nexus_handler = GridscanNexusFileCallback( + param_type=HyperionSpecifiedThreeDGridScan + ) assert nexus_handler.nexus_writer_1 is None assert nexus_handler.nexus_writer_2 is None @@ -73,7 +78,9 @@ def test_given_different_bit_depths_then_writers_created_wth_correct_VDS_size( vds_type: DTypeLike, ): mock_nexus_writer.side_effect = [MagicMock(), MagicMock()] - nexus_handler = GridscanNexusFileCallback() + nexus_handler = GridscanNexusFileCallback( + param_type=HyperionSpecifiedThreeDGridScan + ) nexus_handler.activity_gated_start(TestData.test_start_document) nexus_handler.activity_gated_descriptor( @@ -101,7 +108,9 @@ def test_beam_and_attenuator_set_on_ispyb_transmission_event( mock_nexus_writer: MagicMock, ): mock_nexus_writer.side_effect = [MagicMock(), MagicMock()] - nexus_handler = GridscanNexusFileCallback() + nexus_handler = GridscanNexusFileCallback( + param_type=HyperionSpecifiedThreeDGridScan + ) nexus_handler.activity_gated_start(TestData.test_start_document) nexus_handler.activity_gated_descriptor( @@ -120,7 +129,9 @@ def test_beam_and_attenuator_set_on_ispyb_transmission_event( def test_sensible_error_if_writing_triggered_before_params_received( nexus_writer: MagicMock, ): - nexus_handler = GridscanNexusFileCallback() + nexus_handler = GridscanNexusFileCallback( + param_type=HyperionSpecifiedThreeDGridScan + ) with pytest.raises(AssertionError) as excinfo: nexus_handler.activity_gated_descriptor( TestData.test_descriptor_document_during_data_collection diff --git a/tests/unit_tests/hyperion/device_setup_plans/test_manipulate_sample.py b/tests/unit_tests/hyperion/device_setup_plans/test_manipulate_sample.py index 04cea4328..f9a8b3c85 100644 --- a/tests/unit_tests/hyperion/device_setup_plans/test_manipulate_sample.py +++ b/tests/unit_tests/hyperion/device_setup_plans/test_manipulate_sample.py @@ -12,7 +12,7 @@ from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( FlyScanXRayCentreComposite, ) -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan @pytest.mark.parametrize( @@ -61,7 +61,7 @@ async def test_move_aperture_does_nothing_when_none_selected( @patch("bluesky.plan_stubs.abs_set", autospec=True) def test_move_x_y_z( bps_abs_set: MagicMock, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, fake_fgs_composite: FlyScanXRayCentreComposite, RE: RunEngine, motor_position: list[float], @@ -102,7 +102,7 @@ def test_move_x_y_z( @patch("bluesky.plan_stubs.abs_set", autospec=True) def test_move_phi_chi_omega( bps_abs_set: MagicMock, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, fake_fgs_composite: FlyScanXRayCentreComposite, RE: RunEngine, motor_position: list[float], diff --git a/tests/unit_tests/hyperion/experiment_plans/conftest.py b/tests/unit_tests/hyperion/experiment_plans/conftest.py index 8b3336331..c5591fdbc 100644 --- a/tests/unit_tests/hyperion/experiment_plans/conftest.py +++ b/tests/unit_tests/hyperion/experiment_plans/conftest.py @@ -47,7 +47,7 @@ create_gridscan_callbacks, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan FLYSCAN_RESULT_HIGH = XRayCentreResult( centre_of_mass_mm=np.array([0.1, 0.2, 0.3]), @@ -179,7 +179,7 @@ async def mock_complete(results): def run_generic_ispyb_handler_setup( ispyb_handler: GridscanISPyBCallback, - params: HyperionThreeDGridScan, + params: HyperionSpecifiedThreeDGridScan, ): """This is useful when testing 'run_gridscan_and_move(...)' because this stuff happens at the start of the outer plan.""" diff --git a/tests/unit_tests/hyperion/experiment_plans/test_change_aperture_then_move_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_change_aperture_then_move_plan.py index 200a6442c..56d7c4ad5 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_change_aperture_then_move_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_change_aperture_then_move_plan.py @@ -8,7 +8,7 @@ change_aperture_then_move_to_xtal, ) from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan @pytest.fixture @@ -30,7 +30,7 @@ def test_change_aperture_then_move_to_xtal_happy_path( simple_flyscan_hit: XRayCentreResult, smargon: Smargon, aperture_scatterguard: ApertureScatterguard, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, set_stub_offsets: bool, ): test_fgs_params.features.set_stub_offsets = set_stub_offsets diff --git a/tests/unit_tests/hyperion/experiment_plans/test_flyscan_xray_centre_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_flyscan_xray_centre_plan.py index d9bb63011..e4436b2e7 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_flyscan_xray_centre_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_flyscan_xray_centre_plan.py @@ -69,7 +69,10 @@ ) from mx_bluesky.hyperion.external_interaction.config_server import HyperionFeatureFlags from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + HyperionSpecifiedThreeDGridScan, +) from tests.conftest import ( RunEngineSimulator, create_dummy_scan_spec, @@ -103,7 +106,8 @@ def fgs_composite_with_panda_pcap(fake_fgs_composite: FlyScanXRayCentreComposite @pytest.fixture def fgs_params_use_panda( - test_fgs_params: HyperionThreeDGridScan, feature_flags: HyperionFeatureFlags + test_fgs_params: HyperionSpecifiedThreeDGridScan, + feature_flags: HyperionFeatureFlags, ): feature_flags.use_panda_for_gridscan = True test_fgs_params.features = feature_flags @@ -114,7 +118,7 @@ def fgs_params_use_panda( def test_fgs_params_panda_zebra( request: pytest.FixtureRequest, feature_flags: HyperionFeatureFlags, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, ): if request.param: feature_flags.use_panda_for_gridscan = request.param @@ -123,7 +127,7 @@ def test_fgs_params_panda_zebra( @pytest.fixture -def ispyb_plan(test_fgs_params: HyperionThreeDGridScan): +def ispyb_plan(test_fgs_params: HyperionSpecifiedThreeDGridScan): @bpp.set_run_key_decorator(CONST.PLAN.GRIDSCAN_OUTER) @bpp.run_decorator( # attach experiment metadata to the start document md={ @@ -158,7 +162,7 @@ def mock_ispyb(): @pytest.fixture def feature_controlled( fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, ) -> _FeatureControlled: return _get_feature_controlled(fake_fgs_composite, test_fgs_params_panda_zebra) @@ -176,7 +180,7 @@ class TestFlyscanXrayCentrePlan: def test_eiger2_x_16_detector_specified( self, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, ): assert ( test_fgs_params.detector_params.detector_size_constants.det_type_string @@ -193,10 +197,12 @@ def test_when_run_gridscan_called_ispyb_deposition_made_and_records_errors( self, RE: RunEngine, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, mock_ispyb: MagicMock, ): - ispyb_callback = GridscanISPyBCallback() + ispyb_callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) RE.subscribe(ispyb_callback) error = None @@ -217,7 +223,7 @@ def test_when_run_gridscan_called_ispyb_deposition_made_and_records_errors( def test_read_hardware_for_ispyb_updates_from_ophyd_devices( self, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, RE: RunEngine, ispyb_plan, ): @@ -334,7 +340,7 @@ async def test_results_adjusted_and_event_raised( run_gridscan: MagicMock, move_aperture: MagicMock, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, feature_controlled: _FeatureControlled, RE_with_subs: ReWithSubs, ): @@ -389,7 +395,7 @@ def test_results_adjusted_and_passed_to_move_xyz( run_gridscan: MagicMock, move_aperture: MagicMock, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, RE_with_subs: ReWithSubs, ): RE, _ = RE_with_subs @@ -427,7 +433,7 @@ def test_results_adjusted_and_passed_to_move_xyz( def test_results_passed_to_move_motors( self, bps_abs_set: MagicMock, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, fake_fgs_composite: FlyScanXRayCentreComposite, RE: RunEngine, ): @@ -481,7 +487,7 @@ def test_individual_plans_triggered_once_and_only_once_in_composite_run( move_aperture: MagicMock, RE_with_subs: ReWithSubs, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, ): RE, (_, ispyb_cb) = RE_with_subs @@ -513,7 +519,7 @@ async def test_when_gridscan_finished_then_dev_shm_disabled( run_gridscan: MagicMock, aperture_set: MagicMock, RE_with_subs: ReWithSubs, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, feature_controlled: _FeatureControlled, ): @@ -555,7 +561,7 @@ def test_when_gridscan_succeeds_ispyb_comment_appended_to( run_gridscan: MagicMock, aperture_set: MagicMock, RE_with_subs: ReWithSubs, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, feature_controlled: _FeatureControlled, ): @@ -590,7 +596,7 @@ def test_waits_for_motion_program( self, check_topup_and_wait, RE: RunEngine, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, fake_fgs_composite: FlyScanXRayCentreComposite, done_status: Status, ): @@ -637,7 +643,7 @@ def test_when_gridscan_finds_no_xtal_ispyb_comment_appended_to( move_xyz: MagicMock, run_gridscan: MagicMock, RE_with_subs: ReWithSubs, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, feature_controlled: _FeatureControlled, ): @@ -679,7 +685,7 @@ def test_when_gridscan_finds_no_xtal_exception_is_raised( move_xyz: MagicMock, run_gridscan: MagicMock, RE_with_subs: ReWithSubs, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, feature_controlled: _FeatureControlled, ): @@ -773,7 +779,7 @@ def test_when_grid_scan_ran_then_eiger_disarmed_before_zocalo_end( mock_kickoff, mock_abs_set, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, RE_with_subs: ReWithSubs, ): test_fgs_params.x_steps = 9 @@ -830,7 +836,7 @@ def test_flyscan_xray_centre_sets_directory_stages_arms_disarms_unstages_the_pan mock_set_panda_directory: MagicMock, done_status: Status, fgs_composite_with_panda_pcap: FlyScanXRayCentreComposite, - fgs_params_use_panda: HyperionThreeDGridScan, + fgs_params_use_panda: HyperionSpecifiedThreeDGridScan, sim_run_engine: RunEngineSimulator, ): sim_run_engine.add_handler("unstage", lambda _: done_status) @@ -893,7 +899,7 @@ def test_fgs_arms_eiger_without_grid_detect( mock_complete, mock_wait, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, RE: RunEngine, done_status: Status, feature_controlled: _FeatureControlled, @@ -930,7 +936,7 @@ def test_when_grid_scan_fails_with_exception_then_detector_disarmed_and_correct_ mock_wait, mock_kickoff, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, RE: RunEngine, feature_controlled: _FeatureControlled, ): @@ -1041,7 +1047,7 @@ def test_kickoff_and_complete_gridscan_triggers_zocalo( def test_read_hardware_during_collection_occurs_after_eiger_arm( self, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, sim_run_engine: RunEngineSimulator, feature_controlled: _FeatureControlled, ): @@ -1080,7 +1086,7 @@ def test_read_hardware_during_collection_occurs_after_eiger_arm( def test_if_smargon_speed_over_limit_then_log_error( self, mock_kickoff_and_complete: MagicMock, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, fake_fgs_composite: FlyScanXRayCentreComposite, feature_controlled: _FeatureControlled, RE: RunEngine, @@ -1107,7 +1113,7 @@ def test_if_smargon_speed_over_limit_then_log_error( def test_run_gridscan_and_fetch_results_discards_results_below_threshold( self, fake_fgs_composite: FlyScanXRayCentreComposite, - test_fgs_params_panda_zebra: HyperionThreeDGridScan, + test_fgs_params_panda_zebra: HyperionSpecifiedThreeDGridScan, feature_controlled: _FeatureControlled, RE: RunEngine, ): diff --git a/tests/unit_tests/hyperion/experiment_plans/test_grid_detect_then_xray_centre_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_grid_detect_then_xray_centre_plan.py index e3bc7fcc9..c328d39dc 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_grid_detect_then_xray_centre_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_grid_detect_then_xray_centre_plan.py @@ -17,7 +17,6 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import ( ispyb_activation_wrapper, ) -from mx_bluesky.common.parameters.gridscan import GridScanWithEdgeDetect from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( _fire_xray_centre_result_event, ) @@ -28,7 +27,8 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.gridscan import ( - HyperionThreeDGridScan, + GridScanWithEdgeDetect, + HyperionSpecifiedThreeDGridScan, ) from ....conftest import OavGridSnapshotTestEvents @@ -40,7 +40,7 @@ def _fake_flyscan(*args): def test_full_grid_scan( - test_fgs_params: HyperionThreeDGridScan, test_config_files: dict[str, str] + test_fgs_params: HyperionSpecifiedThreeDGridScan, test_config_files: dict[str, str] ): devices = MagicMock() plan = grid_detect_then_xray_centre( @@ -134,7 +134,7 @@ def test_when_full_grid_scan_run_then_parameters_sent_to_fgs_as_expected( ) ) - params: HyperionThreeDGridScan = mock_flyscan.call_args[0][1] + params: HyperionSpecifiedThreeDGridScan = mock_flyscan.call_args[0][1] assert params.detector_params.num_triggers == 180 assert params.FGS_params.x_axis.full_steps == 15 diff --git a/tests/unit_tests/hyperion/experiment_plans/test_grid_detection_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_grid_detection_plan.py index 40be33a4b..2bbe54d10 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_grid_detection_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_grid_detection_plan.py @@ -31,7 +31,10 @@ get_min_and_max_y_of_pin, grid_detection_plan, ) -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + HyperionSpecifiedThreeDGridScan, +) from .conftest import assert_event @@ -227,12 +230,12 @@ async def test_when_grid_detection_plan_run_then_ispyb_callback_gets_correct_val fake_devices: tuple[OavGridDetectionComposite, MagicMock], RE: RunEngine, test_config_files: dict[str, str], - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, tmp_path: Path, ): params = OAVParameters("loopCentring", test_config_files["oav_config_json"]) composite, _ = fake_devices - cb = GridscanISPyBCallback() + cb = GridscanISPyBCallback(param_type=GridCommonWithHyperionDetectorParams) RE.subscribe(cb) with patch.multiple(cb, activity_gated_start=DEFAULT, activity_gated_event=DEFAULT): @@ -287,7 +290,7 @@ def test_when_grid_detection_plan_run_then_grid_detection_callback_gets_correct_ fake_devices: tuple[OavGridDetectionComposite, MagicMock], RE: RunEngine, test_config_files: dict[str, str], - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, tmp_path: Path, ): params = OAVParameters("loopCentring", test_config_files["oav_config_json"]) diff --git a/tests/unit_tests/hyperion/experiment_plans/test_load_centre_collect_full_plan.py b/tests/unit_tests/hyperion/experiment_plans/test_load_centre_collect_full_plan.py index 5350ca885..5522c3f5a 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_load_centre_collect_full_plan.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_load_centre_collect_full_plan.py @@ -16,7 +16,6 @@ from ophyd_async.testing import set_mock_value from pydantic import ValidationError -from mx_bluesky.common.parameters.robot_load import RobotLoadAndEnergyChange from mx_bluesky.common.utils.exceptions import WarningException from mx_bluesky.hyperion.device_setup_plans.check_beamstop import BeamstopException from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( @@ -34,6 +33,7 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange from mx_bluesky.hyperion.parameters.rotation import ( MultiRotationScan, RotationScanPerSweep, 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 6a1e647a1..ea6efc868 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 @@ -11,9 +11,6 @@ from dodal.devices.smargon import Smargon from dodal.devices.synchrotron import SynchrotronMode -from mx_bluesky.common.parameters.gridscan import ( - PinTipCentreThenXrayCentre, -) from mx_bluesky.hyperion.device_setup_plans.check_beamstop import BeamstopException from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( _fire_xray_centre_result_event, @@ -27,6 +24,9 @@ pin_tip_centre_then_xray_centre, ) from mx_bluesky.hyperion.parameters.constants import CONST +from mx_bluesky.hyperion.parameters.gridscan import ( + PinTipCentreThenXrayCentre, +) from ....conftest import raw_params_from_file, simulate_xrc_result from ....system_tests.hyperion.external_interaction.conftest import ( diff --git a/tests/unit_tests/hyperion/experiment_plans/test_robot_load_and_change_energy.py b/tests/unit_tests/hyperion/experiment_plans/test_robot_load_and_change_energy.py index 325e8b09f..152ab8f2a 100644 --- a/tests/unit_tests/hyperion/experiment_plans/test_robot_load_and_change_energy.py +++ b/tests/unit_tests/hyperion/experiment_plans/test_robot_load_and_change_energy.py @@ -13,7 +13,6 @@ from ophyd.sim import NullStatus from ophyd_async.testing import set_mock_value -from mx_bluesky.common.parameters.robot_load import RobotLoadAndEnergyChange from mx_bluesky.hyperion.experiment_plans.robot_load_and_change_energy import ( RobotLoadAndEnergyChangeComposite, SampleLocation, @@ -25,6 +24,7 @@ from mx_bluesky.hyperion.external_interaction.callbacks.robot_load.ispyb_callback import ( RobotLoadISPyBCallback, ) +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange from ....conftest import raw_params_from_file 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 76a3b9f73..3479ed07e 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 @@ -8,9 +8,6 @@ from dodal.devices.i03.beamstop import BeamstopPositions from dodal.devices.robot import SampleLocation -from mx_bluesky.common.parameters.gridscan import ( - PinTipCentreThenXrayCentre, -) from mx_bluesky.hyperion.device_setup_plans.check_beamstop import BeamstopException from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import ( _fire_xray_centre_result_event, @@ -23,7 +20,10 @@ robot_load_then_centre, ) from mx_bluesky.hyperion.parameters.constants import CONST -from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre +from mx_bluesky.hyperion.parameters.gridscan import ( + PinTipCentreThenXrayCentre, +) +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre from ....conftest import assert_none_matching, raw_params_from_file from .conftest import FLYSCAN_RESULT_LOW, FLYSCAN_RESULT_MED, sim_fire_event_on_open_run @@ -34,7 +34,7 @@ def robot_load_then_centre_params(): params = raw_params_from_file( "tests/test_data/parameter_json_files/good_test_robot_load_and_centre_params.json" ) - return HyperionRobotLoadThenCentre(**params) + return RobotLoadThenCentre(**params) @pytest.fixture @@ -76,7 +76,7 @@ def test_robot_load_then_centre_centres_on_the_first_flyscan_result( mock_change_aperture_then_move_to_xtal: MagicMock, mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, ): RE = RunEngine() @@ -100,7 +100,7 @@ def test_robot_load_then_centre_centres_on_the_first_flyscan_result( def test_when_plan_run_then_centring_plan_run_with_expected_parameters( mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, ): RE = RunEngine() @@ -129,7 +129,7 @@ def test_when_plan_run_then_centring_plan_run_with_expected_parameters( def test_when_plan_run_with_requested_energy_specified_energy_set_on_eiger( mock_centring_plan: MagicMock, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, ): robot_load_composite.eiger.set_detector_parameters = MagicMock() @@ -154,7 +154,7 @@ def test_when_plan_run_with_requested_energy_specified_energy_set_on_eiger( ) def test_given_no_energy_supplied_when_robot_load_then_centre_current_energy_set_on_eiger( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params_no_energy: HyperionRobotLoadThenCentre, + robot_load_then_centre_params_no_energy: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, ): robot_load_composite.eiger.set_detector_parameters = MagicMock() @@ -216,7 +216,7 @@ def dummy_robot_load_plan(*args, **kwargs): ) def test_when_plan_run_then_detector_arm_started_before_wait_on_robot_load( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine, ): sim_run_engine.add_handler_for_callback_subscribes() @@ -264,7 +264,7 @@ def mock_current_sample(sim_run_engine: RunEngineSimulator, sample: SampleLocati ) def test_given_sample_already_loaded_and_chi_not_changed_when_robot_load_called_then_eiger_not_staged_and_centring_not_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_loaded, ): @@ -314,7 +314,7 @@ def test_given_sample_already_loaded_and_chi_not_changed_when_robot_load_called_ ) def test_given_sample_already_loaded_and_chi_is_changed_when_robot_load_called_then_eiger_staged_and_centring_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_loaded, ): @@ -373,7 +373,7 @@ def test_given_sample_already_loaded_and_chi_is_changed_when_robot_load_called_t ) def test_given_sample_not_loaded_and_chi_not_changed_when_robot_load_called_then_eiger_staged_before_robot_and_centring_run_after( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_not_loaded, ): @@ -416,7 +416,7 @@ def test_given_sample_not_loaded_and_chi_not_changed_when_robot_load_called_then ) def test_given_sample_not_loaded_and_chi_changed_when_robot_load_called_then_eiger_staged_before_robot_and_centring_run( robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sim_run_engine: RunEngineSimulator, sample_is_not_loaded, ): @@ -465,7 +465,7 @@ def test_given_sample_not_loaded_and_chi_changed_when_robot_load_called_then_eig def test_robot_load_then_centre_sets_energy_when_chi_change_and_no_robot_load( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sample_is_loaded, ): robot_load_then_centre_params.chi_start_deg = 30 @@ -494,7 +494,7 @@ def test_robot_load_then_centre_sets_energy_when_chi_change_and_no_robot_load( def test_robot_load_then_centre_sets_energy_when_no_robot_load_no_chi_change( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, sample_is_loaded, ): robot_load_then_centre_params.chi_start_deg = None @@ -511,11 +511,11 @@ def test_robot_load_then_centre_sets_energy_when_no_robot_load_no_chi_change( def test_tip_offset_um_passed_to_pin_tip_centre_plan( - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, ): robot_load_then_centre_params.tip_offset_um = 100 assert ( - robot_load_then_centre_params.pin_centre_then_xray_centre_params().tip_offset_um + robot_load_then_centre_params.pin_centre_then_xray_centre_params.tip_offset_um == 100 ) @@ -523,7 +523,7 @@ def test_tip_offset_um_passed_to_pin_tip_centre_plan( def test_robot_load_then_centre_fails_with_exception_when_no_beamstop( sim_run_engine: RunEngineSimulator, robot_load_composite: RobotLoadThenCentreComposite, - robot_load_then_centre_params: HyperionRobotLoadThenCentre, + robot_load_then_centre_params: RobotLoadThenCentre, ): sim_run_engine.add_read_handler_for( robot_load_composite.beamstop.selected_pos, BeamstopPositions.UNKNOWN diff --git a/tests/unit_tests/hyperion/external_interaction/conftest.py b/tests/unit_tests/hyperion/external_interaction/conftest.py index 71d7c0110..c2817cbdf 100644 --- a/tests/unit_tests/hyperion/external_interaction/conftest.py +++ b/tests/unit_tests/hyperion/external_interaction/conftest.py @@ -3,7 +3,7 @@ import pytest from mx_bluesky.common.utils.utils import convert_angstrom_to_eV -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from mx_bluesky.hyperion.parameters.rotation import RotationScan from ....conftest import ( @@ -32,7 +32,7 @@ def test_rotation_params(): @pytest.fixture(params=[1050]) def test_fgs_params(request): assert request.param % 25 == 0, "Please use a multiple of 25 images" - params = HyperionThreeDGridScan(**default_raw_gridscan_params()) + params = HyperionSpecifiedThreeDGridScan(**default_raw_gridscan_params()) params.demand_energy_ev = convert_angstrom_to_eV(1.0) params.use_roi_mode = True first_scan_img = (request.param // 10) * 6 diff --git a/tests/unit_tests/hyperion/external_interaction/nexus/test_write_nexus.py b/tests/unit_tests/hyperion/external_interaction/nexus/test_write_nexus.py index 02ba42d6f..d3e191734 100644 --- a/tests/unit_tests/hyperion/external_interaction/nexus/test_write_nexus.py +++ b/tests/unit_tests/hyperion/external_interaction/nexus/test_write_nexus.py @@ -21,7 +21,7 @@ create_beam_and_attenuator_parameters, ) from mx_bluesky.common.external_interaction.nexus.write_nexus import NexusWriter -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan """It's hard to effectively unit test the nexus writing so these are really system tests that confirms that we're passing the right sorts of data to nexgen to get a sensible output. @@ -38,7 +38,7 @@ def assert_end_data_correct(nexus_writer: NexusWriter): assert "end_time_estimated" in entry -def create_nexus_writer(parameters: HyperionThreeDGridScan, writer_num): +def create_nexus_writer(parameters: HyperionSpecifiedThreeDGridScan, writer_num): d_size = parameters.detector_params.detector_size_constants.det_size_pixels n_img = ( parameters.scan_indices[1] @@ -71,7 +71,7 @@ def create_nexus_writer(parameters: HyperionThreeDGridScan, writer_num): @contextmanager -def create_nexus_writers(parameters: HyperionThreeDGridScan): +def create_nexus_writers(parameters: HyperionSpecifiedThreeDGridScan): writers = [create_nexus_writer(parameters, i) for i in [1, 2]] writers[1].start_index = parameters.scan_indices[1] try: @@ -84,7 +84,7 @@ def create_nexus_writers(parameters: HyperionThreeDGridScan): @pytest.fixture -def dummy_nexus_writers(test_fgs_params: HyperionThreeDGridScan): +def dummy_nexus_writers(test_fgs_params: HyperionSpecifiedThreeDGridScan): with create_nexus_writers(test_fgs_params) as ( nexus_writer_1, nexus_writer_2, @@ -93,7 +93,9 @@ def dummy_nexus_writers(test_fgs_params: HyperionThreeDGridScan): @pytest.fixture -def dummy_nexus_writers_with_more_images(test_fgs_params: HyperionThreeDGridScan): +def dummy_nexus_writers_with_more_images( + test_fgs_params: HyperionSpecifiedThreeDGridScan, +): x, y, z = 45, 35, 25 test_fgs_params.x_steps = x test_fgs_params.y_steps = y @@ -106,7 +108,7 @@ def dummy_nexus_writers_with_more_images(test_fgs_params: HyperionThreeDGridScan @pytest.fixture -def single_dummy_file(test_fgs_params: HyperionThreeDGridScan): +def single_dummy_file(test_fgs_params: HyperionSpecifiedThreeDGridScan): test_fgs_params.use_roi_mode = True d_size = test_fgs_params.detector_params.detector_size_constants.det_size_pixels data_shape = (test_fgs_params.scan_indices[1], d_size.width, d_size.height) @@ -128,7 +130,7 @@ def single_dummy_file(test_fgs_params: HyperionThreeDGridScan): indirect=["test_fgs_params"], ) def test_given_number_of_images_above_1000_then_expected_datafiles_used( - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, expected_num_of_files: Literal[3, 4, 9], single_dummy_file: NexusWriter, ): @@ -146,7 +148,7 @@ def test_given_number_of_images_above_1000_then_expected_datafiles_used( def test_given_dummy_data_then_datafile_written_correctly( - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, dummy_nexus_writers: tuple[NexusWriter, NexusWriter], ): nexus_writer_1, nexus_writer_2 = dummy_nexus_writers @@ -322,7 +324,7 @@ def assert_contains_external_link(data_path, entry_name, file_name): def test_nexus_writer_files_are_formatted_as_expected( - test_fgs_params: HyperionThreeDGridScan, single_dummy_file: NexusWriter + test_fgs_params: HyperionSpecifiedThreeDGridScan, single_dummy_file: NexusWriter ): for file in [single_dummy_file.nexus_file, single_dummy_file.master_file]: file_name = os.path.basename(file.name) @@ -342,7 +344,7 @@ def test_nexus_writer_writes_width_and_height_correctly(single_dummy_file: Nexus @patch.dict(os.environ, {"BEAMLINE": "I03"}) def test_nexus_writer_writes_beamline_name_correctly( - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, ): d_size = test_fgs_params.detector_params.detector_size_constants.det_size_pixels data_shape = (test_fgs_params.num_images, d_size.width, d_size.height) @@ -410,7 +412,7 @@ def test_given_some_datafiles_outside_of_VDS_range_THEN_they_are_not_in_nexus_fi def test_given_data_files_not_yet_written_when_nexus_files_created_then_nexus_files_still_written( - test_fgs_params: HyperionThreeDGridScan, + test_fgs_params: HyperionSpecifiedThreeDGridScan, ): test_fgs_params.file_name = "non_existant_file" with create_nexus_writers(test_fgs_params) as ( diff --git a/tests/unit_tests/hyperion/parameters/test_parameter_model.py b/tests/unit_tests/hyperion/parameters/test_parameter_model.py index bc09c091d..6de23ab3d 100644 --- a/tests/unit_tests/hyperion/parameters/test_parameter_model.py +++ b/tests/unit_tests/hyperion/parameters/test_parameter_model.py @@ -17,11 +17,11 @@ create_parameters_for_grid_detection, ) from mx_bluesky.hyperion.parameters.gridscan import ( - HyperionThreeDGridScan, + HyperionSpecifiedThreeDGridScan, OddYStepsException, ) from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect -from mx_bluesky.hyperion.parameters.robot_load import HyperionRobotLoadThenCentre +from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre from mx_bluesky.hyperion.parameters.rotation import RotationScan from ....conftest import raw_params_from_file @@ -72,7 +72,7 @@ def get_empty_grid_parameters() -> GridParamUpdate: def test_minimal_3d_gridscan_params(minimal_3d_gridscan_params): - test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + test_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert {"sam_x", "sam_y", "sam_z"} == set(test_params.scan_points.keys()) assert test_params.scan_indices == [0, 35] assert test_params.num_images == (5 * 7 + 5 * 9) @@ -80,16 +80,16 @@ def test_minimal_3d_gridscan_params(minimal_3d_gridscan_params): def test_cant_do_panda_fgs_with_odd_y_steps(minimal_3d_gridscan_params): - test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + test_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) with pytest.raises(OddYStepsException): _ = test_params.panda_FGS_params assert test_params.FGS_params def test_serialise_deserialise(minimal_3d_gridscan_params): - test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + test_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) serialised = json.loads(test_params.model_dump_json()) - deserialised = HyperionThreeDGridScan(**serialised) + deserialised = HyperionSpecifiedThreeDGridScan(**serialised) assert deserialised.demand_energy_ev is None assert deserialised.visit == "cm12345" assert deserialised.x_start_um == 0.123 @@ -98,16 +98,16 @@ def test_serialise_deserialise(minimal_3d_gridscan_params): def test_param_version(minimal_3d_gridscan_params): with pytest.raises(ValidationError): minimal_3d_gridscan_params["parameter_model_version"] = "4.3.0" - _ = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + _ = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) minimal_3d_gridscan_params["parameter_model_version"] = "5.0.0" - _ = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + _ = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) minimal_3d_gridscan_params["parameter_model_version"] = "5.3.0" - _ = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + _ = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) minimal_3d_gridscan_params["parameter_model_version"] = "5.3.7" - _ = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + _ = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) with pytest.raises(ValidationError): minimal_3d_gridscan_params["parameter_model_version"] = "6.3.7" - _ = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + _ = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) def test_robot_load_then_centre_params(): @@ -119,12 +119,12 @@ def test_robot_load_then_centre_params(): "storage_directory": "/tmp/dls/i03/data/2024/cm31105-4/xraycentring/123456/", } params["detector_distance_mm"] = 200 - test_params = HyperionRobotLoadThenCentre(**params) + test_params = RobotLoadThenCentre(**params) assert test_params.detector_params def test_default_snapshot_path(minimal_3d_gridscan_params): - gridscan_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + gridscan_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert gridscan_params.snapshot_directory == Path( "/tmp/dls/i03/data/2024/cm31105-4/xraycentring/123456/snapshots" ) @@ -132,7 +132,7 @@ def test_default_snapshot_path(minimal_3d_gridscan_params): params_with_snapshot_path = dict(minimal_3d_gridscan_params) params_with_snapshot_path["snapshot_directory"] = "/tmp/my_snapshots" - gridscan_params_with_snapshot_path = HyperionThreeDGridScan( + gridscan_params_with_snapshot_path = HyperionSpecifiedThreeDGridScan( **params_with_snapshot_path ) assert gridscan_params_with_snapshot_path.snapshot_directory == Path( @@ -161,14 +161,14 @@ def test_selected_aperture_uses_default(): def test_feature_flags_overriden_if_supplied(minimal_3d_gridscan_params): - test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + test_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert test_params.features.use_panda_for_gridscan is False assert test_params.features.compare_cpu_and_gpu_zocalo is False minimal_3d_gridscan_params["features"] = { "use_panda_for_gridscan": True, "compare_cpu_and_gpu_zocalo": True, } - test_params = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + test_params = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert test_params.features.compare_cpu_and_gpu_zocalo assert test_params.features.use_panda_for_gridscan # Config server shouldn't update values which were explicitly provided @@ -181,13 +181,13 @@ def test_feature_flags_overriden_if_supplied(minimal_3d_gridscan_params): def test_gpu_enabled_if_use_gpu_or_compare_gpu_enabled(_, minimal_3d_gridscan_params): minimal_3d_gridscan_params["detector_distance_mm"] = 100 - grid_scan = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + grid_scan = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert not grid_scan.detector_params.enable_dev_shm minimal_3d_gridscan_params["features"] = { "compare_cpu_and_gpu_zocalo": True, } - grid_scan = HyperionThreeDGridScan(**minimal_3d_gridscan_params) + grid_scan = HyperionSpecifiedThreeDGridScan(**minimal_3d_gridscan_params) assert grid_scan.detector_params.enable_dev_shm @@ -198,7 +198,7 @@ def test_hyperion_params_correctly_carried_through_UDC_parameter_models( load_centre_collect_params_with_panda.robot_load_then_centre ) pin_tip_then_xrc_params = ( - robot_load_then_centre_params.pin_centre_then_xray_centre_params() + robot_load_then_centre_params.pin_centre_then_xray_centre_params ) grid_detect_then_xrc_params = create_parameters_for_grid_detection( pin_tip_then_xrc_params diff --git a/tests/unit_tests/hyperion/test_main_system.py b/tests/unit_tests/hyperion/test_main_system.py index a2c6e3d14..1905e66de 100644 --- a/tests/unit_tests/hyperion/test_main_system.py +++ b/tests/unit_tests/hyperion/test_main_system.py @@ -31,7 +31,7 @@ ) from mx_bluesky.hyperion.experiment_plans.experiment_registry import PLAN_REGISTRY from mx_bluesky.hyperion.parameters.cli import parse_cli_args -from mx_bluesky.hyperion.parameters.gridscan import HyperionThreeDGridScan +from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan from mx_bluesky.hyperion.utils.context import device_composite_from_context from ...conftest import raw_params_from_file @@ -125,7 +125,7 @@ def mock_dict_values(d: dict): }, "fgs_real_params": { "setup": MagicMock(), - "param_type": HyperionThreeDGridScan, + "param_type": HyperionSpecifiedThreeDGridScan, "experiment_param_type": MagicMock(), "callback_collection_type": MagicMock(), }, @@ -474,7 +474,7 @@ def fake_create_devices(context) -> FakeComposite: autospec=True, ) def test_when_blueskyrunner_initiated_and_skip_flag_is_set_then_setup_called_upon_start( - mock_setup, test_fgs_params: HyperionThreeDGridScan + mock_setup, test_fgs_params: HyperionSpecifiedThreeDGridScan ): mock_setup = MagicMock() with patch.dict( From b7ac4e71fc931559a00eca1776cdb160ad95b98f Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Wed, 15 Jan 2025 17:01:21 +0000 Subject: [PATCH 06/10] typing --- .../external_interaction/test_ispyb_dev_connection.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 88dc311d0..b5f6a1a78 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 @@ -32,7 +32,6 @@ StoreInIspyb, ) from mx_bluesky.common.parameters.components import IspybExperimentType -from mx_bluesky.common.parameters.gridscan import GridScanWithEdgeDetect from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import ( GridDetectThenXRayCentreComposite, grid_detect_then_xray_centre, @@ -46,6 +45,8 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.gridscan import ( + GridCommonWithHyperionDetectorParams, + GridScanWithEdgeDetect, HyperionSpecifiedThreeDGridScan, ) from mx_bluesky.hyperion.parameters.rotation import RotationScan @@ -334,7 +335,9 @@ def test_ispyb_deposition_in_gridscan( os.environ["ISPYB_CONFIG_PATH"] = CONST.SIM.DEV_ISPYB_DATABASE_CFG grid_detect_then_xray_centre_composite.s4_slit_gaps.xgap.user_readback.sim_put(0.1) # type: ignore grid_detect_then_xray_centre_composite.s4_slit_gaps.ygap.user_readback.sim_put(0.1) # type: ignore - ispyb_callback = GridscanISPyBCallback() + ispyb_callback = GridscanISPyBCallback( + param_type=GridCommonWithHyperionDetectorParams + ) RE.subscribe(ispyb_callback) RE( grid_detect_then_xray_centre( From 1aa242e8b614c9bb79d9dd70daaeac486b601987 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Wed, 15 Jan 2025 17:45:31 +0000 Subject: [PATCH 07/10] small tidy --- .../flyscan_xray_centre_plan.py | 2 +- .../hyperion/parameters/robot_load.py | 34 ------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py b/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py index daf8a9126..d41ade5f3 100755 --- a/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +++ b/src/mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py @@ -183,7 +183,7 @@ def flyscan_xray_centre( at any point in it. Args: - parameters (SpecifiedThreeDGridScan): The parameters to run the scan. + parameters (HyperionSpecifiedThreeDGridScan): The parameters to run the scan. Returns: Generator: The plan for the gridscan diff --git a/src/mx_bluesky/hyperion/parameters/robot_load.py b/src/mx_bluesky/hyperion/parameters/robot_load.py index c39030521..3fbf54021 100644 --- a/src/mx_bluesky/hyperion/parameters/robot_load.py +++ b/src/mx_bluesky/hyperion/parameters/robot_load.py @@ -1,4 +1,3 @@ -from dodal.devices.detector.detector import DetectorParams from pydantic import Field from mx_bluesky.common.parameters.components import ( @@ -12,7 +11,6 @@ HardwareConstants, ) from mx_bluesky.hyperion.parameters.components import WithHyperionUDCFeatures -from mx_bluesky.hyperion.parameters.constants import CONST, I03Constants from mx_bluesky.hyperion.parameters.gridscan import ( GridCommonWithHyperionDetectorParams, PinTipCentreThenXrayCentre, @@ -29,38 +27,6 @@ class RobotLoadThenCentre( GridCommonWithHyperionDetectorParams, WithHyperionUDCFeatures ): thawing_time: float = Field(default=HardwareConstants.THAWING_TIME) - tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM) - - # These detector params only exist so that we can properly select enable_dev_shm. Remove in - # https://github.com/DiamondLightSource/hyperion/issues/1395""" - @property - def detector_params(self) -> DetectorParams: - self.det_dist_to_beam_converter_path = ( - self.det_dist_to_beam_converter_path - or CONST.PARAM.DETECTOR.BEAM_XY_LUT_PATH - ) - optional_args = {} - if self.run_number: - optional_args["run_number"] = self.run_number - assert self.detector_distance_mm is not None, ( - "Detector distance must be filled before generating DetectorParams" - ) - return DetectorParams( - detector_size_constants=I03Constants.DETECTOR, - expected_energy_ev=self.demand_energy_ev, - exposure_time=self.exposure_time_s, - directory=self.storage_directory, - prefix=self.file_name, - detector_distance=self.detector_distance_mm, - omega_start=self.omega_start_deg or 0, - omega_increment=0, - num_images_per_trigger=1, - num_triggers=self.num_images, - use_roi_mode=self.use_roi_mode, - det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path, - trigger_mode=self.trigger_mode, - enable_dev_shm=self.features.compare_cpu_and_gpu_zocalo, - ) @property def robot_load_params(self) -> RobotLoadAndEnergyChange: From 2d6ea490723d3e2d4da90ea525947b14a529820e Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Wed, 15 Jan 2025 17:56:28 +0000 Subject: [PATCH 08/10] Change bluesky pinning --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0d4ef8d4e..e996b674f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ dependencies = [ "daq-config-server >= 0.1.1", "ophyd == 1.9.0", "ophyd-async >= 0.8a5", - "bluesky >= 1.13.0a4", + "bluesky >= 1.13", "dls-dodal @ git+https://github.com/DiamondLightSource/dodal.git@e6ad77ee5aa489d0035918e45a28a0d6f72b19ed", ] From dbc237155c24e5267a35b47f7b65599c5021e231 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Wed, 15 Jan 2025 17:59:07 +0000 Subject: [PATCH 09/10] Update test to assert for detector params --- tests/unit_tests/hyperion/parameters/test_parameter_model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit_tests/hyperion/parameters/test_parameter_model.py b/tests/unit_tests/hyperion/parameters/test_parameter_model.py index 6de23ab3d..9ac8c2370 100644 --- a/tests/unit_tests/hyperion/parameters/test_parameter_model.py +++ b/tests/unit_tests/hyperion/parameters/test_parameter_model.py @@ -197,15 +197,19 @@ def test_hyperion_params_correctly_carried_through_UDC_parameter_models( robot_load_then_centre_params = ( load_centre_collect_params_with_panda.robot_load_then_centre ) + assert robot_load_then_centre_params.detector_params.enable_dev_shm pin_tip_then_xrc_params = ( robot_load_then_centre_params.pin_centre_then_xray_centre_params ) + assert pin_tip_then_xrc_params.detector_params.enable_dev_shm grid_detect_then_xrc_params = create_parameters_for_grid_detection( pin_tip_then_xrc_params ) + assert pin_tip_then_xrc_params.detector_params.enable_dev_shm flyscan_xrc_params = create_parameters_for_flyscan_xray_centre( grid_detect_then_xrc_params, get_empty_grid_parameters() ) + assert flyscan_xrc_params.detector_params.enable_dev_shm assert flyscan_xrc_params.panda_runup_distance_mm == 0.17 assert flyscan_xrc_params.features.use_panda_for_gridscan assert flyscan_xrc_params.features.compare_cpu_and_gpu_zocalo From b6716ad59850df3314e778dfe9cbd5c0a4f08687 Mon Sep 17 00:00:00 2001 From: Oliver Silvester Date: Fri, 17 Jan 2025 12:03:54 +0000 Subject: [PATCH 10/10] Fix linting --- .../hyperion/external_interaction/test_ispyb_dev_connection.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 2c813967f..dab9bad32 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 @@ -46,7 +46,6 @@ ) from mx_bluesky.hyperion.parameters.constants import CONST from mx_bluesky.hyperion.parameters.gridscan import ( - GridCommonWithHyperionDetectorParams, GridScanWithEdgeDetect, HyperionSpecifiedThreeDGridScan, ) @@ -340,7 +339,7 @@ def test_ispyb_deposition_in_gridscan( set_mock_value( grid_detect_then_xray_centre_composite.s4_slit_gaps.ygap.user_readback, 0.1 ) - ispyb_callback = GridscanISPyBCallback() + ispyb_callback = GridscanISPyBCallback(HyperionSpecifiedThreeDGridScan) RE.subscribe(ispyb_callback) RE( grid_detect_then_xray_centre(