mx-bluesky 1.4.5__py3-none-any.whl → 1.4.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. mx_bluesky/_version.py +9 -4
  2. mx_bluesky/beamlines/aithre_lasershaping/__init__.py +13 -0
  3. mx_bluesky/beamlines/aithre_lasershaping/check_goniometer_performance.py +29 -0
  4. mx_bluesky/beamlines/aithre_lasershaping/goniometer_controls.py +18 -0
  5. mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +45 -28
  6. mx_bluesky/beamlines/i04/thawing_plan.py +19 -14
  7. mx_bluesky/beamlines/i24/serial/__init__.py +14 -0
  8. mx_bluesky/beamlines/i24/serial/dcid.py +3 -1
  9. mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +12 -12
  10. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +31 -30
  11. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +16 -14
  12. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +19 -21
  13. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +11 -4
  14. mx_bluesky/beamlines/i24/serial/parameters/constants.py +1 -1
  15. mx_bluesky/beamlines/i24/serial/set_visit_directory.sh +1 -1
  16. mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +16 -16
  17. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +48 -49
  18. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +2 -2
  19. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +11 -9
  20. mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +109 -0
  21. mx_bluesky/beamlines/i24/serial/write_nexus.py +5 -4
  22. mx_bluesky/common/device_setup_plans/xbpm_feedback.py +45 -0
  23. mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +2 -4
  24. mx_bluesky/common/external_interaction/callbacks/common/ispyb_mapping.py +1 -1
  25. mx_bluesky/common/external_interaction/callbacks/common/plan_reactive_callback.py +2 -2
  26. mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py +18 -15
  27. mx_bluesky/common/external_interaction/callbacks/sample_handling/__init__.py +0 -0
  28. mx_bluesky/{hyperion → common}/external_interaction/callbacks/sample_handling/sample_handling_callback.py +29 -12
  29. mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +43 -7
  30. mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_mapping.py +1 -1
  31. mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py +2 -1
  32. mx_bluesky/common/external_interaction/ispyb/data_model.py +1 -0
  33. mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +6 -2
  34. mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +21 -1
  35. mx_bluesky/common/external_interaction/nexus/nexus_utils.py +1 -1
  36. mx_bluesky/common/parameters/constants.py +3 -1
  37. mx_bluesky/common/parameters/gridscan.py +36 -1
  38. mx_bluesky/common/plans/do_fgs.py +4 -6
  39. mx_bluesky/common/plans/read_hardware.py +78 -0
  40. mx_bluesky/common/plans/write_sample_status.py +46 -0
  41. mx_bluesky/common/preprocessors/__init__.py +0 -0
  42. mx_bluesky/common/preprocessors/preprocessors.py +105 -0
  43. mx_bluesky/common/protocols/__init__.py +0 -0
  44. mx_bluesky/common/protocols/protocols.py +10 -0
  45. mx_bluesky/common/utils/context.py +68 -0
  46. mx_bluesky/{hyperion/experiment_plans/common → common}/xrc_result.py +16 -0
  47. mx_bluesky/hyperion/__main__.py +7 -9
  48. mx_bluesky/hyperion/baton_handler.py +84 -0
  49. mx_bluesky/hyperion/device_setup_plans/setup_oav.py +5 -5
  50. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +5 -1
  51. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +2 -2
  52. mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
  53. mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
  54. mx_bluesky/hyperion/experiment_plans/__init__.py +0 -4
  55. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +12 -31
  56. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +0 -7
  57. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +44 -97
  58. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +6 -6
  59. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +8 -6
  60. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +11 -11
  61. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +5 -5
  62. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +1 -1
  63. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +2 -4
  64. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +15 -13
  65. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +10 -10
  66. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +1 -29
  67. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +30 -27
  68. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +25 -6
  69. mx_bluesky/hyperion/external_interaction/agamemnon.py +242 -0
  70. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +12 -6
  71. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
  72. mx_bluesky/hyperion/external_interaction/callbacks/snapshot_callback.py +107 -0
  73. mx_bluesky/hyperion/external_interaction/config_server.py +6 -6
  74. mx_bluesky/hyperion/parameters/device_composites.py +49 -0
  75. mx_bluesky/hyperion/parameters/gridscan.py +3 -3
  76. mx_bluesky/hyperion/parameters/rotation.py +1 -1
  77. mx_bluesky/hyperion/utils/__init__.py +1 -0
  78. mx_bluesky/hyperion/utils/context.py +0 -65
  79. mx_bluesky/hyperion/utils/validation.py +3 -3
  80. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info}/METADATA +6 -5
  81. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info}/RECORD +86 -72
  82. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info}/WHEEL +1 -1
  83. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info}/entry_points.txt +1 -0
  84. mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +0 -14
  85. mx_bluesky/common/external_interaction/callbacks/common/aperture_change_callback.py +0 -22
  86. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +0 -54
  87. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +0 -103
  88. /mx_bluesky/{hyperion/external_interaction/callbacks/sample_handling → beamlines/i24/serial/web_gui_plans}/__init__.py +0 -0
  89. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info/licenses}/LICENSE +0 -0
  90. {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.7.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,12 @@
1
1
  from datetime import datetime
2
2
  from enum import Enum
3
3
  from pathlib import Path
4
+ from typing import cast
4
5
 
5
6
  import bluesky.plan_stubs as bps
6
7
  from bluesky.utils import MsgGenerator
7
8
  from dodal.common.beamlines.beamline_utils import get_path_provider
9
+ from dodal.common.types import UpdatingPathProvider
8
10
  from dodal.devices.fast_grid_scan import PandAGridScanParams
9
11
  from dodal.devices.smargon import Smargon
10
12
  from ophyd_async.fastcs.panda import (
@@ -222,6 +224,8 @@ def set_panda_directory(panda_directory: Path) -> MsgGenerator:
222
224
  suffix = datetime.now().strftime("_%Y%m%d%H%M%S")
223
225
 
224
226
  async def set_panda_dir():
225
- await get_path_provider().update(directory=panda_directory, suffix=suffix)
227
+ await cast(UpdatingPathProvider, get_path_provider()).update(
228
+ directory=panda_directory, suffix=suffix
229
+ )
226
230
 
227
231
  yield from bps.wait_for([set_panda_dir])
@@ -47,7 +47,7 @@ def bluesky_retry(func: Callable):
47
47
 
48
48
 
49
49
  def arm_zebra(zebra: Zebra):
50
- yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
50
+ yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True)
51
51
 
52
52
 
53
53
  def tidy_up_zebra_after_rotation_scan(
@@ -56,7 +56,7 @@ def tidy_up_zebra_after_rotation_scan(
56
56
  group="tidy_up_zebra_after_rotation",
57
57
  wait=True,
58
58
  ):
59
- yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, group=group) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
59
+ yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, group=group)
60
60
  yield from bps.abs_set(
61
61
  zebra_shutter.control_mode, ZebraShutterControl.MANUAL, group=group
62
62
  )
@@ -16,10 +16,10 @@ def move_smargon_warn_on_out_of_range(
16
16
  "Pin tip centring failed - pin too long/short/bent and out of range"
17
17
  )
18
18
  yield from bps.mv(
19
- smargon.x, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
20
- position[0], # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
21
- smargon.y, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
22
- position[1], # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
23
- smargon.z, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
24
- position[2], # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
19
+ smargon.x,
20
+ position[0],
21
+ smargon.y,
22
+ position[1],
23
+ smargon.z,
24
+ position[2],
25
25
  )
@@ -44,7 +44,7 @@ def start_preparing_data_collection_then_do_plan(
44
44
  """
45
45
 
46
46
  def wrapped_plan():
47
- yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
47
+ yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
48
48
  if detector_distance_mm:
49
49
  yield from set_detector_z_position(
50
50
  detector_motion, detector_distance_mm, group
@@ -55,5 +55,5 @@ def start_preparing_data_collection_then_do_plan(
55
55
  yield from check_beamstop(beamstop)
56
56
  yield from bpp.contingency_wrapper(
57
57
  wrapped_plan(),
58
- except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
58
+ except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
59
59
  )
@@ -15,9 +15,6 @@ from mx_bluesky.hyperion.experiment_plans.load_centre_collect_full_plan import (
15
15
  from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan import (
16
16
  pin_tip_centre_then_xray_centre,
17
17
  )
18
- from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
19
- robot_load_then_centre,
20
- )
21
18
  from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
22
19
  multi_rotation_scan,
23
20
  rotation_scan,
@@ -29,6 +26,5 @@ __all__ = [
29
26
  "rotation_scan",
30
27
  "pin_tip_centre_then_xray_centre",
31
28
  "multi_rotation_scan",
32
- "robot_load_then_centre",
33
29
  "load_centre_collect_full",
34
30
  ]
@@ -1,13 +1,12 @@
1
1
  import bluesky.plan_stubs as bps
2
- import bluesky.preprocessors as bpp
3
2
  import numpy
4
3
  from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
5
4
  from dodal.devices.smargon import Smargon, StubPosition
6
5
 
7
6
  from mx_bluesky.common.utils.log import LOGGER
8
7
  from mx_bluesky.common.utils.tracing import TRACER
8
+ from mx_bluesky.common.xrc_result import XRayCentreResult
9
9
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_x_y_z
10
- from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult
11
10
  from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
12
11
 
13
12
 
@@ -21,17 +20,13 @@ def change_aperture_then_move_to_xtal(
21
20
  * Change the aperture so that the beam size is comparable to the crystal size
22
21
  * Centre on the centre-of-mass
23
22
  * Reset the stub offsets if specified by params"""
24
- if best_hit.bounding_box_mm is not None:
25
- bounding_box_size = numpy.abs(
26
- best_hit.bounding_box_mm[1] - best_hit.bounding_box_mm[0]
27
- )
28
- with TRACER.start_span("change_aperture"):
29
- yield from set_aperture_for_bbox_mm(
30
- aperture_scatterguard,
31
- bounding_box_size,
32
- )
33
- else:
34
- LOGGER.warning("No bounding box size received")
23
+ bounding_box_size = numpy.abs(
24
+ best_hit.bounding_box_mm[1] - best_hit.bounding_box_mm[0]
25
+ )
26
+ yield from set_aperture_for_bbox_mm(
27
+ aperture_scatterguard,
28
+ bounding_box_size,
29
+ )
35
30
 
36
31
  # once we have the results, go to the appropriate position
37
32
  LOGGER.info("Moving to centre of mass.")
@@ -43,11 +38,7 @@ def change_aperture_then_move_to_xtal(
43
38
  # https://github.com/DiamondLightSource/mx-bluesky/issues/552
44
39
  if parameters and parameters.FGS_params.set_stub_offsets:
45
40
  LOGGER.info("Recentring smargon co-ordinate system to this point.")
46
- yield from bps.mv(
47
- # See: https://github.com/bluesky/bluesky/issues/1809
48
- smargon.stub_offsets, # type: ignore
49
- StubPosition.CURRENT_AS_CENTER, # type: ignore
50
- )
41
+ yield from bps.mv(smargon.stub_offsets, StubPosition.CURRENT_AS_CENTER)
51
42
 
52
43
 
53
44
  def set_aperture_for_bbox_mm(
@@ -56,12 +47,12 @@ def set_aperture_for_bbox_mm(
56
47
  ):
57
48
  """Sets aperture size based on bbox_size.
58
49
 
59
- This function determines the aperture size needed to accomodate the bounding box
50
+ This function determines the aperture size needed to accommodate the bounding box
60
51
  of a crystal. The x-axis length of the bounding box is used, setting the aperture
61
52
  to Medium if this is less than 50um, and Large otherwise.
62
53
 
63
54
  Args:
64
- aperture_device: The aperture scatter gaurd device we are controlling.
55
+ aperture_device: The aperture scatter guard device we are controlling.
65
56
  bbox_size_mm: The [x,y,z] lengths, in mm, of a bounding box
66
57
  containing a crystal. This describes (in no particular order):
67
58
  * The maximum width a crystal occupies
@@ -81,14 +72,4 @@ def set_aperture_for_bbox_mm(
81
72
  f"Setting aperture to {new_selected_aperture} based on bounding box size {bbox_size_mm}."
82
73
  )
83
74
 
84
- @bpp.set_run_key_decorator("change_aperture")
85
- @bpp.run_decorator(
86
- md={
87
- "subplan_name": "change_aperture",
88
- "aperture_size": new_selected_aperture.value,
89
- }
90
- )
91
- def set_aperture():
92
- yield from bps.abs_set(aperture_device, new_selected_aperture)
93
-
94
- yield from set_aperture()
75
+ yield from bps.abs_set(aperture_device, new_selected_aperture)
@@ -9,7 +9,6 @@ from mx_bluesky.hyperion.experiment_plans import (
9
9
  grid_detect_then_xray_centre_plan,
10
10
  load_centre_collect_full_plan,
11
11
  pin_centre_then_xray_centre_plan,
12
- robot_load_then_centre_plan,
13
12
  )
14
13
  from mx_bluesky.hyperion.parameters.gridscan import (
15
14
  GridScanWithEdgeDetect,
@@ -17,7 +16,6 @@ from mx_bluesky.hyperion.parameters.gridscan import (
17
16
  PinTipCentreThenXrayCentre,
18
17
  )
19
18
  from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
20
- from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre
21
19
  from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan, RotationScan
22
20
 
23
21
 
@@ -38,7 +36,6 @@ class ExperimentRegistryEntry(TypedDict):
38
36
  | MultiRotationScan
39
37
  | PinTipCentreThenXrayCentre
40
38
  | LoadCentreCollect
41
- | RobotLoadThenCentre
42
39
  ]
43
40
 
44
41
 
@@ -59,10 +56,6 @@ PLAN_REGISTRY: dict[str, ExperimentRegistryEntry] = {
59
56
  "setup": pin_centre_then_xray_centre_plan.create_devices,
60
57
  "param_type": PinTipCentreThenXrayCentre,
61
58
  },
62
- "robot_load_then_centre": {
63
- "setup": robot_load_then_centre_plan.create_devices,
64
- "param_type": RobotLoadThenCentre,
65
- },
66
59
  "multi_rotation_scan": {
67
60
  "setup": rotation_scan_plan.create_devices,
68
61
  "param_type": MultiRotationScan,
@@ -9,59 +9,45 @@ from typing import Protocol
9
9
  import bluesky.plan_stubs as bps
10
10
  import bluesky.preprocessors as bpp
11
11
  import numpy as np
12
- import pydantic
13
12
  from blueapi.core import BlueskyContext
14
- from bluesky.callbacks import CallbackBase
15
13
  from bluesky.utils import MsgGenerator
16
- from dodal.devices.aperturescatterguard import (
17
- ApertureScatterguard,
18
- )
19
- from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
20
- from dodal.devices.backlight import Backlight
21
- from dodal.devices.dcm import DCM
22
- from dodal.devices.eiger import EigerDetector
23
14
  from dodal.devices.fast_grid_scan import (
24
15
  FastGridScanCommon,
25
- PandAFastGridScan,
26
- ZebraFastGridScan,
27
16
  )
28
17
  from dodal.devices.fast_grid_scan import (
29
18
  set_fast_grid_scan_params as set_flyscan_params,
30
19
  )
31
- from dodal.devices.flux import Flux
32
- from dodal.devices.robot import BartRobot
33
- from dodal.devices.s4_slit_gaps import S4SlitGaps
34
- from dodal.devices.smargon import Smargon
35
- from dodal.devices.synchrotron import Synchrotron
36
- from dodal.devices.undulator import Undulator
37
- from dodal.devices.xbpm_feedback import XBPMFeedback
38
20
  from dodal.devices.zebra.zebra import Zebra
39
- from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
40
21
  from dodal.devices.zocalo.zocalo_results import (
41
22
  ZOCALO_READING_PLAN_NAME,
42
23
  ZOCALO_STAGE_GROUP,
43
24
  XrcResult,
44
- ZocaloResults,
45
25
  get_full_processing_results,
46
26
  )
47
- from event_model import RunStart
48
- from ophyd_async.fastcs.panda import HDFPanda
27
+ from dodal.plans.preprocessors.verify_undulator_gap import (
28
+ verify_undulator_gap_before_run_decorator,
29
+ )
49
30
 
50
31
  from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
51
32
  ispyb_activation_wrapper,
52
33
  )
53
34
  from mx_bluesky.common.parameters.constants import HardwareConstants
54
35
  from mx_bluesky.common.plans.do_fgs import kickoff_and_complete_gridscan
36
+ from mx_bluesky.common.plans.read_hardware import (
37
+ standard_read_hardware_during_collection,
38
+ standard_read_hardware_pre_collection,
39
+ )
40
+ from mx_bluesky.common.preprocessors.preprocessors import (
41
+ transmission_and_xbpm_feedback_for_collection_decorator,
42
+ )
43
+ from mx_bluesky.common.utils.context import device_composite_from_context
55
44
  from mx_bluesky.common.utils.exceptions import (
56
45
  CrystalNotFoundException,
57
46
  SampleException,
58
47
  )
59
48
  from mx_bluesky.common.utils.log import LOGGER
60
49
  from mx_bluesky.common.utils.tracing import TRACER
61
- from mx_bluesky.hyperion.device_setup_plans.read_hardware_for_setup import (
62
- read_hardware_during_collection,
63
- read_hardware_pre_collection,
64
- )
50
+ from mx_bluesky.common.xrc_result import XRayCentreEventHandler, XRayCentreResult
65
51
  from mx_bluesky.hyperion.device_setup_plans.setup_panda import (
66
52
  disarm_panda_for_gridscan,
67
53
  set_panda_directory,
@@ -72,16 +58,14 @@ from mx_bluesky.hyperion.device_setup_plans.setup_zebra import (
72
58
  setup_zebra_for_panda_flyscan,
73
59
  tidy_up_zebra_after_gridscan,
74
60
  )
75
- from mx_bluesky.hyperion.device_setup_plans.xbpm_feedback import (
76
- transmission_and_xbpm_feedback_for_collection_decorator,
77
- )
78
61
  from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import (
79
62
  change_aperture_then_move_to_xtal,
80
63
  )
81
- from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult
82
64
  from mx_bluesky.hyperion.parameters.constants import CONST
65
+ from mx_bluesky.hyperion.parameters.device_composites import (
66
+ HyperionFlyScanXRayCentreComposite,
67
+ )
83
68
  from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
84
- from mx_bluesky.hyperion.utils.context import device_composite_from_context
85
69
 
86
70
  ZOCALO_MIN_TOTAL_COUNT_THRESHOLD = 3
87
71
 
@@ -90,56 +74,21 @@ class SmargonSpeedException(Exception):
90
74
  pass
91
75
 
92
76
 
93
- @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
94
- class FlyScanXRayCentreComposite:
95
- """All devices which are directly or indirectly required by this plan"""
96
-
97
- aperture_scatterguard: ApertureScatterguard
98
- attenuator: BinaryFilterAttenuator
99
- backlight: Backlight
100
- dcm: DCM
101
- eiger: EigerDetector
102
- zebra_fast_grid_scan: ZebraFastGridScan
103
- flux: Flux
104
- s4_slit_gaps: S4SlitGaps
105
- smargon: Smargon
106
- undulator: Undulator
107
- synchrotron: Synchrotron
108
- xbpm_feedback: XBPMFeedback
109
- zebra: Zebra
110
- zocalo: ZocaloResults
111
- panda: HDFPanda
112
- panda_fast_grid_scan: PandAFastGridScan
113
- robot: BartRobot
114
- sample_shutter: ZebraShutter
115
-
116
-
117
- class XRayCentreEventHandler(CallbackBase):
118
- def __init__(self):
119
- super().__init__()
120
- self.xray_centre_results: Sequence[XRayCentreResult] | None = None
121
-
122
- def start(self, doc: RunStart) -> RunStart | None:
123
- if CONST.PLAN.FLYSCAN_RESULTS in doc:
124
- self.xray_centre_results = [
125
- XRayCentreResult(**result_dict)
126
- for result_dict in doc[CONST.PLAN.FLYSCAN_RESULTS] # type: ignore
127
- ]
128
- return doc
129
-
130
-
131
- def create_devices(context: BlueskyContext) -> FlyScanXRayCentreComposite:
77
+ def create_devices(context: BlueskyContext) -> HyperionFlyScanXRayCentreComposite:
132
78
  """Creates the devices required for the plan and connect to them"""
133
- return device_composite_from_context(context, FlyScanXRayCentreComposite)
79
+ return device_composite_from_context(context, HyperionFlyScanXRayCentreComposite)
134
80
 
135
81
 
136
82
  def flyscan_xray_centre_no_move(
137
- composite: FlyScanXRayCentreComposite, parameters: HyperionSpecifiedThreeDGridScan
83
+ composite: HyperionFlyScanXRayCentreComposite,
84
+ parameters: HyperionSpecifiedThreeDGridScan,
138
85
  ) -> MsgGenerator:
139
86
  """Perform a flyscan and determine the centres of interest"""
140
- parameters.features.update_self_from_server()
87
+
141
88
  composite.eiger.set_detector_parameters(parameters.detector_params)
142
89
  composite.zocalo.zocalo_environment = CONST.ZOCALO_ENV
90
+
91
+ parameters.features.update_self_from_server()
143
92
  composite.zocalo.use_cpu_and_gpu = parameters.features.compare_cpu_and_gpu_zocalo
144
93
  composite.zocalo.use_gpu = parameters.features.use_gpu_results
145
94
 
@@ -156,15 +105,8 @@ def flyscan_xray_centre_no_move(
156
105
  }
157
106
  )
158
107
  @bpp.finalize_decorator(lambda: feature_controlled.tidy_plan(composite))
159
- @transmission_and_xbpm_feedback_for_collection_decorator(
160
- composite.undulator,
161
- composite.xbpm_feedback,
162
- composite.attenuator,
163
- composite.dcm,
164
- parameters.transmission_frac,
165
- )
166
108
  def run_gridscan_and_fetch_and_tidy(
167
- fgs_composite: FlyScanXRayCentreComposite,
109
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
168
110
  params: HyperionSpecifiedThreeDGridScan,
169
111
  feature_controlled: _FeatureControlled,
170
112
  ) -> MsgGenerator:
@@ -178,7 +120,7 @@ def flyscan_xray_centre_no_move(
178
120
 
179
121
 
180
122
  def flyscan_xray_centre(
181
- composite: FlyScanXRayCentreComposite,
123
+ composite: HyperionFlyScanXRayCentreComposite,
182
124
  parameters: HyperionSpecifiedThreeDGridScan,
183
125
  ) -> MsgGenerator:
184
126
  """Create the plan to run the grid scan based on provided parameters.
@@ -194,6 +136,11 @@ def flyscan_xray_centre(
194
136
  """
195
137
  xrc_event_handler = XRayCentreEventHandler()
196
138
 
139
+ @transmission_and_xbpm_feedback_for_collection_decorator(
140
+ composite,
141
+ parameters.transmission_frac,
142
+ )
143
+ @verify_undulator_gap_before_run_decorator(composite)
197
144
  @bpp.subs_decorator(xrc_event_handler)
198
145
  def flyscan_and_fetch_results() -> MsgGenerator:
199
146
  yield from ispyb_activation_wrapper(
@@ -217,7 +164,7 @@ def flyscan_xray_centre(
217
164
  @bpp.set_run_key_decorator(CONST.PLAN.GRIDSCAN_AND_MOVE)
218
165
  @bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_AND_MOVE})
219
166
  def run_gridscan_and_fetch_results(
220
- fgs_composite: FlyScanXRayCentreComposite,
167
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
221
168
  parameters: HyperionSpecifiedThreeDGridScan,
222
169
  feature_controlled: _FeatureControlled,
223
170
  ) -> MsgGenerator:
@@ -265,7 +212,7 @@ def run_gridscan_and_fetch_results(
265
212
  finally:
266
213
  # Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
267
214
  LOGGER.info("Turning off Eiger dev/shm streaming")
268
- yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
215
+ yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
269
216
 
270
217
  # Wait on everything before returning to GDA (particularly apertures), can be removed
271
218
  # when we do not return to GDA here
@@ -314,7 +261,7 @@ def _fire_xray_centre_result_event(results: Sequence[XRayCentreResult]):
314
261
  @bpp.set_run_key_decorator(CONST.PLAN.GRIDSCAN_MAIN)
315
262
  @bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_MAIN})
316
263
  def run_gridscan(
317
- fgs_composite: FlyScanXRayCentreComposite,
264
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
318
265
  parameters: HyperionSpecifiedThreeDGridScan,
319
266
  feature_controlled: _FeatureControlled,
320
267
  md={ # noqa
@@ -329,7 +276,7 @@ def run_gridscan(
329
276
  # we should generate an event reading the values which need to be included in the
330
277
  # ispyb deposition
331
278
  with TRACER.start_span("ispyb_hardware_readings"):
332
- yield from read_hardware_pre_collection(
279
+ yield from standard_read_hardware_pre_collection(
333
280
  fgs_composite.undulator,
334
281
  fgs_composite.synchrotron,
335
282
  fgs_composite.s4_slit_gaps,
@@ -338,7 +285,7 @@ def run_gridscan(
338
285
  )
339
286
 
340
287
  read_during_collection = partial(
341
- read_hardware_during_collection,
288
+ standard_read_hardware_during_collection,
342
289
  fgs_composite.aperture_scatterguard,
343
290
  fgs_composite.attenuator,
344
291
  fgs_composite.flux,
@@ -354,7 +301,7 @@ def run_gridscan(
354
301
 
355
302
  LOGGER.info("Waiting for arming to finish")
356
303
  yield from bps.wait(CONST.WAIT.GRID_READY_FOR_DC)
357
- yield from bps.stage(fgs_composite.eiger) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
304
+ yield from bps.stage(fgs_composite.eiger)
358
305
 
359
306
  yield from kickoff_and_complete_gridscan(
360
307
  feature_controlled.fgs_motors,
@@ -394,18 +341,18 @@ class _FeatureControlled:
394
341
  class _ExtraSetup(Protocol):
395
342
  def __call__(
396
343
  self,
397
- fgs_composite: FlyScanXRayCentreComposite,
344
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
398
345
  parameters: HyperionSpecifiedThreeDGridScan,
399
346
  ) -> MsgGenerator: ...
400
347
 
401
348
  setup_trigger: _ExtraSetup
402
- tidy_plan: Callable[[FlyScanXRayCentreComposite], MsgGenerator]
349
+ tidy_plan: Callable[[HyperionFlyScanXRayCentreComposite], MsgGenerator]
403
350
  set_flyscan_params: Callable[[], MsgGenerator]
404
351
  fgs_motors: FastGridScanCommon
405
352
 
406
353
 
407
354
  def _get_feature_controlled(
408
- fgs_composite: FlyScanXRayCentreComposite,
355
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
409
356
  parameters: HyperionSpecifiedThreeDGridScan,
410
357
  ):
411
358
  if parameters.features.use_panda_for_gridscan:
@@ -433,7 +380,7 @@ def _get_feature_controlled(
433
380
 
434
381
 
435
382
  def _generic_tidy(
436
- fgs_composite: FlyScanXRayCentreComposite, group, wait=True
383
+ fgs_composite: HyperionFlyScanXRayCentreComposite, group, wait=True
437
384
  ) -> MsgGenerator:
438
385
  LOGGER.info("Tidying up Zebra")
439
386
  yield from tidy_up_zebra_after_gridscan(
@@ -444,7 +391,7 @@ def _generic_tidy(
444
391
  yield from bps.unstage(fgs_composite.zocalo, group=group, wait=wait)
445
392
 
446
393
 
447
- def _panda_tidy(fgs_composite: FlyScanXRayCentreComposite):
394
+ def _panda_tidy(fgs_composite: HyperionFlyScanXRayCentreComposite):
448
395
  group = "panda_flyscan_tidy"
449
396
  LOGGER.info("Disabling panda blocks")
450
397
  yield from disarm_panda_for_gridscan(fgs_composite.panda, group)
@@ -454,7 +401,7 @@ def _panda_tidy(fgs_composite: FlyScanXRayCentreComposite):
454
401
 
455
402
 
456
403
  def _zebra_triggering_setup(
457
- fgs_composite: FlyScanXRayCentreComposite,
404
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
458
405
  parameters: HyperionSpecifiedThreeDGridScan,
459
406
  ):
460
407
  yield from setup_zebra_for_gridscan(
@@ -463,7 +410,7 @@ def _zebra_triggering_setup(
463
410
 
464
411
 
465
412
  def _panda_triggering_setup(
466
- fgs_composite: FlyScanXRayCentreComposite,
413
+ fgs_composite: HyperionFlyScanXRayCentreComposite,
467
414
  parameters: HyperionSpecifiedThreeDGridScan,
468
415
  ):
469
416
  LOGGER.info("Setting up Panda for flyscan")
@@ -498,8 +445,8 @@ def _panda_triggering_setup(
498
445
  )
499
446
 
500
447
  yield from bps.mv(
501
- fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
502
- time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
448
+ fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms,
449
+ time_between_x_steps_ms,
503
450
  )
504
451
 
505
452
  directory_provider_root = Path(parameters.storage_directory)
@@ -39,7 +39,9 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback
39
39
  ispyb_activation_wrapper,
40
40
  )
41
41
  from mx_bluesky.common.parameters.constants import OavConstants
42
+ from mx_bluesky.common.utils.context import device_composite_from_context
42
43
  from mx_bluesky.common.utils.log import LOGGER
44
+ from mx_bluesky.common.xrc_result import XRayCentreEventHandler
43
45
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
44
46
  move_aperture_if_required,
45
47
  )
@@ -50,10 +52,6 @@ from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import
50
52
  change_aperture_then_move_to_xtal,
51
53
  )
52
54
  from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
53
- FlyScanXRayCentreComposite as FlyScanXRayCentreComposite,
54
- )
55
- from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
56
- XRayCentreEventHandler,
57
55
  flyscan_xray_centre_no_move,
58
56
  )
59
57
  from mx_bluesky.hyperion.experiment_plans.oav_grid_detection_plan import (
@@ -61,11 +59,13 @@ from mx_bluesky.hyperion.experiment_plans.oav_grid_detection_plan import (
61
59
  grid_detection_plan,
62
60
  )
63
61
  from mx_bluesky.hyperion.parameters.constants import CONST
62
+ from mx_bluesky.hyperion.parameters.device_composites import (
63
+ HyperionFlyScanXRayCentreComposite,
64
+ )
64
65
  from mx_bluesky.hyperion.parameters.gridscan import (
65
66
  GridScanWithEdgeDetect,
66
67
  HyperionSpecifiedThreeDGridScan,
67
68
  )
68
- from mx_bluesky.hyperion.utils.context import device_composite_from_context
69
69
 
70
70
 
71
71
  @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
@@ -167,7 +167,7 @@ def detect_grid_and_do_gridscan(
167
167
  )
168
168
 
169
169
  yield from flyscan_xray_centre_no_move(
170
- FlyScanXRayCentreComposite(
170
+ HyperionFlyScanXRayCentreComposite(
171
171
  aperture_scatterguard=composite.aperture_scatterguard,
172
172
  attenuator=composite.attenuator,
173
173
  backlight=composite.backlight,
@@ -8,11 +8,11 @@ from bluesky.preprocessors import run_decorator, set_run_key_decorator, subs_wra
8
8
  from bluesky.utils import MsgGenerator
9
9
  from dodal.devices.oav.oav_parameters import OAVParameters
10
10
 
11
- import mx_bluesky.hyperion.experiment_plans.common.xrc_result as flyscan_result
11
+ import mx_bluesky.common.xrc_result as flyscan_result
12
+ from mx_bluesky.common.parameters.components import WithSnapshot
13
+ from mx_bluesky.common.utils.context import device_composite_from_context
12
14
  from mx_bluesky.common.utils.log import LOGGER
13
- from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
14
- XRayCentreEventHandler,
15
- )
15
+ from mx_bluesky.common.xrc_result import XRayCentreEventHandler
16
16
  from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
17
17
  RobotLoadThenCentreComposite,
18
18
  robot_load_then_xray_centre,
@@ -24,7 +24,6 @@ from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
24
24
  )
25
25
  from mx_bluesky.hyperion.parameters.constants import CONST
26
26
  from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
27
- from mx_bluesky.hyperion.utils.context import device_composite_from_context
28
27
 
29
28
 
30
29
  @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
@@ -56,7 +55,10 @@ def load_centre_collect_full(
56
55
  @run_decorator(
57
56
  md={
58
57
  "metadata": {"sample_id": parameters.sample_id},
59
- "activate_callbacks": ["SampleHandlingCallback"],
58
+ "activate_callbacks": ["BeamDrawingCallback", "SampleHandlingCallback"],
59
+ "with_snapshot": parameters.multi_rotation_scan.model_dump_json(
60
+ include=WithSnapshot.model_fields.keys() # type: ignore
61
+ ),
60
62
  }
61
63
  )
62
64
  def plan_with_callback_subs():
@@ -14,13 +14,13 @@ from dodal.devices.oav.pin_image_recognition.utils import NONE_VALUE
14
14
  from dodal.devices.oav.utils import PinNotFoundException, wait_for_tip_to_be_found
15
15
  from dodal.devices.smargon import Smargon
16
16
 
17
+ from mx_bluesky.common.utils.context import device_composite_from_context
17
18
  from mx_bluesky.common.utils.exceptions import catch_exception_and_warn
18
19
  from mx_bluesky.common.utils.log import LOGGER
19
20
  from mx_bluesky.hyperion.device_setup_plans.setup_oav import (
20
21
  pre_centring_setup_oav,
21
22
  )
22
23
  from mx_bluesky.hyperion.parameters.constants import CONST
23
- from mx_bluesky.hyperion.utils.context import device_composite_from_context
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  from dodal.devices.oav.oav_parameters import OAVParameters
@@ -100,7 +100,7 @@ def grid_detection_plan(
100
100
 
101
101
  # The FGS uses -90 so we need to match it
102
102
  for angle in [0, -90]:
103
- yield from bps.mv(smargon.omega, angle) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
103
+ yield from bps.mv(smargon.omega, angle)
104
104
  # need to wait for the OAV image to update
105
105
  # See #673 for improvements
106
106
  yield from bps.sleep(CONST.HARDWARE.OAV_REFRESH_DELAY)
@@ -152,20 +152,20 @@ def grid_detection_plan(
152
152
 
153
153
  upper_left = (tip_x_px, min_y)
154
154
 
155
- yield from bps.abs_set(oav.grid_snapshot.top_left_x, upper_left[0]) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
156
- yield from bps.abs_set(oav.grid_snapshot.top_left_y, upper_left[1]) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
157
- yield from bps.abs_set(oav.grid_snapshot.box_width, box_size_x_pixels) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
158
- yield from bps.abs_set(oav.grid_snapshot.num_boxes_x, x_steps) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
159
- yield from bps.abs_set(oav.grid_snapshot.num_boxes_y, y_steps) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
155
+ yield from bps.abs_set(oav.grid_snapshot.top_left_x, upper_left[0])
156
+ yield from bps.abs_set(oav.grid_snapshot.top_left_y, upper_left[1])
157
+ yield from bps.abs_set(oav.grid_snapshot.box_width, box_size_x_pixels)
158
+ yield from bps.abs_set(oav.grid_snapshot.num_boxes_x, x_steps)
159
+ yield from bps.abs_set(oav.grid_snapshot.num_boxes_y, y_steps)
160
160
 
161
161
  snapshot_filename = snapshot_template.format(angle=abs(angle))
162
162
 
163
- yield from bps.abs_set(oav.grid_snapshot.filename, snapshot_filename) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
164
- yield from bps.abs_set(oav.grid_snapshot.directory, snapshot_dir) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
165
- yield from bps.trigger(oav.grid_snapshot, wait=True) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
163
+ yield from bps.abs_set(oav.grid_snapshot.filename, snapshot_filename)
164
+ yield from bps.abs_set(oav.grid_snapshot.directory, snapshot_dir)
165
+ yield from bps.trigger(oav.grid_snapshot, wait=True)
166
166
  yield from bps.create(CONST.DESCRIPTORS.OAV_GRID_SNAPSHOT_TRIGGERED)
167
167
 
168
- yield from bps.read(oav) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
168
+ yield from bps.read(oav)
169
169
  yield from bps.read(smargon)
170
170
  yield from bps.save()
171
171