mx-bluesky 1.2.0__py3-none-any.whl → 1.4.0__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 (77) hide show
  1. mx_bluesky/__init__.py +8 -3
  2. mx_bluesky/__main__.py +12 -7
  3. mx_bluesky/_version.py +2 -2
  4. mx_bluesky/beamlines/i04/callbacks/murko_callback.py +14 -4
  5. mx_bluesky/beamlines/i04/thawing_plan.py +48 -10
  6. mx_bluesky/beamlines/i24/serial/__init__.py +3 -0
  7. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +68 -90
  8. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +1 -1
  9. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +104 -126
  10. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +139 -162
  11. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +25 -36
  12. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +24 -34
  13. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +14 -11
  14. mx_bluesky/beamlines/i24/serial/log.py +58 -49
  15. mx_bluesky/beamlines/i24/serial/parameters/fixed_target/cs/cs_maker.json +3 -3
  16. mx_bluesky/beamlines/i24/serial/run_extruder.sh +30 -5
  17. mx_bluesky/beamlines/i24/serial/run_fixed_target.sh +31 -7
  18. mx_bluesky/beamlines/i24/serial/run_serial.py +24 -8
  19. mx_bluesky/beamlines/i24/serial/setup_beamline/ca.py +0 -2
  20. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +1 -1
  21. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +8 -18
  22. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +2 -2
  23. mx_bluesky/common/__init__.py +0 -0
  24. mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +14 -0
  25. mx_bluesky/common/parameters/components.py +221 -0
  26. mx_bluesky/common/parameters/constants.py +133 -0
  27. mx_bluesky/common/plans/__init__.py +1 -0
  28. mx_bluesky/common/plans/do_fgs.py +121 -0
  29. mx_bluesky/common/utils/log.py +116 -0
  30. mx_bluesky/{hyperion → common/utils}/tracing.py +2 -2
  31. mx_bluesky/hyperion/__main__.py +11 -9
  32. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +31 -26
  33. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +6 -12
  34. mx_bluesky/hyperion/device_setup_plans/setup_oav.py +6 -12
  35. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +1 -2
  36. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +48 -17
  37. mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
  38. mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
  39. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +4 -4
  40. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +25 -83
  41. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +7 -5
  42. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +19 -18
  43. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +8 -5
  44. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +4 -4
  45. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +17 -17
  46. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +15 -11
  47. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +6 -3
  48. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +6 -4
  49. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +3 -3
  50. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +1 -2
  51. mx_bluesky/hyperion/external_interaction/callbacks/common/ispyb_mapping.py +1 -1
  52. mx_bluesky/hyperion/external_interaction/callbacks/grid_detection_callback.py +18 -13
  53. mx_bluesky/hyperion/external_interaction/callbacks/ispyb_callback_base.py +29 -12
  54. mx_bluesky/hyperion/external_interaction/callbacks/log_uid_tag_callback.py +1 -1
  55. mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +1 -1
  56. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +4 -3
  57. mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/ispyb_callback.py +23 -18
  58. mx_bluesky/hyperion/external_interaction/config_server.py +22 -10
  59. mx_bluesky/hyperion/external_interaction/ispyb/ispyb_store.py +1 -1
  60. mx_bluesky/hyperion/external_interaction/nexus/nexus_utils.py +2 -2
  61. mx_bluesky/hyperion/external_interaction/nexus/write_nexus.py +1 -1
  62. mx_bluesky/hyperion/log.py +0 -84
  63. mx_bluesky/hyperion/parameters/components.py +1 -243
  64. mx_bluesky/hyperion/parameters/constants.py +22 -118
  65. mx_bluesky/hyperion/parameters/gridscan.py +13 -9
  66. mx_bluesky/hyperion/parameters/load_centre_collect.py +3 -3
  67. mx_bluesky/hyperion/parameters/robot_load.py +3 -3
  68. mx_bluesky/hyperion/parameters/rotation.py +9 -5
  69. mx_bluesky/hyperion/utils/utils.py +17 -0
  70. mx_bluesky/hyperion/utils/validation.py +5 -6
  71. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/METADATA +4 -2
  72. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/RECORD +76 -70
  73. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/WHEEL +1 -1
  74. mx_bluesky/example.py +0 -19
  75. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/LICENSE +0 -0
  76. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/entry_points.txt +0 -0
  77. {mx_bluesky-1.2.0.dist-info → mx_bluesky-1.4.0.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,6 @@ import dataclasses
4
4
  from collections.abc import Callable
5
5
  from functools import partial
6
6
  from pathlib import Path
7
- from time import time
8
7
  from typing import Protocol
9
8
 
10
9
  import bluesky.plan_stubs as bps
@@ -40,16 +39,15 @@ from dodal.devices.zocalo.zocalo_results import (
40
39
  ZOCALO_READING_PLAN_NAME,
41
40
  ZOCALO_STAGE_GROUP,
42
41
  ZocaloResults,
43
- get_processing_result,
42
+ get_full_processing_results,
44
43
  )
45
- from dodal.plans.check_topup import check_topup_and_wait_if_necessary
46
44
  from ophyd_async.fastcs.panda import HDFPanda
47
- from scanspec.core import AxesPoints, Axis
48
45
 
46
+ from mx_bluesky.common.plans.do_fgs import kickoff_and_complete_gridscan
47
+ from mx_bluesky.common.utils.tracing import TRACER
49
48
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_x_y_z
50
49
  from mx_bluesky.hyperion.device_setup_plans.read_hardware_for_setup import (
51
50
  read_hardware_during_collection,
52
- read_hardware_for_zocalo,
53
51
  read_hardware_pre_collection,
54
52
  )
55
53
  from mx_bluesky.hyperion.device_setup_plans.setup_panda import (
@@ -69,7 +67,6 @@ from mx_bluesky.hyperion.exceptions import WarningException
69
67
  from mx_bluesky.hyperion.log import LOGGER
70
68
  from mx_bluesky.hyperion.parameters.constants import CONST
71
69
  from mx_bluesky.hyperion.parameters.gridscan import ThreeDGridScan
72
- from mx_bluesky.hyperion.tracing import TRACER
73
70
  from mx_bluesky.hyperion.utils.context import device_composite_from_context
74
71
 
75
72
 
@@ -134,8 +131,8 @@ def flyscan_xray_centre(
134
131
  """
135
132
  parameters.features.update_self_from_server()
136
133
  composite.eiger.set_detector_parameters(parameters.detector_params)
137
- composite.zocalo.zocalo_environment = parameters.zocalo_environment
138
- composite.zocalo.use_cpu_and_gpu = parameters.use_cpu_and_gpu_zocalo
134
+ composite.zocalo.zocalo_environment = CONST.ZOCALO_ENV
135
+ composite.zocalo.use_cpu_and_gpu = parameters.features.compare_cpu_and_gpu_zocalo
139
136
 
140
137
  feature_controlled = _get_feature_controlled(composite, parameters)
141
138
 
@@ -143,8 +140,6 @@ def flyscan_xray_centre(
143
140
  @bpp.run_decorator( # attach experiment metadata to the start document
144
141
  md={
145
142
  "subplan_name": CONST.PLAN.GRIDSCAN_OUTER,
146
- CONST.TRIGGER.ZOCALO: CONST.PLAN.DO_FGS,
147
- "zocalo_environment": parameters.zocalo_environment,
148
143
  "hyperion_parameters": parameters.model_dump_json(),
149
144
  "activate_callbacks": [
150
145
  "GridscanNexusFileCallback",
@@ -202,24 +197,25 @@ def run_gridscan_and_move(
202
197
  [fgs_composite.zocalo], name=ZOCALO_READING_PLAN_NAME
203
198
  )
204
199
  LOGGER.info("Zocalo triggered and read, interpreting results.")
205
- xray_centre, bbox_size = yield from get_processing_result(
206
- fgs_composite.zocalo
207
- )
208
- LOGGER.info(f"Got xray centre: {xray_centre}, bbox size: {bbox_size}")
209
- if xray_centre is not None:
200
+ xrc_results = yield from get_full_processing_results(fgs_composite.zocalo)
201
+ LOGGER.info(f"Got xray centring results: {xrc_results}")
202
+ if xrc_results:
203
+ best_result = xrc_results[0]
204
+ xrc_centre_grid_coords = best_result["centre_of_mass"]
210
205
  xray_centre = parameters.FGS_params.grid_position_to_motor_position(
211
- xray_centre
206
+ np.array(xrc_centre_grid_coords)
212
207
  )
213
- else:
214
- LOGGER.warning("No X-ray centre received")
215
- raise CrystalNotFoundException()
216
- if bbox_size is not None:
217
208
  with TRACER.start_span("change_aperture"):
209
+ bbox_size = np.abs(
210
+ np.array(best_result["bounding_box"][1])
211
+ - np.array(best_result["bounding_box"][0])
212
+ )
218
213
  yield from set_aperture_for_bbox_size(
219
214
  fgs_composite.aperture_scatterguard, bbox_size
220
215
  )
221
216
  else:
222
- LOGGER.warning("No bounding box size received")
217
+ LOGGER.warning("No X-ray centre received")
218
+ raise CrystalNotFoundException()
223
219
 
224
220
  # once we have the results, go to the appropriate position
225
221
  LOGGER.info("Moving to centre of mass.")
@@ -230,12 +226,13 @@ def run_gridscan_and_move(
230
226
  if parameters.FGS_params.set_stub_offsets:
231
227
  LOGGER.info("Recentring smargon co-ordinate system to this point.")
232
228
  yield from bps.mv(
233
- fgs_composite.sample_motors.stub_offsets, StubPosition.CURRENT_AS_CENTER
229
+ fgs_composite.sample_motors.stub_offsets, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
230
+ StubPosition.CURRENT_AS_CENTER, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
234
231
  )
235
232
  finally:
236
233
  # Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
237
234
  LOGGER.info("Turning off Eiger dev/shm streaming")
238
- yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0)
235
+ yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
239
236
 
240
237
  # Wait on everything before returning to GDA (particularly apertures), can be removed
241
238
  # when we do not return to GDA here
@@ -266,7 +263,7 @@ def run_gridscan(
266
263
  fgs_composite.undulator,
267
264
  fgs_composite.synchrotron,
268
265
  fgs_composite.s4_slit_gaps,
269
- fgs_composite.robot,
266
+ fgs_composite.dcm,
270
267
  fgs_composite.smargon,
271
268
  )
272
269
 
@@ -287,7 +284,7 @@ def run_gridscan(
287
284
 
288
285
  LOGGER.info("Waiting for arming to finish")
289
286
  yield from bps.wait(CONST.WAIT.GRID_READY_FOR_DC)
290
- yield from bps.stage(fgs_composite.eiger)
287
+ yield from bps.stage(fgs_composite.eiger) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
291
288
 
292
289
  yield from kickoff_and_complete_gridscan(
293
290
  feature_controlled.fgs_motors,
@@ -295,66 +292,11 @@ def run_gridscan(
295
292
  fgs_composite.synchrotron,
296
293
  [parameters.scan_points_first_grid, parameters.scan_points_second_grid],
297
294
  parameters.scan_indices,
298
- do_during_run=read_during_collection,
295
+ plan_during_collection=read_during_collection,
299
296
  )
300
297
  yield from bps.abs_set(feature_controlled.fgs_motors.z_steps, 0, wait=False)
301
298
 
302
299
 
303
- def kickoff_and_complete_gridscan(
304
- gridscan: FastGridScanCommon,
305
- eiger: EigerDetector,
306
- synchrotron: Synchrotron,
307
- scan_points: list[AxesPoints[Axis]],
308
- scan_start_indices: list[int],
309
- do_during_run: Callable[[], MsgGenerator] | None = None,
310
- ):
311
- @TRACER.start_as_current_span(CONST.PLAN.DO_FGS)
312
- @bpp.set_run_key_decorator(CONST.PLAN.DO_FGS)
313
- @bpp.run_decorator(
314
- md={
315
- "subplan_name": CONST.PLAN.DO_FGS,
316
- "scan_points": scan_points,
317
- "scan_start_indices": scan_start_indices,
318
- }
319
- )
320
- @bpp.contingency_decorator(
321
- except_plan=lambda e: (yield from bps.stop(eiger)),
322
- else_plan=lambda: (yield from bps.unstage(eiger)),
323
- )
324
- def do_fgs():
325
- # Check topup gate
326
- expected_images = yield from bps.rd(gridscan.expected_images)
327
- exposure_sec_per_image = yield from bps.rd(eiger.cam.acquire_time)
328
- LOGGER.info("waiting for topup if necessary...")
329
- yield from check_topup_and_wait_if_necessary(
330
- synchrotron,
331
- expected_images * exposure_sec_per_image,
332
- 30.0,
333
- )
334
- yield from read_hardware_for_zocalo(eiger)
335
- LOGGER.info("Wait for all moves with no assigned group")
336
- yield from bps.wait()
337
- LOGGER.info("kicking off FGS")
338
- yield from bps.kickoff(gridscan, wait=True)
339
- gridscan_start_time = time()
340
- LOGGER.info("Waiting for Zocalo device queue to have been cleared...")
341
- yield from bps.wait(
342
- ZOCALO_STAGE_GROUP
343
- ) # Make sure ZocaloResults queue is clear and ready to accept our new data
344
- if do_during_run:
345
- LOGGER.info(f"Running {do_during_run} during FGS")
346
- yield from do_during_run()
347
- LOGGER.info("completing FGS")
348
- yield from bps.complete(gridscan, wait=True)
349
-
350
- # Remove this logging statement once metrics have been added
351
- LOGGER.info(
352
- f"Gridscan motion program took {round(time()-gridscan_start_time,2)} to complete"
353
- )
354
-
355
- yield from do_fgs()
356
-
357
-
358
300
  def wait_for_gridscan_valid(fgs_motors: FastGridScanCommon, timeout=0.5):
359
301
  LOGGER.info("Waiting for valid fgs_params")
360
302
  SLEEP_PER_CHECK = 0.1
@@ -515,8 +457,8 @@ def _panda_triggering_setup(
515
457
  )
516
458
 
517
459
  yield from bps.mv(
518
- fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms,
519
- time_between_x_steps_ms,
460
+ fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
461
+ time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
520
462
  )
521
463
 
522
464
  directory_provider_root = Path(parameters.storage_directory)
@@ -15,7 +15,7 @@ from dodal.devices.eiger import EigerDetector
15
15
  from dodal.devices.fast_grid_scan import PandAFastGridScan, ZebraFastGridScan
16
16
  from dodal.devices.flux import Flux
17
17
  from dodal.devices.oav.oav_detector import OAV
18
- from dodal.devices.oav.oav_parameters import OAV_CONFIG_JSON, OAVParameters
18
+ from dodal.devices.oav.oav_parameters import OAVParameters
19
19
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
20
20
  from dodal.devices.robot import BartRobot
21
21
  from dodal.devices.s4_slit_gaps import S4SlitGaps
@@ -28,6 +28,7 @@ from dodal.devices.zebra_controlled_shutter import ZebraShutter
28
28
  from dodal.devices.zocalo import ZocaloResults
29
29
  from ophyd_async.fastcs.panda import HDFPanda
30
30
 
31
+ from mx_bluesky.common.parameters.constants import OavConstants
31
32
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
32
33
  move_aperture_if_required,
33
34
  )
@@ -109,7 +110,7 @@ def detect_grid_and_do_gridscan(
109
110
  ):
110
111
  snapshot_template = f"{parameters.detector_params.prefix}_{parameters.detector_params.run_number}_{{angle}}"
111
112
 
112
- grid_params_callback = GridDetectionCallback(composite.oav.parameters)
113
+ grid_params_callback = GridDetectionCallback()
113
114
 
114
115
  @bpp.subs_decorator([grid_params_callback])
115
116
  def run_grid_detection_plan(
@@ -129,7 +130,8 @@ def detect_grid_and_do_gridscan(
129
130
  oav_params,
130
131
  snapshot_template,
131
132
  str(snapshot_dir),
132
- grid_width_microns=parameters.grid_width_um,
133
+ parameters.grid_width_um,
134
+ parameters.box_size_um,
133
135
  )
134
136
 
135
137
  yield from run_grid_detection_plan(
@@ -178,7 +180,7 @@ def detect_grid_and_do_gridscan(
178
180
  def grid_detect_then_xray_centre(
179
181
  composite: GridDetectThenXRayCentreComposite,
180
182
  parameters: GridScanWithEdgeDetect,
181
- oav_config: str = OAV_CONFIG_JSON,
183
+ oav_config: str = OavConstants.OAV_CONFIG_JSON,
182
184
  ) -> MsgGenerator:
183
185
  """
184
186
  A plan which combines the collection of snapshots from the OAV and the determination
@@ -204,6 +206,6 @@ def grid_detect_then_xray_centre(
204
206
  eiger,
205
207
  composite.detector_motion,
206
208
  parameters.detector_params.detector_distance,
207
- plan_to_perform,
209
+ plan_to_perform, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809 and MsgGenerator should allow for return values
208
210
  group=CONST.WAIT.GRID_READY_FOR_DC,
209
211
  )
@@ -63,7 +63,7 @@ def grid_detection_plan(
63
63
  snapshot_template: str,
64
64
  snapshot_dir: str,
65
65
  grid_width_microns: float,
66
- box_size_um: float = 20,
66
+ box_size_um: float,
67
67
  ):
68
68
  """
69
69
  Creates the parameters for two grids that are 90 degrees from each other and
@@ -74,7 +74,7 @@ def grid_detection_plan(
74
74
  parameters (OAVParameters): Object containing parameters for setting up the OAV
75
75
  snapshot_template (str): A template for the name of the snapshots, expected to be filled in with an angle
76
76
  snapshot_dir (str): The location to save snapshots
77
- grid_width_microns (int): The width of the grid to scan in microns
77
+ grid_width_microns (float): The width of the grid to scan in microns
78
78
  box_size_um (float): The size of each box of the grid in microns
79
79
  """
80
80
  oav: OAV = composite.oav
@@ -90,16 +90,17 @@ def grid_detection_plan(
90
90
 
91
91
  LOGGER.info("OAV Centring: Camera set up")
92
92
 
93
- assert isinstance(oav.parameters.micronsPerXPixel, float)
94
- box_size_x_pixels = box_size_um / oav.parameters.micronsPerXPixel
95
- assert isinstance(oav.parameters.micronsPerYPixel, float)
96
- box_size_y_pixels = box_size_um / oav.parameters.micronsPerYPixel
93
+ microns_per_pixel_x = yield from bps.rd(oav.microns_per_pixel_x)
94
+ microns_per_pixel_y = yield from bps.rd(oav.microns_per_pixel_y)
97
95
 
98
- grid_width_pixels = int(grid_width_microns / oav.parameters.micronsPerXPixel)
96
+ box_size_x_pixels = box_size_um / microns_per_pixel_x
97
+ box_size_y_pixels = box_size_um / microns_per_pixel_y
98
+
99
+ grid_width_pixels = int(grid_width_microns / microns_per_pixel_x)
99
100
 
100
101
  # The FGS uses -90 so we need to match it
101
102
  for angle in [0, -90]:
102
- yield from bps.mv(smargon.omega, angle)
103
+ yield from bps.mv(smargon.omega, angle) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
103
104
  # need to wait for the OAV image to update
104
105
  # See #673 for improvements
105
106
  yield from bps.sleep(CONST.HARDWARE.OAV_REFRESH_DELAY)
@@ -115,7 +116,7 @@ def grid_detection_plan(
115
116
  (yield from bps.rd(pin_tip_detection.triggered_bottom_edge))
116
117
  )
117
118
 
118
- full_image_height_px = yield from bps.rd(oav.cam.array_size.array_size_y)
119
+ full_image_height_px = yield from bps.rd(oav.cam.array_size_y)
119
120
 
120
121
  # only use the area from the start of the pin onwards
121
122
  top_edge = top_edge[tip_x_px : tip_x_px + grid_width_pixels]
@@ -151,20 +152,20 @@ def grid_detection_plan(
151
152
 
152
153
  upper_left = (tip_x_px, min_y)
153
154
 
154
- yield from bps.abs_set(oav.grid_snapshot.top_left_x, upper_left[0])
155
- yield from bps.abs_set(oav.grid_snapshot.top_left_y, upper_left[1])
156
- yield from bps.abs_set(oav.grid_snapshot.box_width, box_size_x_pixels)
157
- yield from bps.abs_set(oav.grid_snapshot.num_boxes_x, x_steps)
158
- yield from bps.abs_set(oav.grid_snapshot.num_boxes_y, y_steps)
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
159
160
 
160
161
  snapshot_filename = snapshot_template.format(angle=abs(angle))
161
162
 
162
- yield from bps.abs_set(oav.grid_snapshot.filename, snapshot_filename)
163
- yield from bps.abs_set(oav.grid_snapshot.directory, snapshot_dir)
164
- yield from bps.trigger(oav.grid_snapshot, wait=True)
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
165
166
  yield from bps.create(CONST.DESCRIPTORS.OAV_GRID_SNAPSHOT_TRIGGERED)
166
167
 
167
- yield from bps.read(oav.grid_snapshot)
168
+ yield from bps.read(oav) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
168
169
  yield from bps.read(smargon)
169
170
  yield from bps.save()
170
171
 
@@ -9,8 +9,8 @@ from dodal.devices.oav.oav_detector import OAV
9
9
  from dodal.devices.oav.oav_parameters import OAVParameters
10
10
  from dodal.devices.smargon import Smargon
11
11
 
12
+ from mx_bluesky.common.parameters.components import WithSnapshot
12
13
  from mx_bluesky.hyperion.device_setup_plans.setup_oav import setup_general_oav_params
13
- from mx_bluesky.hyperion.parameters.components import WithSnapshot
14
14
  from mx_bluesky.hyperion.parameters.constants import CONST, DocDescriptorNames
15
15
 
16
16
  OAV_SNAPSHOT_SETUP_SHOT = "oav_snapshot_setup_shot"
@@ -61,7 +61,8 @@ def _setup_oav(
61
61
  ):
62
62
  yield from setup_general_oav_params(composite.oav, oav_parameters)
63
63
  yield from bps.abs_set(
64
- composite.oav.snapshot.directory, str(parameters.snapshot_directory)
64
+ composite.oav.snapshot.directory, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
65
+ str(parameters.snapshot_directory),
65
66
  )
66
67
 
67
68
 
@@ -72,10 +73,12 @@ def _take_oav_snapshot(composite: OavSnapshotComposite, omega: float):
72
73
  time_now = datetime.now()
73
74
  filename = f"{time_now.strftime('%H%M%S')}_oav_snapshot_{omega:.0f}"
74
75
  yield from bps.abs_set(
75
- composite.oav.snapshot.filename, filename, group=OAV_SNAPSHOT_SETUP_SHOT
76
+ composite.oav.snapshot.filename, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
77
+ filename,
78
+ group=OAV_SNAPSHOT_SETUP_SHOT,
76
79
  )
77
80
  yield from bps.wait(group=OAV_SNAPSHOT_SETUP_SHOT)
78
- yield from bps.trigger(composite.oav.snapshot, wait=True)
81
+ yield from bps.trigger(composite.oav.snapshot, wait=True) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
79
82
  yield from bps.create(DocDescriptorNames.OAV_ROTATION_SNAPSHOT_TRIGGERED)
80
- yield from bps.read(composite.oav.snapshot)
83
+ yield from bps.read(composite.oav.snapshot) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
81
84
  yield from bps.save()
@@ -4,8 +4,9 @@ import json
4
4
 
5
5
  from blueapi.core import BlueskyContext, MsgGenerator
6
6
  from dodal.devices.eiger import EigerDetector
7
- from dodal.devices.oav.oav_parameters import OAV_CONFIG_JSON, OAVParameters
7
+ from dodal.devices.oav.oav_parameters import OAVParameters
8
8
 
9
+ from mx_bluesky.common.parameters.constants import OavConstants
9
10
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_phi_chi_omega
10
11
  from mx_bluesky.hyperion.device_setup_plans.utils import (
11
12
  start_preparing_data_collection_then_do_plan,
@@ -55,11 +56,10 @@ def create_parameters_for_grid_detection(
55
56
  def pin_centre_then_xray_centre_plan(
56
57
  composite: GridDetectThenXRayCentreComposite,
57
58
  parameters: PinTipCentreThenXrayCentre,
58
- oav_config_file: str = OAV_CONFIG_JSON,
59
+ oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
59
60
  ):
60
61
  """Plan that perfoms a pin tip centre followed by an xray centre to completely
61
62
  centre the sample"""
62
- oav_config_file = parameters.oav_centring_file
63
63
 
64
64
  pin_tip_centring_composite = PinTipCentringComposite(
65
65
  oav=composite.oav,
@@ -102,7 +102,7 @@ def pin_centre_then_xray_centre_plan(
102
102
  def pin_tip_centre_then_xray_centre(
103
103
  composite: GridDetectThenXRayCentreComposite,
104
104
  parameters: PinTipCentreThenXrayCentre,
105
- oav_config_file: str = OAV_CONFIG_JSON,
105
+ oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
106
106
  ) -> MsgGenerator:
107
107
  """Starts preparing for collection then performs the pin tip centre and xray centre"""
108
108
 
@@ -7,7 +7,7 @@ from bluesky.utils import Msg
7
7
  from dodal.devices.backlight import Backlight
8
8
  from dodal.devices.oav.oav_detector import OAV
9
9
  from dodal.devices.oav.oav_parameters import OAV_CONFIG_JSON, OAVParameters
10
- from dodal.devices.oav.pin_image_recognition import PinTipDetection
10
+ from dodal.devices.oav.pin_image_recognition import PinTipDetection, Tip
11
11
  from dodal.devices.oav.utils import (
12
12
  Pixel,
13
13
  get_move_required_so_that_beam_is_at_pixel,
@@ -43,11 +43,11 @@ def create_devices(context: BlueskyContext) -> PinTipCentringComposite:
43
43
 
44
44
  def trigger_and_return_pin_tip(
45
45
  pin_tip: PinTipDetection,
46
- ) -> Generator[Msg, None, Pixel]:
46
+ ) -> Generator[Msg, None, Tip]:
47
47
  yield from bps.trigger(pin_tip, wait=True)
48
48
  tip_x_y_px = yield from bps.rd(pin_tip.triggered_tip)
49
49
  LOGGER.info(f"Pin tip found at {tip_x_y_px}")
50
- return tip_x_y_px # type: ignore
50
+ return tip_x_y_px
51
51
 
52
52
 
53
53
  def move_pin_into_view(
@@ -74,16 +74,16 @@ def move_pin_into_view(
74
74
  Tuple[int, int]: The location of the pin tip in pixels
75
75
  """
76
76
 
77
- def pin_tip_valid(pin_x: float):
78
- return pin_x != 0 and pin_x != pin_tip_device.INVALID_POSITION[0]
77
+ def pin_tip_valid(pin_xy: Tip):
78
+ return not all(pin_xy == pin_tip_device.INVALID_POSITION) and pin_xy[0] != 0
79
79
 
80
80
  for _ in range(max_steps):
81
- tip_x_px, tip_y_px = yield from trigger_and_return_pin_tip(pin_tip_device)
81
+ tip_xy_px = yield from trigger_and_return_pin_tip(pin_tip_device)
82
82
 
83
- if pin_tip_valid(tip_x_px):
84
- return (tip_x_px, tip_y_px)
83
+ if pin_tip_valid(tip_xy_px):
84
+ return (int(tip_xy_px[0]), int(tip_xy_px[1]))
85
85
 
86
- if tip_x_px == 0:
86
+ if tip_xy_px[0] == 0:
87
87
  # Pin is off in the -ve direction
88
88
  step_size_mm = -step_size_mm
89
89
 
@@ -97,19 +97,19 @@ def move_pin_into_view(
97
97
  f"Pin tip is off screen, and moving {step_size_mm} mm would cross limits, "
98
98
  f"moving to {move_within_limits} instead"
99
99
  )
100
- yield from bps.mv(smargon.x, move_within_limits)
100
+ yield from bps.mv(smargon.x, move_within_limits) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
101
101
 
102
102
  # Some time for the view to settle after the move
103
103
  yield from bps.sleep(CONST.HARDWARE.OAV_REFRESH_DELAY)
104
104
 
105
- tip_x_px, tip_y_px = yield from trigger_and_return_pin_tip(pin_tip_device)
105
+ tip_xy_px = yield from trigger_and_return_pin_tip(pin_tip_device)
106
106
 
107
- if not pin_tip_valid(tip_x_px):
107
+ if not pin_tip_valid(tip_xy_px):
108
108
  raise WarningException(
109
109
  "Pin tip centring failed - pin too long/short/bent and out of range"
110
110
  )
111
111
  else:
112
- return (tip_x_px, tip_y_px)
112
+ return (int(tip_xy_px[0]), int(tip_xy_px[1]))
113
113
 
114
114
 
115
115
  def pin_tip_centre_plan(
@@ -132,13 +132,13 @@ def pin_tip_centre_plan(
132
132
  pin_tip_setup = composite.pin_tip_detection
133
133
  pin_tip_detect = composite.pin_tip_detection
134
134
 
135
- assert oav.parameters.micronsPerXPixel is not None
136
- tip_offset_px = int(tip_offset_microns / oav.parameters.micronsPerXPixel)
135
+ microns_per_pixel_x = yield from bps.rd(oav.microns_per_pixel_x)
136
+ tip_offset_px = int(tip_offset_microns / microns_per_pixel_x)
137
137
 
138
138
  def offset_and_move(tip: Pixel):
139
139
  pixel_to_move_to = (tip[0] + tip_offset_px, tip[1])
140
140
  position_mm = yield from get_move_required_so_that_beam_is_at_pixel(
141
- smargon, pixel_to_move_to, oav.parameters
141
+ smargon, pixel_to_move_to, oav
142
142
  )
143
143
  LOGGER.info(f"Tip centring moving to : {position_mm}")
144
144
  yield from move_smargon_warn_on_out_of_range(smargon, position_mm)
@@ -154,7 +154,7 @@ def pin_tip_centre_plan(
154
154
  tip = yield from move_pin_into_view(pin_tip_detect, smargon)
155
155
  yield from offset_and_move(tip)
156
156
 
157
- yield from bps.mvr(smargon.omega, 90)
157
+ yield from bps.mvr(smargon.omega, 90) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
158
158
 
159
159
  # need to wait for the OAV image to update
160
160
  # See #673 for improvements
@@ -13,7 +13,7 @@ from bluesky.utils import Msg
13
13
  from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
14
14
  from dodal.devices.attenuator import Attenuator
15
15
  from dodal.devices.dcm import DCM
16
- from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, VFMMirrorVoltages
16
+ from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
17
17
  from dodal.devices.motors import XYZPositioner
18
18
  from dodal.devices.oav.oav_detector import OAV
19
19
  from dodal.devices.robot import BartRobot, SampleLocation
@@ -37,7 +37,7 @@ from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange
37
37
  class RobotLoadAndEnergyChangeComposite:
38
38
  # SetEnergyComposite fields
39
39
  vfm: FocusingMirrorWithStripes
40
- vfm_mirror_voltages: VFMMirrorVoltages
40
+ mirror_voltages: MirrorVoltages
41
41
  dcm: DCM
42
42
  undulator_dcm: UndulatorDCM
43
43
  xbpm_feedback: XBPMFeedback
@@ -100,15 +100,17 @@ def prepare_for_robot_load(
100
100
  group="prepare_robot_load",
101
101
  )
102
102
 
103
- yield from bps.mv(smargon.stub_offsets, StubPosition.RESET_TO_ROBOT_LOAD)
103
+ yield from bps.mv(smargon.stub_offsets, StubPosition.RESET_TO_ROBOT_LOAD) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
104
104
 
105
105
  # fmt: off
106
- yield from bps.mv(smargon.x, 0,
107
- smargon.y, 0,
108
- smargon.z, 0,
109
- smargon.omega, 0,
110
- smargon.chi, 0,
111
- smargon.phi, 0)
106
+ yield from bps.mv(
107
+ smargon.x, 0, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
108
+ smargon.y, 0, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
109
+ smargon.z, 0, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
110
+ smargon.omega, 0, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
111
+ smargon.chi, 0, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
112
+ smargon.phi, 0 # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
113
+ )
112
114
  # fmt: on
113
115
 
114
116
  yield from bps.wait("prepare_robot_load")
@@ -135,7 +137,9 @@ def do_robot_load(
135
137
  yield from bps.wait("robot_load")
136
138
 
137
139
  yield from bps.abs_set(
138
- composite.thawer.thaw_for_time_s, thawing_time, group="thawing_finished"
140
+ composite.thawer.thaw_for_time_s, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
141
+ thawing_time,
142
+ group="thawing_finished",
139
143
  )
140
144
  yield from wait_for_smargon_not_disabled(composite.smargon)
141
145
 
@@ -195,7 +199,7 @@ def robot_load_and_snapshots(
195
199
 
196
200
  yield from bps.create(name=CONST.DESCRIPTORS.ROBOT_LOAD)
197
201
  yield from bps.read(composite.robot.barcode)
198
- yield from bps.read(composite.oav.snapshot)
202
+ yield from bps.read(composite.oav.snapshot) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
199
203
  yield from bps.read(composite.webcam)
200
204
  yield from bps.save()
201
205
 
@@ -12,7 +12,7 @@ from dodal.devices.detector.detector_motion import DetectorMotion
12
12
  from dodal.devices.eiger import EigerDetector
13
13
  from dodal.devices.fast_grid_scan import PandAFastGridScan, ZebraFastGridScan
14
14
  from dodal.devices.flux import Flux
15
- from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, VFMMirrorVoltages
15
+ from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
16
16
  from dodal.devices.motors import XYZPositioner
17
17
  from dodal.devices.oav.oav_detector import OAV
18
18
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
@@ -31,6 +31,7 @@ from dodal.devices.zocalo import ZocaloResults
31
31
  from dodal.log import LOGGER
32
32
  from ophyd_async.fastcs.panda import HDFPanda
33
33
 
34
+ from mx_bluesky.common.parameters.constants import OavConstants
34
35
  from mx_bluesky.hyperion.device_setup_plans.utils import (
35
36
  fill_in_energy_if_not_supplied,
36
37
  start_preparing_data_collection_then_do_plan,
@@ -78,7 +79,7 @@ class RobotLoadThenCentreComposite:
78
79
 
79
80
  # SetEnergyComposite fields
80
81
  vfm: FocusingMirrorWithStripes
81
- vfm_mirror_voltages: VFMMirrorVoltages
82
+ mirror_voltages: MirrorVoltages
82
83
  dcm: DCM
83
84
  undulator_dcm: UndulatorDCM
84
85
 
@@ -97,6 +98,7 @@ def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite:
97
98
  def centring_plan_from_robot_load_params(
98
99
  composite: RobotLoadThenCentreComposite,
99
100
  params: RobotLoadThenCentre,
101
+ oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
100
102
  ):
101
103
  yield from pin_centre_then_xray_centre_plan(
102
104
  cast(GridDetectThenXRayCentreComposite, composite),
@@ -107,13 +109,14 @@ def centring_plan_from_robot_load_params(
107
109
  def robot_load_then_centre_plan(
108
110
  composite: RobotLoadThenCentreComposite,
109
111
  params: RobotLoadThenCentre,
112
+ oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
110
113
  ):
111
114
  yield from robot_load_and_change_energy_plan(
112
115
  cast(RobotLoadAndEnergyChangeComposite, composite),
113
116
  params.robot_load_params(),
114
117
  )
115
118
 
116
- yield from centring_plan_from_robot_load_params(composite, params)
119
+ yield from centring_plan_from_robot_load_params(composite, params, oav_config_file)
117
120
 
118
121
 
119
122
  def robot_load_then_centre(
@@ -24,6 +24,9 @@ from dodal.devices.zebra import RotationDirection, Zebra
24
24
  from dodal.devices.zebra_controlled_shutter import ZebraShutter
25
25
  from dodal.plans.check_topup import check_topup_and_wait_if_necessary
26
26
 
27
+ from mx_bluesky.common.device_setup_plans.read_hardware_for_setup import (
28
+ read_hardware_for_zocalo,
29
+ )
27
30
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
28
31
  cleanup_sample_environment,
29
32
  move_phi_chi_omega,
@@ -32,7 +35,6 @@ from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
32
35
  )
33
36
  from mx_bluesky.hyperion.device_setup_plans.read_hardware_for_setup import (
34
37
  read_hardware_during_collection,
35
- read_hardware_for_zocalo,
36
38
  read_hardware_pre_collection,
37
39
  )
38
40
  from mx_bluesky.hyperion.device_setup_plans.setup_zebra import (
@@ -252,7 +254,7 @@ def rotation_scan_plan(
252
254
  composite.undulator,
253
255
  composite.synchrotron,
254
256
  composite.s4_slit_gaps,
255
- composite.robot,
257
+ composite.dcm,
256
258
  composite.smargon,
257
259
  )
258
260
 
@@ -348,7 +350,7 @@ def rotation_scan(
348
350
  md={
349
351
  "subplan_name": CONST.PLAN.ROTATION_OUTER,
350
352
  CONST.TRIGGER.ZOCALO: CONST.PLAN.ROTATION_MAIN,
351
- "zocalo_environment": parameters.zocalo_environment,
353
+ "zocalo_environment": CONST.ZOCALO_ENV,
352
354
  "hyperion_parameters": parameters.model_dump_json(),
353
355
  "activate_callbacks": [
354
356
  "RotationISPyBCallback",
@@ -379,7 +381,7 @@ def rotation_scan(
379
381
  rotation_with_cleanup_and_stage(params),
380
382
  group=CONST.WAIT.ROTATION_READY_FOR_DC,
381
383
  )
382
- yield from bps.unstage(eiger)
384
+ yield from bps.unstage(eiger) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
383
385
 
384
386
  yield from rotation_scan_plan_with_stage_and_cleanup(parameters)
385
387