mx-bluesky 1.4.6__py3-none-any.whl → 1.4.8__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 (95) hide show
  1. mx_bluesky/_version.py +2 -2
  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 +35 -29
  6. mx_bluesky/beamlines/i04/thawing_plan.py +18 -3
  7. mx_bluesky/beamlines/i23/__init__.py +3 -0
  8. mx_bluesky/beamlines/i23/serial.py +71 -0
  9. mx_bluesky/beamlines/i24/serial/__init__.py +2 -0
  10. mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +12 -12
  11. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +36 -30
  12. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +3 -3
  13. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +15 -66
  14. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +8 -10
  15. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +10 -3
  16. mx_bluesky/beamlines/i24/serial/log.py +9 -9
  17. mx_bluesky/beamlines/i24/serial/parameters/utils.py +36 -7
  18. mx_bluesky/beamlines/i24/serial/set_visit_directory.sh +1 -1
  19. mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +16 -17
  20. mx_bluesky/beamlines/i24/serial/setup_beamline/pv_abstract.py +4 -4
  21. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +51 -52
  22. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +3 -2
  23. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +9 -7
  24. mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +71 -11
  25. mx_bluesky/beamlines/i24/serial/write_nexus.py +6 -5
  26. mx_bluesky/{hyperion → common}/device_setup_plans/check_beamstop.py +1 -1
  27. mx_bluesky/{hyperion → common}/device_setup_plans/manipulate_sample.py +1 -1
  28. mx_bluesky/{hyperion → common}/device_setup_plans/setup_oav.py +12 -6
  29. mx_bluesky/common/device_setup_plans/xbpm_feedback.py +45 -0
  30. mx_bluesky/{hyperion → common}/experiment_plans/change_aperture_then_move_plan.py +13 -29
  31. mx_bluesky/{hyperion → common}/experiment_plans/oav_grid_detection_plan.py +6 -6
  32. mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +8 -9
  33. mx_bluesky/common/external_interaction/callbacks/common/ispyb_mapping.py +1 -1
  34. mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py +18 -15
  35. mx_bluesky/{hyperion → common}/external_interaction/callbacks/sample_handling/sample_handling_callback.py +16 -4
  36. mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +50 -45
  37. mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py +2 -1
  38. mx_bluesky/common/external_interaction/ispyb/data_model.py +1 -0
  39. mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +18 -2
  40. mx_bluesky/common/external_interaction/ispyb/ispyb_utils.py +4 -4
  41. mx_bluesky/common/external_interaction/nexus/nexus_utils.py +1 -1
  42. mx_bluesky/common/parameters/components.py +22 -2
  43. mx_bluesky/common/parameters/constants.py +6 -16
  44. mx_bluesky/common/parameters/gridscan.py +36 -32
  45. mx_bluesky/common/plans/common_flyscan_xray_centre_plan.py +316 -0
  46. mx_bluesky/common/plans/inner_plans/__init__ .py +0 -0
  47. mx_bluesky/common/plans/read_hardware.py +3 -3
  48. mx_bluesky/common/plans/write_sample_status.py +46 -0
  49. mx_bluesky/common/preprocessors/__init__.py +0 -0
  50. mx_bluesky/common/preprocessors/preprocessors.py +105 -0
  51. mx_bluesky/common/protocols/__init__.py +0 -0
  52. mx_bluesky/common/protocols/protocols.py +10 -0
  53. mx_bluesky/common/utils/log.py +15 -12
  54. mx_bluesky/hyperion/__main__.py +5 -24
  55. mx_bluesky/hyperion/baton_handler.py +84 -0
  56. mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +4 -4
  57. mx_bluesky/hyperion/device_setup_plans/setup_panda.py +5 -1
  58. mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +0 -33
  59. mx_bluesky/hyperion/device_setup_plans/utils.py +4 -4
  60. mx_bluesky/hyperion/experiment_plans/__init__.py +0 -10
  61. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +0 -16
  62. mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +71 -88
  63. mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +183 -0
  64. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +17 -8
  65. mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +29 -8
  66. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +4 -4
  67. mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +6 -4
  68. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +11 -3
  69. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +9 -34
  70. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +35 -68
  71. mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +27 -8
  72. mx_bluesky/hyperion/external_interaction/agamemnon.py +140 -10
  73. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +17 -9
  74. mx_bluesky/hyperion/external_interaction/callbacks/snapshot_callback.py +259 -0
  75. mx_bluesky/hyperion/parameters/cli.py +2 -10
  76. mx_bluesky/hyperion/parameters/constants.py +0 -5
  77. mx_bluesky/hyperion/parameters/device_composites.py +40 -5
  78. mx_bluesky/hyperion/parameters/gridscan.py +9 -58
  79. mx_bluesky/hyperion/parameters/rotation.py +1 -5
  80. mx_bluesky/hyperion/utils/context.py +2 -5
  81. mx_bluesky/hyperion/utils/validation.py +13 -10
  82. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info}/METADATA +10 -9
  83. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info}/RECORD +92 -79
  84. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info}/WHEEL +1 -1
  85. mx_bluesky/common/external_interaction/callbacks/common/aperture_change_callback.py +0 -22
  86. mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +0 -103
  87. mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +0 -466
  88. /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short1-laser.png → s1l.png} +0 -0
  89. /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short2-laser.png → s2l.png} +0 -0
  90. /mx_bluesky/{hyperion → common}/device_setup_plans/position_detector.py +0 -0
  91. /mx_bluesky/{hyperion → common}/external_interaction/callbacks/sample_handling/__init__.py +0 -0
  92. /mx_bluesky/common/plans/{do_fgs.py → inner_plans/do_fgs.py} +0 -0
  93. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info}/entry_points.txt +0 -0
  94. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info/licenses}/LICENSE +0 -0
  95. {mx_bluesky-1.4.6.dist-info → mx_bluesky-1.4.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,10 @@
1
+ from typing import Protocol, runtime_checkable
2
+
3
+ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
4
+ from dodal.devices.xbpm_feedback import XBPMFeedback
5
+
6
+
7
+ @runtime_checkable
8
+ class XBPMPauseDevices(Protocol):
9
+ xbpm_feedback: XBPMFeedback
10
+ attenuator: BinaryFilterAttenuator
@@ -66,14 +66,15 @@ def do_default_logging_setup(
66
66
  """Configures dodal logger so that separate debug and info log files are created,
67
67
  info logs are sent to Graylog, info logs are streamed to sys.sterr, and logs from ophyd
68
68
  and bluesky and ophyd-async are optionally included."""
69
-
69
+ logging_path, debug_logging_path = _get_logging_dirs()
70
70
  handlers = set_up_all_logging_handlers(
71
71
  dodal_logger,
72
- _get_logging_dir(),
72
+ logging_path,
73
73
  file_name,
74
74
  dev_mode,
75
75
  ERROR_LOG_BUFFER_LINES,
76
76
  graylog_port,
77
+ debug_logging_path,
77
78
  )
78
79
 
79
80
  if integrate_all_logs:
@@ -102,8 +103,8 @@ def flush_debug_handler() -> str:
102
103
  return handler.target.baseFilename
103
104
 
104
105
 
105
- def _get_logging_dir() -> Path:
106
- """Get the path to write the mx_bluesky log files to.
106
+ def _get_logging_dirs() -> tuple[Path, Path]:
107
+ """Get the paths to write the mx_bluesky log files to.
107
108
 
108
109
  Log location can be specified in the LOG_DIR environment variable, otherwise MX bluesky logs are written to 'dls_sw/ixx/logs/bluesky'.
109
110
  This directory will be created if it is not found
@@ -111,18 +112,20 @@ def _get_logging_dir() -> Path:
111
112
  Logs are written to ./tmp/logs/bluesky if BEAMLINE environment variable is not found
112
113
 
113
114
  Returns:
114
- logging_path (Path): Path to the log file for the file handler to write to.
115
+ tuple[Path, Path]: Paths to the standard log file and to the debug log file, for the file handlers to write to
115
116
  """
116
117
 
117
118
  logging_str = environ.get("LOG_DIR")
119
+ beamline = environ.get("BEAMLINE")
118
120
  if logging_str:
119
121
  logging_path = Path(logging_str)
122
+ debug_logging_path = logging_path
123
+ elif beamline:
124
+ logging_path = Path(f"/dls_sw/{beamline}/logs/bluesky/")
125
+ debug_logging_path = Path(f"/dls/tmp/{beamline}/logs/bluesky/")
120
126
  else:
121
- beamline = environ.get("BEAMLINE")
122
- logging_path = (
123
- Path(f"/dls_sw/{beamline}/logs/bluesky/")
124
- if beamline
125
- else Path("/tmp/logs/bluesky")
126
- )
127
+ logging_path = Path("/tmp/logs/bluesky")
128
+ debug_logging_path = logging_path
127
129
  Path.mkdir(logging_path, exist_ok=True, parents=True)
128
- return logging_path
130
+ Path.mkdir(debug_logging_path, exist_ok=True, parents=True)
131
+ return logging_path, debug_logging_path
@@ -16,9 +16,6 @@ from flask import Flask, request
16
16
  from flask_restful import Api, Resource
17
17
  from pydantic.dataclasses import dataclass
18
18
 
19
- from mx_bluesky.common.external_interaction.callbacks.common.aperture_change_callback import (
20
- ApertureChangeCallback,
21
- )
22
19
  from mx_bluesky.common.external_interaction.callbacks.common.log_uid_tag_callback import (
23
20
  LogUidTaggingCallback,
24
21
  )
@@ -39,6 +36,7 @@ from mx_bluesky.hyperion.experiment_plans.experiment_registry import (
39
36
  PlanNotFound,
40
37
  )
41
38
  from mx_bluesky.hyperion.external_interaction.agamemnon import (
39
+ compare_params,
42
40
  update_params_from_agamemnon,
43
41
  )
44
42
  from mx_bluesky.hyperion.parameters.cli import parse_cli_args
@@ -84,18 +82,15 @@ class BlueskyRunner:
84
82
  self,
85
83
  RE: RunEngine,
86
84
  context: BlueskyContext,
87
- skip_startup_connection=False,
88
85
  ) -> None:
89
86
  self.command_queue: Queue[Command] = Queue()
90
87
  self.current_status: StatusAndMessage = StatusAndMessage(Status.IDLE)
91
88
  self.last_run_aborted: bool = False
92
- self.aperture_change_callback = ApertureChangeCallback()
93
89
  self.logging_uid_tag_callback = LogUidTaggingCallback()
94
90
  self.context: BlueskyContext
95
91
 
96
92
  self.RE = RE
97
93
  self.context = context
98
- RE.subscribe(self.aperture_change_callback)
99
94
  RE.subscribe(self.logging_uid_tag_callback)
100
95
 
101
96
  LOGGER.info("Connecting to external callback ZMQ proxy...")
@@ -105,12 +100,6 @@ class BlueskyRunner:
105
100
  if VERBOSE_EVENT_LOGGING:
106
101
  RE.subscribe(VerbosePlanExecutionLoggingCallback())
107
102
 
108
- self.skip_startup_connection = skip_startup_connection
109
- if not self.skip_startup_connection:
110
- LOGGER.info("Initialising dodal devices...")
111
- for plan_name in PLAN_REGISTRY:
112
- PLAN_REGISTRY[plan_name]["setup"](context)
113
-
114
103
  def start(
115
104
  self,
116
105
  experiment: Callable,
@@ -175,10 +164,7 @@ class BlueskyRunner:
175
164
  with TRACER.start_span("do_run"):
176
165
  self.RE(command.experiment(command.devices, command.parameters))
177
166
 
178
- self.current_status = StatusAndMessage(
179
- Status.IDLE,
180
- self.aperture_change_callback.last_selected_aperture,
181
- )
167
+ self.current_status = StatusAndMessage(Status.IDLE)
182
168
 
183
169
  self.last_run_aborted = False
184
170
  except WarningException as exception:
@@ -212,6 +198,7 @@ def compose_start_args(context: BlueskyContext, plan_name: str, action: Actions)
212
198
  try:
213
199
  parameters = experiment_internal_param_type(**json.loads(request.data))
214
200
  parameters = update_params_from_agamemnon(parameters)
201
+ compare_params(parameters)
215
202
  if parameters.model_extra:
216
203
  raise ValueError(f"Extra fields not allowed {parameters.model_extra}")
217
204
  except Exception as e:
@@ -284,15 +271,11 @@ class FlushLogs(Resource):
284
271
  def create_app(
285
272
  test_config=None,
286
273
  RE: RunEngine = RunEngine({}),
287
- skip_startup_connection: bool = False,
288
274
  ) -> tuple[Flask, BlueskyRunner]:
289
- context = setup_context(
290
- wait_for_connection=not skip_startup_connection,
291
- )
275
+ context = setup_context()
292
276
  runner = BlueskyRunner(
293
277
  RE,
294
278
  context=context,
295
- skip_startup_connection=skip_startup_connection,
296
279
  )
297
280
  app = Flask(__name__)
298
281
  if test_config:
@@ -322,9 +305,7 @@ def create_targets():
322
305
  CONST.LOG_FILE_NAME, CONST.GRAYLOG_PORT, dev_mode=args.dev_mode
323
306
  )
324
307
  LOGGER.info(f"Hyperion launched with args:{argv}")
325
- app, runner = create_app(
326
- skip_startup_connection=args.skip_startup_connection,
327
- )
308
+ app, runner = create_app()
328
309
  return app, runner, hyperion_port, args.dev_mode
329
310
 
330
311
 
@@ -0,0 +1,84 @@
1
+ from bluesky import plan_stubs as bps
2
+ from bluesky import preprocessors as bpp
3
+ from dodal.devices.baton import Baton
4
+
5
+ from mx_bluesky.common.utils.exceptions import WarningException
6
+ from mx_bluesky.hyperion.experiment_plans.load_centre_collect_full_plan import (
7
+ LoadCentreCollectComposite,
8
+ load_centre_collect_full,
9
+ )
10
+ from mx_bluesky.hyperion.external_interaction.agamemnon import (
11
+ create_parameters_from_agamemnon,
12
+ )
13
+ from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
14
+
15
+ HYPERION_USER = "Hyperion"
16
+ NO_USER = "None"
17
+
18
+
19
+ def wait_for_hyperion_requested(baton: Baton):
20
+ SLEEP_PER_CHECK = 0.1
21
+ while True:
22
+ requested_user = yield from bps.rd(baton.requested_user)
23
+ if requested_user == HYPERION_USER:
24
+ break
25
+ yield from bps.sleep(SLEEP_PER_CHECK)
26
+
27
+
28
+ def ignore_sample_errors(exception: Exception):
29
+ yield from bps.null()
30
+ # For sample errors we want to continue the loop
31
+ if not isinstance(exception, WarningException):
32
+ raise exception
33
+
34
+
35
+ def main_hyperion_loop(baton: Baton, composite: LoadCentreCollectComposite):
36
+ requested_user = yield from bps.rd(baton.requested_user)
37
+ while requested_user == HYPERION_USER:
38
+
39
+ def inner_loop():
40
+ parameters: LoadCentreCollect | None = create_parameters_from_agamemnon() # type: ignore # not complete until https://github.com/DiamondLightSource/mx-bluesky/issues/773
41
+ if parameters:
42
+ yield from load_centre_collect_full(composite, parameters)
43
+ else:
44
+ yield from bps.mv(baton.requested_user, NO_USER)
45
+
46
+ yield from bpp.contingency_wrapper(
47
+ inner_loop(), except_plan=ignore_sample_errors, auto_raise=False
48
+ )
49
+ requested_user = yield from bps.rd(baton.requested_user)
50
+
51
+
52
+ def move_to_default_state():
53
+ # To be filled in in https://github.com/DiamondLightSource/mx-bluesky/issues/396
54
+ yield from bps.null()
55
+
56
+
57
+ def run_udc_when_requested(baton: Baton, composite: LoadCentreCollectComposite):
58
+ """This will wait for the baton to be handed to hyperion and then run through the
59
+ UDC queue from agamemnon until:
60
+ 1. There are no more instructions from agamemnon
61
+ 2. There is an error on the beamline
62
+ 3. The baton is requested by another party
63
+
64
+ In the case of 1. or 2. hyperion will immediately release the baton. In the case of
65
+ 3. the baton will be released after the next collection has finished."""
66
+
67
+ yield from wait_for_hyperion_requested(baton)
68
+ yield from bps.abs_set(baton.current_user, HYPERION_USER)
69
+
70
+ def default_state_then_collect():
71
+ yield from move_to_default_state()
72
+ yield from main_hyperion_loop(baton, composite)
73
+
74
+ def release_baton():
75
+ # If hyperion has given up the baton itself we need to also release requested
76
+ # user so that hyperion doesn't think we're requested again
77
+ requested_user = yield from bps.rd(baton.requested_user)
78
+ if requested_user == HYPERION_USER:
79
+ yield from bps.abs_set(baton.requested_user, NO_USER)
80
+ yield from bps.abs_set(baton.current_user, NO_USER)
81
+
82
+ yield from bpp.contingency_wrapper(
83
+ default_state_then_collect(), final_plan=release_baton
84
+ )
@@ -6,7 +6,7 @@ from dodal.devices.focusing_mirror import (
6
6
  MirrorStripe,
7
7
  MirrorVoltages,
8
8
  )
9
- from dodal.devices.undulator_dcm import UndulatorDCM
9
+ from dodal.devices.i03.undulator_dcm import UndulatorDCM
10
10
  from dodal.devices.util.adjuster_plans import lookup_table_adjuster
11
11
  from dodal.devices.util.lookup_tables import (
12
12
  linear_interpolation_lut,
@@ -102,7 +102,7 @@ def adjust_dcm_pitch_roll_vfm_from_lut(
102
102
  dcm = undulator_dcm.dcm_ref()
103
103
  LOGGER.info(f"Adjusting DCM and VFM for {energy_kev} keV")
104
104
  d_spacing_a: float = yield from bps.rd(
105
- undulator_dcm.dcm_ref().crystal_metadata_d_spacing
105
+ undulator_dcm.dcm_ref().crystal_metadata_d_spacing_a
106
106
  )
107
107
  bragg_deg = energy_to_bragg_angle(energy_kev, d_spacing_a)
108
108
  LOGGER.info(f"Target Bragg angle = {bragg_deg} degrees")
@@ -110,7 +110,7 @@ def adjust_dcm_pitch_roll_vfm_from_lut(
110
110
  linear_interpolation_lut(
111
111
  *parse_lookup_table(undulator_dcm.pitch_energy_table_path)
112
112
  ),
113
- dcm.pitch_in_mrad,
113
+ dcm.xtal_1.pitch_in_mrad,
114
114
  bragg_deg,
115
115
  )
116
116
  yield from dcm_pitch_adjuster(DCM_GROUP)
@@ -122,7 +122,7 @@ def adjust_dcm_pitch_roll_vfm_from_lut(
122
122
  linear_interpolation_lut(
123
123
  *parse_lookup_table(undulator_dcm.roll_energy_table_path)
124
124
  ),
125
- dcm.roll_in_mrad,
125
+ dcm.xtal_1.roll_in_mrad,
126
126
  bragg_deg,
127
127
  )
128
128
  yield from dcm_roll_adjuster(DCM_GROUP)
@@ -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])
@@ -1,8 +1,4 @@
1
- from collections.abc import Callable
2
- from functools import wraps
3
-
4
1
  import bluesky.plan_stubs as bps
5
- import bluesky.preprocessors as bpp
6
2
  from bluesky.utils import MsgGenerator
7
3
  from dodal.devices.zebra.zebra import (
8
4
  ArmDemand,
@@ -21,31 +17,6 @@ from mx_bluesky.common.utils.log import LOGGER
21
17
  ZEBRA_STATUS_TIMEOUT = 30
22
18
 
23
19
 
24
- def bluesky_retry(func: Callable):
25
- """Decorator that will retry the decorated plan if it fails.
26
-
27
- Use this with care as it knows nothing about the state of the world when things fail.
28
- If it is possible that your plan fails when the beamline is in a transient state that
29
- the plan could not act on do not use this decorator without doing some more intelligent
30
- clean up.
31
-
32
- You should avoid using this decorator often in general production as it hides errors,
33
- instead it should be used only for debugging these underlying errors.
34
- """
35
-
36
- @wraps(func)
37
- def newfunc(*args, **kwargs):
38
- def log_and_retry(exception):
39
- LOGGER.error(f"Function {func.__name__} failed with {exception}, retrying")
40
- yield from func(*args, **kwargs)
41
-
42
- yield from bpp.contingency_wrapper(
43
- func(*args, **kwargs), except_plan=log_and_retry, auto_raise=False
44
- )
45
-
46
- return newfunc
47
-
48
-
49
20
  def arm_zebra(zebra: Zebra):
50
21
  yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True)
51
22
 
@@ -105,7 +76,6 @@ def configure_zebra_and_shutter_for_auto_shutter(
105
76
  yield from set_shutter_auto_input(zebra, input, group=group)
106
77
 
107
78
 
108
- @bluesky_retry
109
79
  def setup_zebra_for_rotation(
110
80
  zebra: Zebra,
111
81
  zebra_shutter: ZebraShutter,
@@ -185,7 +155,6 @@ def setup_zebra_for_rotation(
185
155
  yield from bps.wait(group, timeout=ZEBRA_STATUS_TIMEOUT)
186
156
 
187
157
 
188
- @bluesky_retry
189
158
  def setup_zebra_for_gridscan(
190
159
  zebra: Zebra,
191
160
  zebra_shutter: ZebraShutter,
@@ -215,7 +184,6 @@ def setup_zebra_for_gridscan(
215
184
  yield from bps.wait(group, timeout=ZEBRA_STATUS_TIMEOUT)
216
185
 
217
186
 
218
- @bluesky_retry
219
187
  def tidy_up_zebra_after_gridscan(
220
188
  zebra: Zebra,
221
189
  zebra_shutter: ZebraShutter,
@@ -236,7 +204,6 @@ def tidy_up_zebra_after_gridscan(
236
204
  yield from bps.wait(group, timeout=ZEBRA_STATUS_TIMEOUT)
237
205
 
238
206
 
239
- @bluesky_retry
240
207
  def setup_zebra_for_panda_flyscan(
241
208
  zebra: Zebra,
242
209
  zebra_shutter: ZebraShutter,
@@ -3,16 +3,16 @@ from collections.abc import Generator
3
3
  from bluesky import plan_stubs as bps
4
4
  from bluesky import preprocessors as bpp
5
5
  from bluesky.utils import Msg
6
- from dodal.devices.dcm import DCM
7
6
  from dodal.devices.detector import (
8
7
  DetectorParams,
9
8
  )
10
9
  from dodal.devices.detector.detector_motion import DetectorMotion, ShutterState
11
10
  from dodal.devices.eiger import EigerDetector
12
- from dodal.devices.i03.beamstop import Beamstop
11
+ from dodal.devices.i03 import Beamstop
12
+ from dodal.devices.i03.dcm import DCM
13
13
 
14
- from mx_bluesky.hyperion.device_setup_plans.check_beamstop import check_beamstop
15
- from mx_bluesky.hyperion.device_setup_plans.position_detector import (
14
+ from mx_bluesky.common.device_setup_plans.check_beamstop import check_beamstop
15
+ from mx_bluesky.common.device_setup_plans.position_detector import (
16
16
  set_detector_z_position,
17
17
  set_shutter,
18
18
  )
@@ -3,9 +3,6 @@
3
3
  The __all__ list in here are the plans that are externally available from outside Hyperion.
4
4
  """
5
5
 
6
- from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
7
- flyscan_xray_centre,
8
- )
9
6
  from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import (
10
7
  grid_detect_then_xray_centre,
11
8
  )
@@ -15,20 +12,13 @@ from mx_bluesky.hyperion.experiment_plans.load_centre_collect_full_plan import (
15
12
  from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan import (
16
13
  pin_tip_centre_then_xray_centre,
17
14
  )
18
- from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
19
- robot_load_then_centre,
20
- )
21
15
  from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
22
16
  multi_rotation_scan,
23
- rotation_scan,
24
17
  )
25
18
 
26
19
  __all__ = [
27
- "flyscan_xray_centre",
28
20
  "grid_detect_then_xray_centre",
29
- "rotation_scan",
30
21
  "pin_tip_centre_then_xray_centre",
31
22
  "multi_rotation_scan",
32
- "robot_load_then_centre",
33
23
  "load_centre_collect_full",
34
24
  ]
@@ -3,13 +3,11 @@ from __future__ import annotations
3
3
  from collections.abc import Callable
4
4
  from typing import TypedDict
5
5
 
6
- import mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan as flyscan_xray_centre_plan
7
6
  import mx_bluesky.hyperion.experiment_plans.rotation_scan_plan as rotation_scan_plan
8
7
  from mx_bluesky.hyperion.experiment_plans import (
9
8
  grid_detect_then_xray_centre_plan,
10
9
  load_centre_collect_full_plan,
11
10
  pin_centre_then_xray_centre_plan,
12
- robot_load_then_centre_plan,
13
11
  )
14
12
  from mx_bluesky.hyperion.parameters.gridscan import (
15
13
  GridScanWithEdgeDetect,
@@ -17,7 +15,6 @@ from mx_bluesky.hyperion.parameters.gridscan import (
17
15
  PinTipCentreThenXrayCentre,
18
16
  )
19
17
  from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
20
- from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre
21
18
  from mx_bluesky.hyperion.parameters.rotation import MultiRotationScan, RotationScan
22
19
 
23
20
 
@@ -38,31 +35,18 @@ class ExperimentRegistryEntry(TypedDict):
38
35
  | MultiRotationScan
39
36
  | PinTipCentreThenXrayCentre
40
37
  | LoadCentreCollect
41
- | RobotLoadThenCentre
42
38
  ]
43
39
 
44
40
 
45
41
  PLAN_REGISTRY: dict[str, ExperimentRegistryEntry] = {
46
- "flyscan_xray_centre": {
47
- "setup": flyscan_xray_centre_plan.create_devices,
48
- "param_type": HyperionSpecifiedThreeDGridScan,
49
- },
50
42
  "grid_detect_then_xray_centre": {
51
43
  "setup": grid_detect_then_xray_centre_plan.create_devices,
52
44
  "param_type": GridScanWithEdgeDetect,
53
45
  },
54
- "rotation_scan": {
55
- "setup": rotation_scan_plan.create_devices,
56
- "param_type": RotationScan,
57
- },
58
46
  "pin_tip_centre_then_xray_centre": {
59
47
  "setup": pin_centre_then_xray_centre_plan.create_devices,
60
48
  "param_type": PinTipCentreThenXrayCentre,
61
49
  },
62
- "robot_load_then_centre": {
63
- "setup": robot_load_then_centre_plan.create_devices,
64
- "param_type": RobotLoadThenCentre,
65
- },
66
50
  "multi_rotation_scan": {
67
51
  "setup": rotation_scan_plan.create_devices,
68
52
  "param_type": MultiRotationScan,