mx-bluesky 1.4.2__py3-none-any.whl → 1.4.4__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 (92) hide show
  1. mx_bluesky/_version.py +2 -2
  2. mx_bluesky/beamlines/i24/serial/dcid.py +3 -3
  3. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +24 -9
  4. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +13 -4
  5. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +1 -1
  6. mx_bluesky/beamlines/i24/serial/parameters/__init__.py +2 -1
  7. mx_bluesky/beamlines/i24/serial/parameters/constants.py +13 -5
  8. mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +20 -4
  9. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +40 -11
  10. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +81 -40
  11. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/aperture_change_callback.py +1 -1
  12. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/grid_detection_callback.py +19 -1
  13. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/ispyb_callback_base.py +40 -34
  14. mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/ispyb_mapping.py +4 -4
  15. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/logging_callback.py +1 -1
  16. mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/zocalo_callback.py +13 -19
  17. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_callback.py +39 -34
  18. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_mapping.py +2 -2
  19. mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/nexus_callback.py +20 -15
  20. mx_bluesky/common/external_interaction/config_server.py +11 -0
  21. mx_bluesky/common/external_interaction/ispyb/__init__.py +0 -0
  22. mx_bluesky/{hyperion → common}/external_interaction/ispyb/data_model.py +2 -0
  23. mx_bluesky/{hyperion → common}/external_interaction/ispyb/exp_eye_store.py +5 -5
  24. mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_store.py +20 -18
  25. mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_utils.py +2 -2
  26. mx_bluesky/common/external_interaction/nexus/__init__.py +0 -0
  27. mx_bluesky/{hyperion → common}/external_interaction/nexus/nexus_utils.py +21 -6
  28. mx_bluesky/{hyperion → common}/external_interaction/nexus/write_nexus.py +5 -5
  29. mx_bluesky/common/external_interaction/test_config_server.py +38 -0
  30. mx_bluesky/common/parameters/components.py +9 -8
  31. mx_bluesky/common/parameters/constants.py +1 -0
  32. mx_bluesky/common/parameters/gridscan.py +107 -53
  33. mx_bluesky/common/plans/do_fgs.py +4 -10
  34. mx_bluesky/{hyperion → common/utils}/exceptions.py +15 -1
  35. mx_bluesky/common/utils/log.py +17 -7
  36. mx_bluesky/hyperion/__main__.py +15 -14
  37. mx_bluesky/hyperion/device_setup_plans/check_beamstop.py +27 -0
  38. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +13 -6
  39. mx_bluesky/hyperion/device_setup_plans/manipulate_sample.py +1 -1
  40. mx_bluesky/hyperion/device_setup_plans/position_detector.py +1 -1
  41. mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +3 -3
  42. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +21 -4
  43. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +62 -36
  44. mx_bluesky/hyperion/device_setup_plans/smargon.py +1 -1
  45. mx_bluesky/hyperion/device_setup_plans/utils.py +4 -0
  46. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +8 -8
  47. mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +28 -17
  48. mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +10 -1
  49. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
  50. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +39 -49
  51. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +22 -23
  52. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +4 -11
  53. mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +3 -3
  54. mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +6 -14
  55. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +12 -11
  56. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +2 -2
  57. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +9 -4
  58. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +10 -11
  59. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -17
  60. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +2 -2
  61. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +32 -23
  62. mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +60 -34
  63. mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +22 -15
  64. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +25 -24
  65. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -1
  66. mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +13 -9
  67. mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +12 -46
  68. mx_bluesky/hyperion/external_interaction/config_server.py +15 -1
  69. mx_bluesky/hyperion/parameters/components.py +3 -2
  70. mx_bluesky/hyperion/parameters/constants.py +1 -0
  71. mx_bluesky/hyperion/parameters/gridscan.py +54 -89
  72. mx_bluesky/hyperion/parameters/load_centre_collect.py +51 -6
  73. mx_bluesky/hyperion/parameters/robot_load.py +40 -0
  74. mx_bluesky/hyperion/parameters/rotation.py +28 -3
  75. mx_bluesky/hyperion/utils/context.py +1 -1
  76. mx_bluesky/hyperion/utils/validation.py +4 -2
  77. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/METADATA +6 -6
  78. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/RECORD +89 -87
  79. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/WHEEL +1 -1
  80. mx_bluesky/common/parameters/robot_load.py +0 -16
  81. mx_bluesky/hyperion/external_interaction/exceptions.py +0 -4
  82. mx_bluesky/hyperion/log.py +0 -15
  83. /mx_bluesky/{hyperion/external_interaction/callbacks/xray_centre → common/external_interaction}/__init__.py +0 -0
  84. /mx_bluesky/{hyperion/external_interaction/ispyb → common/external_interaction/callbacks/common}/__init__.py +0 -0
  85. /mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/abstract_event.py +0 -0
  86. /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/log_uid_tag_callback.py +0 -0
  87. /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/plan_reactive_callback.py +0 -0
  88. /mx_bluesky/{hyperion/external_interaction/nexus → common/external_interaction/callbacks/xray_centre}/__init__.py +0 -0
  89. /mx_bluesky/{hyperion → common}/utils/utils.py +0 -0
  90. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/LICENSE +0 -0
  91. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/entry_points.txt +0 -0
  92. {mx_bluesky-1.4.2.dist-info → mx_bluesky-1.4.4.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ from blueapi.core import BlueskyContext
9
9
  from bluesky import plan_stubs as bps
10
10
  from bluesky.utils import MsgGenerator
11
11
  from dodal.devices.aperturescatterguard import ApertureScatterguard
12
- from dodal.devices.attenuator import Attenuator
12
+ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
13
13
  from dodal.devices.backlight import Backlight
14
14
  from dodal.devices.dcm import DCM
15
15
  from dodal.devices.detector.detector_motion import DetectorMotion
@@ -17,6 +17,7 @@ from dodal.devices.eiger import EigerDetector
17
17
  from dodal.devices.fast_grid_scan import PandAFastGridScan, ZebraFastGridScan
18
18
  from dodal.devices.flux import Flux
19
19
  from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
20
+ from dodal.devices.i03.beamstop import Beamstop
20
21
  from dodal.devices.motors import XYZPositioner
21
22
  from dodal.devices.oav.oav_detector import OAV
22
23
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
@@ -29,14 +30,13 @@ from dodal.devices.undulator import Undulator
29
30
  from dodal.devices.undulator_dcm import UndulatorDCM
30
31
  from dodal.devices.webcam import Webcam
31
32
  from dodal.devices.xbpm_feedback import XBPMFeedback
32
- from dodal.devices.zebra import Zebra
33
- from dodal.devices.zebra_controlled_shutter import ZebraShutter
33
+ from dodal.devices.zebra.zebra import Zebra
34
+ from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
34
35
  from dodal.devices.zocalo import ZocaloResults
35
36
  from dodal.log import LOGGER
36
37
  from ophyd_async.fastcs.panda import HDFPanda
37
38
 
38
39
  from mx_bluesky.common.parameters.constants import OavConstants
39
- from mx_bluesky.common.parameters.gridscan import RobotLoadThenCentre
40
40
  from mx_bluesky.hyperion.device_setup_plans.utils import (
41
41
  fill_in_energy_if_not_supplied,
42
42
  start_preparing_data_collection_then_do_plan,
@@ -63,13 +63,14 @@ from mx_bluesky.hyperion.experiment_plans.set_energy_plan import (
63
63
  set_energy_plan,
64
64
  )
65
65
  from mx_bluesky.hyperion.parameters.constants import CONST
66
+ from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre
66
67
 
67
68
 
68
69
  @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
69
70
  class RobotLoadThenCentreComposite:
70
71
  # common fields
71
72
  xbpm_feedback: XBPMFeedback
72
- attenuator: Attenuator
73
+ attenuator: BinaryFilterAttenuator
73
74
 
74
75
  # GridDetectThenXRayCentreComposite fields
75
76
  aperture_scatterguard: ApertureScatterguard
@@ -101,10 +102,7 @@ class RobotLoadThenCentreComposite:
101
102
  robot: BartRobot
102
103
  webcam: Webcam
103
104
  lower_gonio: XYZPositioner
104
-
105
- @property
106
- def sample_motors(self):
107
- return self.smargon
105
+ beamstop: Beamstop
108
106
 
109
107
 
110
108
  def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite:
@@ -120,7 +118,7 @@ def _flyscan_plan_from_robot_load_params(
120
118
  ):
121
119
  yield from pin_centre_then_flyscan_plan(
122
120
  cast(GridDetectThenXRayCentreComposite, composite),
123
- params.pin_centre_then_xray_centre_params(),
121
+ params.pin_centre_then_xray_centre_params,
124
122
  )
125
123
 
126
124
 
@@ -131,7 +129,7 @@ def _robot_load_then_flyscan_plan(
131
129
  ):
132
130
  yield from robot_load_and_change_energy_plan(
133
131
  cast(RobotLoadAndEnergyChangeComposite, composite),
134
- params.robot_load_params(),
132
+ params.robot_load_params,
135
133
  )
136
134
 
137
135
  yield from _flyscan_plan_from_robot_load_params(composite, params, oav_config_file)
@@ -211,6 +209,7 @@ def robot_load_then_xray_centre(
211
209
  eiger.set_detector_parameters(detector_params)
212
210
 
213
211
  yield from start_preparing_data_collection_then_do_plan(
212
+ composite.beamstop,
214
213
  eiger,
215
214
  composite.detector_motion,
216
215
  parameters.detector_distance_mm,
@@ -8,12 +8,13 @@ import pydantic
8
8
  from blueapi.core import BlueskyContext
9
9
  from bluesky.utils import MsgGenerator
10
10
  from dodal.devices.aperturescatterguard import ApertureScatterguard
11
- from dodal.devices.attenuator import Attenuator
11
+ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
12
12
  from dodal.devices.backlight import Backlight
13
13
  from dodal.devices.dcm import DCM
14
14
  from dodal.devices.detector.detector_motion import DetectorMotion
15
15
  from dodal.devices.eiger import EigerDetector
16
16
  from dodal.devices.flux import Flux
17
+ from dodal.devices.i03.beamstop import Beamstop
17
18
  from dodal.devices.oav.oav_detector import OAV
18
19
  from dodal.devices.oav.oav_parameters import OAVParameters
19
20
  from dodal.devices.robot import BartRobot
@@ -22,13 +23,14 @@ from dodal.devices.smargon import Smargon
22
23
  from dodal.devices.synchrotron import Synchrotron
23
24
  from dodal.devices.undulator import Undulator
24
25
  from dodal.devices.xbpm_feedback import XBPMFeedback
25
- from dodal.devices.zebra import RotationDirection, Zebra
26
- from dodal.devices.zebra_controlled_shutter import ZebraShutter
26
+ from dodal.devices.zebra.zebra import RotationDirection, Zebra
27
+ from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
27
28
  from dodal.plan_stubs.check_topup import check_topup_and_wait_if_necessary
28
29
 
29
30
  from mx_bluesky.common.device_setup_plans.read_hardware_for_setup import (
30
31
  read_hardware_for_zocalo,
31
32
  )
33
+ from mx_bluesky.common.utils.log import LOGGER
32
34
  from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
33
35
  cleanup_sample_environment,
34
36
  move_phi_chi_omega,
@@ -55,7 +57,6 @@ from mx_bluesky.hyperion.experiment_plans.oav_snapshot_plan import (
55
57
  oav_snapshot_plan,
56
58
  setup_beamline_for_OAV,
57
59
  )
58
- from mx_bluesky.hyperion.log import LOGGER
59
60
  from mx_bluesky.hyperion.parameters.constants import CONST
60
61
  from mx_bluesky.hyperion.parameters.rotation import (
61
62
  MultiRotationScan,
@@ -69,8 +70,9 @@ class RotationScanComposite(OavSnapshotComposite):
69
70
  """All devices which are directly or indirectly required by this plan"""
70
71
 
71
72
  aperture_scatterguard: ApertureScatterguard
72
- attenuator: Attenuator
73
+ attenuator: BinaryFilterAttenuator
73
74
  backlight: Backlight
75
+ beamstop: Beamstop
74
76
  dcm: DCM
75
77
  detector_motion: DetectorMotion
76
78
  eiger: EigerDetector
@@ -126,13 +128,26 @@ def calculate_motion_profile(
126
128
  See https://github.com/DiamondLightSource/hyperion/wiki/rotation-scan-geometry
127
129
  for a simple pictorial explanation."""
128
130
 
129
- direction = params.rotation_direction.multiplier
131
+ assert params.rotation_increment_deg > 0
132
+
133
+ direction = params.rotation_direction
134
+ start_scan_deg = params.omega_start_deg
135
+
136
+ if params.features.omega_flip:
137
+ # If omega_flip is True then the motor omega axis is inverted with respect to the
138
+ # hyperion coordinate system.
139
+ start_scan_deg = -start_scan_deg
140
+ direction = (
141
+ direction.POSITIVE
142
+ if direction == direction.NEGATIVE
143
+ else direction.NEGATIVE
144
+ )
145
+
130
146
  num_images = params.num_images
131
147
  shutter_time_s = params.shutter_opening_time_s
132
148
  image_width_deg = params.rotation_increment_deg
133
149
  exposure_time_s = params.exposure_time_s
134
150
  motor_time_to_speed_s *= ACCELERATION_MARGIN
135
- start_scan_deg = params.omega_start_deg
136
151
 
137
152
  LOGGER.info("Calculating rotation scan motion profile:")
138
153
  LOGGER.info(
@@ -153,9 +168,9 @@ def calculate_motion_profile(
153
168
  f"{acceleration_offset_deg=} = {motor_time_to_speed_s=} * {speed_for_rotation_deg_s=}"
154
169
  )
155
170
 
156
- start_motion_deg = start_scan_deg - (acceleration_offset_deg * direction)
171
+ start_motion_deg = start_scan_deg - (acceleration_offset_deg * direction.multiplier)
157
172
  LOGGER.info(
158
- f"{start_motion_deg=} = {start_scan_deg=} - ({acceleration_offset_deg=} * {direction=})"
173
+ f"{start_motion_deg=} = {start_scan_deg=} - ({acceleration_offset_deg=} * {direction.multiplier=})"
159
174
  )
160
175
 
161
176
  shutter_opening_deg = speed_for_rotation_deg_s * shutter_time_s
@@ -173,7 +188,7 @@ def calculate_motion_profile(
173
188
 
174
189
  distance_to_move_deg = (
175
190
  scan_width_deg + shutter_opening_deg + acceleration_offset_deg * 2
176
- ) * direction
191
+ ) * direction.multiplier
177
192
  LOGGER.info(
178
193
  f"{distance_to_move_deg=} = ({scan_width_deg=} + {shutter_opening_deg=} + {acceleration_offset_deg=} * 2) * {direction=})"
179
194
  )
@@ -183,7 +198,7 @@ def calculate_motion_profile(
183
198
  start_motion_deg=start_motion_deg,
184
199
  scan_width_deg=scan_width_deg,
185
200
  shutter_time_s=shutter_time_s,
186
- direction=params.rotation_direction,
201
+ direction=direction,
187
202
  speed_for_rotation_deg_s=speed_for_rotation_deg_s,
188
203
  acceleration_offset_deg=acceleration_offset_deg,
189
204
  shutter_opening_deg=shutter_opening_deg,
@@ -344,6 +359,8 @@ def rotation_scan(
344
359
  parameters: RotationScan,
345
360
  oav_params: OAVParameters | None = None,
346
361
  ) -> MsgGenerator:
362
+ parameters.features.update_self_from_server()
363
+
347
364
  if not oav_params:
348
365
  oav_params = OAVParameters(context="xrayCentring")
349
366
 
@@ -351,9 +368,7 @@ def rotation_scan(
351
368
  @bpp.run_decorator( # attach experiment metadata to the start document
352
369
  md={
353
370
  "subplan_name": CONST.PLAN.ROTATION_OUTER,
354
- CONST.TRIGGER.ZOCALO: CONST.PLAN.ROTATION_MAIN,
355
- "zocalo_environment": CONST.ZOCALO_ENV,
356
- "hyperion_parameters": parameters.model_dump_json(),
371
+ "mx_bluesky_parameters": parameters.model_dump_json(),
357
372
  "activate_callbacks": [
358
373
  "RotationISPyBCallback",
359
374
  "RotationNexusFileCallback",
@@ -377,6 +392,7 @@ def rotation_scan(
377
392
 
378
393
  LOGGER.info("setting up and staging eiger...")
379
394
  yield from start_preparing_data_collection_then_do_plan(
395
+ composite.beamstop,
380
396
  eiger,
381
397
  composite.detector_motion,
382
398
  params.detector_distance_mm,
@@ -393,6 +409,7 @@ def multi_rotation_scan(
393
409
  parameters: MultiRotationScan,
394
410
  oav_params: OAVParameters | None = None,
395
411
  ) -> MsgGenerator:
412
+ parameters.features.update_self_from_server()
396
413
  if not oav_params:
397
414
  oav_params = OAVParameters(context="xrayCentring")
398
415
  eiger: EigerDetector = composite.eiger
@@ -424,9 +441,7 @@ def multi_rotation_scan(
424
441
  @bpp.run_decorator( # attach experiment metadata to the start document
425
442
  md={
426
443
  "subplan_name": CONST.PLAN.ROTATION_OUTER,
427
- CONST.TRIGGER.ZOCALO: CONST.PLAN.ROTATION_MAIN,
428
- "zocalo_environment": CONST.ZOCALO_ENV,
429
- "hyperion_parameters": single_scan.model_dump_json(),
444
+ "mx_bluesky_parameters": single_scan.model_dump_json(),
430
445
  }
431
446
  )
432
447
  def rotation_scan_core(
@@ -438,6 +453,7 @@ def multi_rotation_scan(
438
453
 
439
454
  LOGGER.info("setting up and staging eiger...")
440
455
  yield from start_preparing_data_collection_then_do_plan(
456
+ composite.beamstop,
441
457
  eiger,
442
458
  composite.detector_motion,
443
459
  parameters.detector_distance_mm,
@@ -7,7 +7,7 @@
7
7
 
8
8
  import pydantic
9
9
  from bluesky import plan_stubs as bps
10
- from dodal.devices.attenuator import Attenuator
10
+ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
11
11
  from dodal.devices.dcm import DCM
12
12
  from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
13
13
  from dodal.devices.undulator_dcm import UndulatorDCM
@@ -30,7 +30,7 @@ class SetEnergyComposite:
30
30
  dcm: DCM
31
31
  undulator_dcm: UndulatorDCM
32
32
  xbpm_feedback: XBPMFeedback
33
- attenuator: Attenuator
33
+ attenuator: BinaryFilterAttenuator
34
34
 
35
35
 
36
36
  def _set_energy_plan(
@@ -7,10 +7,24 @@ from bluesky.callbacks.zmq import Proxy, RemoteDispatcher
7
7
  from dodal.log import LOGGER as dodal_logger
8
8
  from dodal.log import set_up_all_logging_handlers
9
9
 
10
- from mx_bluesky.common.utils.log import _get_logging_dir, tag_filter
11
- from mx_bluesky.hyperion.external_interaction.callbacks.log_uid_tag_callback import (
10
+ from mx_bluesky.common.external_interaction.callbacks.common.log_uid_tag_callback import (
12
11
  LogUidTaggingCallback,
13
12
  )
13
+ from mx_bluesky.common.external_interaction.callbacks.common.zocalo_callback import (
14
+ ZocaloCallback,
15
+ )
16
+ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
17
+ GridscanISPyBCallback,
18
+ )
19
+ from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
20
+ GridscanNexusFileCallback,
21
+ )
22
+ from mx_bluesky.common.utils.log import (
23
+ ISPYB_ZOCALO_CALLBACK_LOGGER,
24
+ NEXUS_LOGGER,
25
+ _get_logging_dir,
26
+ tag_filter,
27
+ )
14
28
  from mx_bluesky.hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
15
29
  RobotLoadISPyBCallback,
16
30
  )
@@ -23,33 +37,28 @@ from mx_bluesky.hyperion.external_interaction.callbacks.rotation.nexus_callback
23
37
  from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import (
24
38
  SampleHandlingCallback,
25
39
  )
26
- from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.ispyb_callback import (
27
- GridscanISPyBCallback,
28
- )
29
- from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.nexus_callback import (
30
- GridscanNexusFileCallback,
31
- )
32
- from mx_bluesky.hyperion.external_interaction.callbacks.zocalo_callback import (
33
- ZocaloCallback,
34
- )
35
- from mx_bluesky.hyperion.log import (
36
- ISPYB_LOGGER,
37
- NEXUS_LOGGER,
38
- )
39
40
  from mx_bluesky.hyperion.parameters.cli import parse_callback_dev_mode_arg
40
41
  from mx_bluesky.hyperion.parameters.constants import CONST
42
+ from mx_bluesky.hyperion.parameters.gridscan import (
43
+ GridCommonWithHyperionDetectorParams,
44
+ HyperionSpecifiedThreeDGridScan,
45
+ )
41
46
 
42
47
  LIVENESS_POLL_SECONDS = 1
43
48
  ERROR_LOG_BUFFER_LINES = 5000
44
49
 
45
50
 
46
51
  def setup_callbacks():
47
- zocalo = ZocaloCallback()
48
52
  return [
49
- GridscanNexusFileCallback(),
50
- GridscanISPyBCallback(emit=zocalo),
53
+ GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
54
+ GridscanISPyBCallback(
55
+ param_type=GridCommonWithHyperionDetectorParams,
56
+ emit=ZocaloCallback(CONST.PLAN.DO_FGS, CONST.ZOCALO_ENV),
57
+ ),
51
58
  RotationNexusFileCallback(),
52
- RotationISPyBCallback(emit=zocalo),
59
+ RotationISPyBCallback(
60
+ emit=ZocaloCallback(CONST.PLAN.ROTATION_MAIN, CONST.ZOCALO_ENV)
61
+ ),
53
62
  LogUidTaggingCallback(),
54
63
  RobotLoadISPyBCallback(),
55
64
  SampleHandlingCallback(),
@@ -58,7 +67,7 @@ def setup_callbacks():
58
67
 
59
68
  def setup_logging(dev_mode: bool):
60
69
  for logger, filename in [
61
- (ISPYB_LOGGER, "hyperion_ispyb_callback.log"),
70
+ (ISPYB_ZOCALO_CALLBACK_LOGGER, "hyperion_ispyb_callback.log"),
62
71
  (NEXUS_LOGGER, "hyperion_nexus_callback.log"),
63
72
  ]:
64
73
  if logger.handlers == []:
@@ -74,7 +83,7 @@ def setup_logging(dev_mode: bool):
74
83
  log_info(f"Loggers initialised with dev_mode={dev_mode}")
75
84
  nexgen_logger = logging.getLogger("nexgen")
76
85
  nexgen_logger.parent = NEXUS_LOGGER
77
- dodal_logger.parent = ISPYB_LOGGER
86
+ dodal_logger.parent = ISPYB_ZOCALO_CALLBACK_LOGGER
78
87
  log_debug("nexgen logger added to nexus logger")
79
88
 
80
89
 
@@ -94,12 +103,12 @@ def setup_threads():
94
103
 
95
104
 
96
105
  def log_info(msg, *args, **kwargs):
97
- ISPYB_LOGGER.info(msg, *args, **kwargs)
106
+ ISPYB_ZOCALO_CALLBACK_LOGGER.info(msg, *args, **kwargs)
98
107
  NEXUS_LOGGER.info(msg, *args, **kwargs)
99
108
 
100
109
 
101
110
  def log_debug(msg, *args, **kwargs):
102
- ISPYB_LOGGER.debug(msg, *args, **kwargs)
111
+ ISPYB_ZOCALO_CALLBACK_LOGGER.debug(msg, *args, **kwargs)
103
112
  NEXUS_LOGGER.debug(msg, *args, **kwargs)
104
113
 
105
114
 
@@ -2,6 +2,15 @@ from collections.abc import Callable
2
2
 
3
3
  from bluesky.callbacks import CallbackBase
4
4
 
5
+ from mx_bluesky.common.external_interaction.callbacks.common.zocalo_callback import (
6
+ ZocaloCallback,
7
+ )
8
+ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
9
+ GridscanISPyBCallback,
10
+ )
11
+ from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
12
+ GridscanNexusFileCallback,
13
+ )
5
14
  from mx_bluesky.hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
6
15
  RobotLoadISPyBCallback,
7
16
  )
@@ -14,56 +23,73 @@ from mx_bluesky.hyperion.external_interaction.callbacks.rotation.nexus_callback
14
23
  from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import (
15
24
  SampleHandlingCallback,
16
25
  )
17
- from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.ispyb_callback import (
18
- GridscanISPyBCallback,
19
- )
20
- from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.nexus_callback import (
21
- GridscanNexusFileCallback,
22
- )
23
- from mx_bluesky.hyperion.external_interaction.callbacks.zocalo_callback import (
24
- ZocaloCallback,
26
+ from mx_bluesky.hyperion.parameters.constants import CONST
27
+ from mx_bluesky.hyperion.parameters.gridscan import (
28
+ GridCommonWithHyperionDetectorParams,
29
+ HyperionSpecifiedThreeDGridScan,
25
30
  )
26
31
 
27
32
  CallbacksFactory = Callable[[], tuple[CallbackBase, ...]]
28
33
 
29
34
 
30
- def create_robot_load_and_centre_callbacks() -> (
31
- tuple[GridscanNexusFileCallback, GridscanISPyBCallback, RobotLoadISPyBCallback]
32
- ):
35
+ def create_robot_load_and_centre_callbacks() -> tuple[
36
+ GridscanNexusFileCallback, GridscanISPyBCallback, RobotLoadISPyBCallback
37
+ ]:
38
+ """Note: This is not actually used in production, see https://github.com/DiamondLightSource/mx-bluesky/issues/516"""
33
39
  return (
34
- GridscanNexusFileCallback(),
35
- GridscanISPyBCallback(emit=ZocaloCallback()),
40
+ GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
41
+ GridscanISPyBCallback(
42
+ param_type=GridCommonWithHyperionDetectorParams,
43
+ emit=ZocaloCallback(CONST.PLAN.DO_FGS, CONST.ZOCALO_ENV),
44
+ ),
36
45
  RobotLoadISPyBCallback(),
37
46
  )
38
47
 
39
48
 
40
- def create_gridscan_callbacks() -> (
41
- tuple[GridscanNexusFileCallback, GridscanISPyBCallback]
42
- ):
43
- return (GridscanNexusFileCallback(), GridscanISPyBCallback(emit=ZocaloCallback()))
49
+ def create_gridscan_callbacks() -> tuple[
50
+ GridscanNexusFileCallback, GridscanISPyBCallback
51
+ ]:
52
+ """Note: This is not actually used in production, see https://github.com/DiamondLightSource/mx-bluesky/issues/516"""
53
+ return (
54
+ GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
55
+ GridscanISPyBCallback(
56
+ param_type=GridCommonWithHyperionDetectorParams,
57
+ emit=ZocaloCallback(CONST.PLAN.DO_FGS, CONST.ZOCALO_ENV),
58
+ ),
59
+ )
44
60
 
45
61
 
46
- def create_rotation_callbacks() -> (
47
- tuple[RotationNexusFileCallback, RotationISPyBCallback]
48
- ):
49
- return (RotationNexusFileCallback(), RotationISPyBCallback(emit=ZocaloCallback()))
62
+ def create_rotation_callbacks() -> tuple[
63
+ RotationNexusFileCallback, RotationISPyBCallback
64
+ ]:
65
+ """Note: This is not actually used in production, see https://github.com/DiamondLightSource/mx-bluesky/issues/516"""
66
+ return (
67
+ RotationNexusFileCallback(),
68
+ RotationISPyBCallback(
69
+ emit=ZocaloCallback(CONST.PLAN.ROTATION_MAIN, CONST.ZOCALO_ENV)
70
+ ),
71
+ )
50
72
 
51
73
 
52
- def create_load_centre_collect_callbacks() -> (
53
- tuple[
54
- GridscanNexusFileCallback,
55
- GridscanISPyBCallback,
56
- RobotLoadISPyBCallback,
57
- RotationNexusFileCallback,
58
- RotationISPyBCallback,
59
- SampleHandlingCallback,
60
- ]
61
- ):
74
+ def create_load_centre_collect_callbacks() -> tuple[
75
+ GridscanNexusFileCallback,
76
+ GridscanISPyBCallback,
77
+ RobotLoadISPyBCallback,
78
+ RotationNexusFileCallback,
79
+ RotationISPyBCallback,
80
+ SampleHandlingCallback,
81
+ ]:
82
+ """Note: This is not actually used in production, see https://github.com/DiamondLightSource/mx-bluesky/issues/516"""
62
83
  return (
63
- GridscanNexusFileCallback(),
64
- GridscanISPyBCallback(emit=ZocaloCallback()),
84
+ GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
85
+ GridscanISPyBCallback(
86
+ param_type=GridCommonWithHyperionDetectorParams,
87
+ emit=ZocaloCallback(CONST.PLAN.DO_FGS, CONST.ZOCALO_ENV),
88
+ ),
65
89
  RobotLoadISPyBCallback(),
66
90
  RotationNexusFileCallback(),
67
- RotationISPyBCallback(emit=ZocaloCallback()),
91
+ RotationISPyBCallback(
92
+ emit=ZocaloCallback(CONST.PLAN.ROTATION_MAIN, CONST.ZOCALO_ENV)
93
+ ),
68
94
  SampleHandlingCallback(),
69
95
  )
@@ -2,18 +2,18 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- from mx_bluesky.hyperion.external_interaction.callbacks.common.ispyb_mapping import (
5
+ from mx_bluesky.common.external_interaction.callbacks.common.ispyb_mapping import (
6
6
  get_proposal_and_session_from_visit_string,
7
7
  )
8
- from mx_bluesky.hyperion.external_interaction.callbacks.plan_reactive_callback import (
8
+ from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import (
9
9
  PlanReactiveCallback,
10
10
  )
11
- from mx_bluesky.hyperion.external_interaction.ispyb.exp_eye_store import (
11
+ from mx_bluesky.common.external_interaction.ispyb.exp_eye_store import (
12
12
  BLSampleStatus,
13
13
  ExpeyeInteraction,
14
14
  RobotActionID,
15
15
  )
16
- from mx_bluesky.hyperion.log import ISPYB_LOGGER
16
+ from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER
17
17
  from mx_bluesky.hyperion.parameters.constants import CONST
18
18
 
19
19
  if TYPE_CHECKING:
@@ -22,18 +22,23 @@ if TYPE_CHECKING:
22
22
 
23
23
  class RobotLoadISPyBCallback(PlanReactiveCallback):
24
24
  def __init__(self) -> None:
25
- ISPYB_LOGGER.debug("Initialising ISPyB Robot Load Callback")
26
- super().__init__(log=ISPYB_LOGGER)
25
+ ISPYB_ZOCALO_CALLBACK_LOGGER.debug("Initialising ISPyB Robot Load Callback")
26
+ super().__init__(log=ISPYB_ZOCALO_CALLBACK_LOGGER)
27
27
  self._metadata: dict | None = None
28
+
28
29
  self.run_uid: str | None = None
29
30
  self.descriptors: dict[str, EventDescriptor] = {}
30
31
  self.action_id: RobotActionID | None = None
31
32
  self.expeye = ExpeyeInteraction()
32
33
 
33
34
  def activity_gated_start(self, doc: RunStart):
34
- ISPYB_LOGGER.debug("ISPyB robot load callback received start document.")
35
+ ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
36
+ "ISPyB robot load callback received start document."
37
+ )
35
38
  if doc.get("subplan_name") == CONST.PLAN.ROBOT_LOAD:
36
- ISPYB_LOGGER.debug(f"ISPyB robot load callback received: {doc}")
39
+ ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
40
+ f"ISPyB robot load callback received: {doc}"
41
+ )
37
42
  self.run_uid = doc.get("uid")
38
43
  self._metadata = doc.get("metadata")
39
44
  assert isinstance(self._metadata, dict)
@@ -59,9 +64,9 @@ class RobotLoadISPyBCallback(PlanReactiveCallback):
59
64
  event_descriptor
60
65
  and event_descriptor.get("name") == CONST.DESCRIPTORS.ROBOT_LOAD
61
66
  ):
62
- assert (
63
- self.action_id is not None
64
- ), "ISPyB Robot load callback event called unexpectedly"
67
+ assert self.action_id is not None, (
68
+ "ISPyB Robot load callback event called unexpectedly"
69
+ )
65
70
  barcode = doc["data"]["robot-barcode"]
66
71
  oav_snapshot = doc["data"]["oav-snapshot-last_saved_path"]
67
72
  webcam_snapshot = doc["data"]["webcam-last_saved_path"]
@@ -73,11 +78,13 @@ class RobotLoadISPyBCallback(PlanReactiveCallback):
73
78
  return super().activity_gated_event(doc)
74
79
 
75
80
  def activity_gated_stop(self, doc: RunStop) -> RunStop | None:
76
- ISPYB_LOGGER.debug("ISPyB robot load callback received stop document.")
81
+ ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
82
+ "ISPyB robot load callback received stop document."
83
+ )
77
84
  if doc.get("run_start") == self.run_uid:
78
- assert (
79
- self.action_id is not None
80
- ), "ISPyB Robot load callback stop called unexpectedly"
85
+ assert self.action_id is not None, (
86
+ "ISPyB Robot load callback stop called unexpectedly"
87
+ )
81
88
  exit_status = doc.get("exit_status")
82
89
  assert exit_status, "Exit status not available in stop document!"
83
90
  assert self._metadata, "Metadata not received before stop document."