mx-bluesky 1.4.8__py3-none-any.whl → 1.5.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 (67) hide show
  1. mx_bluesky/_version.py +2 -2
  2. mx_bluesky/beamlines/aithre_lasershaping/__init__.py +8 -0
  3. mx_bluesky/beamlines/aithre_lasershaping/beamline_safe.py +36 -0
  4. mx_bluesky/beamlines/aithre_lasershaping/goniometer_controls.py +43 -0
  5. mx_bluesky/beamlines/i24/serial/__init__.py +4 -2
  6. mx_bluesky/beamlines/i24/serial/blueapi_config.yaml +6 -1
  7. mx_bluesky/beamlines/i24/serial/dcid.py +5 -5
  8. mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DetStage.edl +2 -2
  9. mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +9 -9
  10. mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +18 -3
  11. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DetStage.edl +2 -2
  12. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +14 -14
  13. mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +2 -2
  14. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +55 -4
  15. mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +9 -2
  16. mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +0 -8
  17. mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +77 -8
  18. mx_bluesky/common/device_setup_plans/manipulate_sample.py +9 -14
  19. mx_bluesky/common/device_setup_plans/utils.py +49 -0
  20. mx_bluesky/common/{plans → experiment_plans}/common_flyscan_xray_centre_plan.py +11 -19
  21. mx_bluesky/{hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py → common/experiment_plans/common_grid_detect_then_xray_centre_plan.py} +108 -126
  22. mx_bluesky/common/{plans → experiment_plans}/inner_plans/do_fgs.py +1 -1
  23. mx_bluesky/common/experiment_plans/oav_grid_detection_plan.py +5 -13
  24. mx_bluesky/{hyperion → common}/experiment_plans/oav_snapshot_plan.py +8 -2
  25. mx_bluesky/common/external_interaction/nexus/nexus_utils.py +2 -2
  26. mx_bluesky/common/parameters/components.py +1 -1
  27. mx_bluesky/common/parameters/device_composites.py +65 -0
  28. mx_bluesky/common/utils/__init__.py +0 -0
  29. mx_bluesky/common/utils/log.py +12 -11
  30. mx_bluesky/hyperion/__main__.py +6 -11
  31. mx_bluesky/hyperion/baton_handler.py +8 -3
  32. mx_bluesky/hyperion/device_setup_plans/smargon.py +2 -7
  33. mx_bluesky/hyperion/device_setup_plans/utils.py +0 -47
  34. mx_bluesky/hyperion/experiment_plans/__init__.py +5 -5
  35. mx_bluesky/hyperion/experiment_plans/experiment_registry.py +6 -7
  36. mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +40 -41
  37. mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py +60 -0
  38. mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +40 -10
  39. mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +26 -15
  40. mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +2 -11
  41. mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +8 -6
  42. mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -36
  43. mx_bluesky/hyperion/external_interaction/agamemnon.py +68 -62
  44. mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +1 -1
  45. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +3 -3
  46. mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +6 -3
  47. mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +2 -2
  48. mx_bluesky/hyperion/external_interaction/config_server.py +4 -1
  49. mx_bluesky/hyperion/parameters/cli.py +3 -10
  50. mx_bluesky/hyperion/parameters/constants.py +1 -1
  51. mx_bluesky/hyperion/parameters/device_composites.py +5 -27
  52. mx_bluesky/hyperion/parameters/load_centre_collect.py +4 -4
  53. mx_bluesky/hyperion/parameters/rotation.py +9 -8
  54. mx_bluesky/hyperion/utils/context.py +5 -2
  55. mx_bluesky/hyperion/utils/validation.py +11 -18
  56. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/METADATA +5 -5
  57. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/RECORD +65 -62
  58. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/WHEEL +1 -1
  59. mx_bluesky/common/device_setup_plans/check_beamstop.py +0 -27
  60. mx_bluesky/common/external_interaction/test_config_server.py +0 -38
  61. /mx_bluesky/common/{plans → experiment_plans}/__init__.py +0 -0
  62. /mx_bluesky/common/{plans → experiment_plans}/inner_plans/__init__ .py +0 -0
  63. /mx_bluesky/common/{plans → experiment_plans}/read_hardware.py +0 -0
  64. /mx_bluesky/common/{plans → experiment_plans}/write_sample_status.py +0 -0
  65. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/entry_points.txt +0 -0
  66. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/licenses/LICENSE +0 -0
  67. {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
+ from typing import Protocol, TypeVar
4
5
 
5
- from blueapi.core import BlueskyContext
6
6
  from bluesky import plan_stubs as bps
7
7
  from bluesky import preprocessors as bpp
8
8
  from bluesky.preprocessors import subs_decorator
@@ -10,20 +10,27 @@ from bluesky.utils import MsgGenerator
10
10
  from dodal.devices.backlight import BacklightPosition
11
11
  from dodal.devices.eiger import EigerDetector
12
12
  from dodal.devices.oav.oav_parameters import OAVParameters
13
- from dodal.plans.preprocessors.verify_undulator_gap import (
14
- verify_undulator_gap_before_run_decorator,
15
- )
16
13
 
17
14
  from mx_bluesky.common.device_setup_plans.manipulate_sample import (
18
15
  move_aperture_if_required,
19
16
  )
17
+ from mx_bluesky.common.device_setup_plans.utils import (
18
+ start_preparing_data_collection_then_do_plan,
19
+ )
20
20
  from mx_bluesky.common.experiment_plans.change_aperture_then_move_plan import (
21
21
  change_aperture_then_move_to_xtal,
22
22
  )
23
+ from mx_bluesky.common.experiment_plans.common_flyscan_xray_centre_plan import (
24
+ BeamlineSpecificFGSFeatures,
25
+ common_flyscan_xray_centre,
26
+ )
23
27
  from mx_bluesky.common.experiment_plans.oav_grid_detection_plan import (
24
28
  OavGridDetectionComposite,
25
29
  grid_detection_plan,
26
30
  )
31
+ from mx_bluesky.common.experiment_plans.oav_snapshot_plan import (
32
+ setup_beamline_for_OAV,
33
+ )
27
34
  from mx_bluesky.common.external_interaction.callbacks.common.grid_detection_callback import (
28
35
  GridDetectionCallback,
29
36
  GridParamUpdate,
@@ -31,59 +38,97 @@ from mx_bluesky.common.external_interaction.callbacks.common.grid_detection_call
31
38
  from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
32
39
  ispyb_activation_wrapper,
33
40
  )
34
- from mx_bluesky.common.parameters.constants import OavConstants
35
- from mx_bluesky.common.parameters.gridscan import GridCommon
36
- from mx_bluesky.common.plans.common_flyscan_xray_centre_plan import (
37
- BeamlineSpecificFGSFeatures,
38
- common_flyscan_xray_centre,
41
+ from mx_bluesky.common.parameters.constants import (
42
+ OavConstants,
43
+ PlanGroupCheckpointConstants,
39
44
  )
40
- from mx_bluesky.common.preprocessors.preprocessors import (
41
- transmission_and_xbpm_feedback_for_collection_decorator,
45
+ from mx_bluesky.common.parameters.device_composites import (
46
+ FlyScanEssentialDevices,
47
+ GridDetectThenXRayCentreComposite,
42
48
  )
43
- from mx_bluesky.common.utils.context import device_composite_from_context
49
+ from mx_bluesky.common.parameters.gridscan import GridCommon, SpecifiedThreeDGridScan
44
50
  from mx_bluesky.common.utils.log import LOGGER
45
51
  from mx_bluesky.common.xrc_result import XRayCentreEventHandler
46
- from mx_bluesky.hyperion.device_setup_plans.utils import (
47
- start_preparing_data_collection_then_do_plan,
48
- )
49
- from mx_bluesky.hyperion.experiment_plans.hyperion_flyscan_xray_centre_plan import (
50
- construct_hyperion_specific_features,
51
- )
52
- from mx_bluesky.hyperion.parameters.constants import CONST
53
- from mx_bluesky.hyperion.parameters.device_composites import (
54
- GridDetectThenXRayCentreComposite,
55
- HyperionFlyScanXRayCentreComposite,
52
+
53
+ TFlyScanEssentialDevices = TypeVar(
54
+ "TFlyScanEssentialDevices", bound=FlyScanEssentialDevices, contravariant=True
56
55
  )
57
- from mx_bluesky.hyperion.parameters.gridscan import (
58
- GridScanWithEdgeDetect,
59
- HyperionSpecifiedThreeDGridScan,
56
+ TSpecifiedThreeDGridScan = TypeVar(
57
+ "TSpecifiedThreeDGridScan", bound=SpecifiedThreeDGridScan, contravariant=True
60
58
  )
61
59
 
62
60
 
63
- def create_devices(context: BlueskyContext) -> GridDetectThenXRayCentreComposite:
64
- return device_composite_from_context(context, GridDetectThenXRayCentreComposite)
61
+ def grid_detect_then_xray_centre(
62
+ composite: GridDetectThenXRayCentreComposite,
63
+ parameters: GridCommon,
64
+ xrc_params_type: type[SpecifiedThreeDGridScan],
65
+ construct_beamline_specific: ConstructBeamlineSpecificFeatures,
66
+ oav_config: str = OavConstants.OAV_CONFIG_JSON,
67
+ ) -> MsgGenerator:
68
+ """
69
+ A plan which combines the collection of snapshots from the OAV and the determination
70
+ of the grid dimensions to use for the following grid scan.
71
+ """
65
72
 
73
+ eiger: EigerDetector = composite.eiger
66
74
 
67
- def create_parameters_for_flyscan_xray_centre(
68
- grid_scan_with_edge_params: GridCommon,
69
- grid_parameters: GridParamUpdate,
70
- ) -> HyperionSpecifiedThreeDGridScan:
71
- params_json = grid_scan_with_edge_params.model_dump()
72
- params_json.update(grid_parameters)
73
- flyscan_xray_centre_parameters = HyperionSpecifiedThreeDGridScan(**params_json)
74
- LOGGER.info(f"Parameters for FGS: {flyscan_xray_centre_parameters}")
75
- return flyscan_xray_centre_parameters
75
+ eiger.set_detector_parameters(parameters.detector_params)
76
+
77
+ oav_params = OAVParameters("xrayCentring", oav_config)
78
+
79
+ flyscan_event_handler = XRayCentreEventHandler()
80
+
81
+ @subs_decorator(flyscan_event_handler)
82
+ def plan_to_perform():
83
+ yield from ispyb_activation_wrapper(
84
+ detect_grid_and_do_gridscan(
85
+ composite,
86
+ parameters,
87
+ oav_params,
88
+ xrc_params_type,
89
+ construct_beamline_specific,
90
+ ),
91
+ parameters,
92
+ )
93
+
94
+ yield from start_preparing_data_collection_then_do_plan(
95
+ composite.beamstop,
96
+ eiger,
97
+ composite.detector_motion,
98
+ parameters.detector_params.detector_distance,
99
+ plan_to_perform(),
100
+ group=PlanGroupCheckpointConstants.GRID_READY_FOR_DC,
101
+ )
102
+
103
+ assert flyscan_event_handler.xray_centre_results, (
104
+ "Flyscan result event not received or no crystal found and exception not raised"
105
+ )
106
+
107
+ yield from change_aperture_then_move_to_xtal(
108
+ flyscan_event_handler.xray_centre_results[0],
109
+ composite.smargon,
110
+ composite.aperture_scatterguard,
111
+ )
76
112
 
77
113
 
78
114
  def detect_grid_and_do_gridscan(
79
115
  composite: GridDetectThenXRayCentreComposite,
80
116
  parameters: GridCommon,
81
117
  oav_params: OAVParameters,
118
+ xrc_params_type: type[SpecifiedThreeDGridScan],
119
+ construct_beamline_specific: ConstructBeamlineSpecificFeatures,
82
120
  ):
83
121
  snapshot_template = f"{parameters.detector_params.prefix}_{parameters.detector_params.run_number}_{{angle}}"
84
122
 
85
123
  grid_params_callback = GridDetectionCallback()
86
124
 
125
+ yield from setup_beamline_for_OAV(
126
+ composite.smargon,
127
+ composite.backlight,
128
+ composite.aperture_scatterguard,
129
+ wait=True,
130
+ )
131
+
87
132
  @bpp.subs_decorator([grid_params_callback])
88
133
  def run_grid_detection_plan(
89
134
  oav_params,
@@ -111,7 +156,7 @@ def detect_grid_and_do_gridscan(
111
156
  yield from bps.prepare(
112
157
  composite.aperture_scatterguard,
113
158
  parameters.selected_aperture,
114
- group=CONST.WAIT.PREPARE_APERTURE,
159
+ group=PlanGroupCheckpointConstants.PREPARE_APERTURE,
115
160
  )
116
161
 
117
162
  yield from run_grid_detection_plan(
@@ -121,105 +166,42 @@ def detect_grid_and_do_gridscan(
121
166
  )
122
167
 
123
168
  yield from bps.abs_set(
124
- composite.backlight, BacklightPosition.OUT, group=CONST.WAIT.GRID_READY_FOR_DC
169
+ composite.backlight,
170
+ BacklightPosition.OUT,
171
+ group=PlanGroupCheckpointConstants.GRID_READY_FOR_DC,
125
172
  )
126
173
 
127
- yield from bps.wait(CONST.WAIT.PREPARE_APERTURE)
174
+ yield from bps.wait(PlanGroupCheckpointConstants.PREPARE_APERTURE)
128
175
  yield from move_aperture_if_required(
129
176
  composite.aperture_scatterguard,
130
177
  parameters.selected_aperture,
131
- group=CONST.WAIT.GRID_READY_FOR_DC,
132
- )
133
-
134
- xrc_composite = HyperionFlyScanXRayCentreComposite(
135
- aperture_scatterguard=composite.aperture_scatterguard,
136
- attenuator=composite.attenuator,
137
- backlight=composite.backlight,
138
- eiger=composite.eiger,
139
- panda_fast_grid_scan=composite.panda_fast_grid_scan,
140
- flux=composite.flux,
141
- s4_slit_gaps=composite.s4_slit_gaps,
142
- smargon=composite.smargon,
143
- undulator=composite.undulator,
144
- synchrotron=composite.synchrotron,
145
- xbpm_feedback=composite.xbpm_feedback,
146
- zebra=composite.zebra,
147
- zocalo=composite.zocalo,
148
- panda=composite.panda,
149
- zebra_fast_grid_scan=composite.zebra_fast_grid_scan,
150
- dcm=composite.dcm,
151
- robot=composite.robot,
152
- sample_shutter=composite.sample_shutter,
178
+ group=PlanGroupCheckpointConstants.GRID_READY_FOR_DC,
153
179
  )
154
-
155
- params = create_parameters_for_flyscan_xray_centre(
156
- parameters, grid_params_callback.get_grid_parameters()
180
+ xrc_params = create_parameters_for_flyscan_xray_centre(
181
+ parameters, grid_params_callback.get_grid_parameters(), xrc_params_type
157
182
  )
183
+ beamline_specific = construct_beamline_specific(composite, xrc_params)
158
184
 
159
- beamline_specific = construct_hyperion_specific_features(xrc_composite, params)
185
+ yield from common_flyscan_xray_centre(composite, xrc_params, beamline_specific)
160
186
 
161
- yield from _gridscan_with_undulator_checks(xrc_composite, params, beamline_specific)
162
187
 
163
-
164
- def _gridscan_with_undulator_checks(
165
- composite: HyperionFlyScanXRayCentreComposite,
166
- params: HyperionSpecifiedThreeDGridScan,
167
- beamline_specific: BeamlineSpecificFGSFeatures,
188
+ class ConstructBeamlineSpecificFeatures(
189
+ Protocol[TFlyScanEssentialDevices, TSpecifiedThreeDGridScan]
168
190
  ):
169
- @transmission_and_xbpm_feedback_for_collection_decorator(
170
- composite, params.transmission_frac
171
- )
172
- @verify_undulator_gap_before_run_decorator(composite)
173
- def _inner():
174
- yield from common_flyscan_xray_centre(composite, params, beamline_specific)
175
-
176
- yield from _inner()
177
-
178
-
179
- def grid_detect_then_xray_centre(
180
- composite: GridDetectThenXRayCentreComposite,
181
- parameters: GridScanWithEdgeDetect,
182
- oav_config: str = OavConstants.OAV_CONFIG_JSON,
183
- ) -> MsgGenerator:
184
- """
185
- A plan which combines the collection of snapshots from the OAV and the determination
186
- of the grid dimensions to use for the following grid scan.
187
- """
188
-
189
- eiger: EigerDetector = composite.eiger
190
-
191
- eiger.set_detector_parameters(parameters.detector_params)
192
-
193
- oav_params = OAVParameters("xrayCentring", oav_config)
194
-
195
- flyscan_event_handler = XRayCentreEventHandler()
196
-
197
- @subs_decorator(flyscan_event_handler)
198
- def plan_to_perform():
199
- yield from ispyb_activation_wrapper(
200
- detect_grid_and_do_gridscan(
201
- composite,
202
- parameters,
203
- oav_params,
204
- ),
205
- parameters,
206
- )
191
+ def __call__(
192
+ self,
193
+ xrc_composite: TFlyScanEssentialDevices,
194
+ xrc_parameters: TSpecifiedThreeDGridScan,
195
+ ) -> BeamlineSpecificFGSFeatures: ...
207
196
 
208
- yield from start_preparing_data_collection_then_do_plan(
209
- composite.beamstop,
210
- eiger,
211
- composite.detector_motion,
212
- parameters.detector_params.detector_distance,
213
- plan_to_perform(),
214
- group=CONST.WAIT.GRID_READY_FOR_DC,
215
- )
216
197
 
217
- assert flyscan_event_handler.xray_centre_results, (
218
- "Flyscan result event not received or no crystal found and exception not raised"
219
- )
220
-
221
- yield from change_aperture_then_move_to_xtal(
222
- flyscan_event_handler.xray_centre_results[0],
223
- composite.smargon,
224
- composite.aperture_scatterguard,
225
- )
198
+ def create_parameters_for_flyscan_xray_centre(
199
+ parameters: GridCommon,
200
+ grid_parameters: GridParamUpdate,
201
+ xrc_params_type: type[SpecifiedThreeDGridScan],
202
+ ) -> SpecifiedThreeDGridScan:
203
+ params_json = parameters.model_dump()
204
+ params_json.update(grid_parameters)
205
+ flyscan_xray_centre_parameters = xrc_params_type(**params_json)
206
+ LOGGER.info(f"Parameters for FGS: {flyscan_xray_centre_parameters}")
207
+ return flyscan_xray_centre_parameters
@@ -14,10 +14,10 @@ from dodal.log import LOGGER
14
14
  from dodal.plan_stubs.check_topup import check_topup_and_wait_if_necessary
15
15
  from scanspec.core import AxesPoints, Axis
16
16
 
17
+ from mx_bluesky.common.experiment_plans.read_hardware import read_hardware_for_zocalo
17
18
  from mx_bluesky.common.parameters.constants import (
18
19
  PlanNameConstants,
19
20
  )
20
- from mx_bluesky.common.plans.read_hardware import read_hardware_for_zocalo
21
21
  from mx_bluesky.common.utils.tracing import TRACER
22
22
 
23
23
 
@@ -5,9 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  import bluesky.plan_stubs as bps
7
7
  import numpy as np
8
- import pydantic
9
8
  from blueapi.core import BlueskyContext
10
- from dodal.devices.backlight import Backlight
11
9
  from dodal.devices.oav.oav_detector import OAV
12
10
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
13
11
  from dodal.devices.oav.pin_image_recognition.utils import NONE_VALUE
@@ -17,7 +15,11 @@ from dodal.devices.smargon import Smargon
17
15
  from mx_bluesky.common.device_setup_plans.setup_oav import (
18
16
  pre_centring_setup_oav,
19
17
  )
20
- from mx_bluesky.common.parameters.constants import DocDescriptorNames, HardwareConstants
18
+ from mx_bluesky.common.parameters.constants import (
19
+ DocDescriptorNames,
20
+ HardwareConstants,
21
+ )
22
+ from mx_bluesky.common.parameters.device_composites import OavGridDetectionComposite
21
23
  from mx_bluesky.common.utils.context import device_composite_from_context
22
24
  from mx_bluesky.common.utils.exceptions import catch_exception_and_warn
23
25
  from mx_bluesky.common.utils.log import LOGGER
@@ -26,16 +28,6 @@ if TYPE_CHECKING:
26
28
  from dodal.devices.oav.oav_parameters import OAVParameters
27
29
 
28
30
 
29
- @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
30
- class OavGridDetectionComposite:
31
- """All devices which are directly or indirectly required by this plan"""
32
-
33
- backlight: Backlight
34
- oav: OAV
35
- smargon: Smargon
36
- pin_tip_detection: PinTipDetection
37
-
38
-
39
31
  def create_devices(context: BlueskyContext) -> OavGridDetectionComposite:
40
32
  return device_composite_from_context(context, OavGridDetectionComposite)
41
33
 
@@ -11,7 +11,10 @@ from dodal.devices.smargon import Smargon
11
11
 
12
12
  from mx_bluesky.common.device_setup_plans.setup_oav import setup_general_oav_params
13
13
  from mx_bluesky.common.parameters.components import WithSnapshot
14
- from mx_bluesky.hyperion.parameters.constants import CONST, DocDescriptorNames
14
+ from mx_bluesky.common.parameters.constants import (
15
+ DocDescriptorNames,
16
+ PlanGroupCheckpointConstants,
17
+ )
15
18
 
16
19
  OAV_SNAPSHOT_SETUP_SHOT = "oav_snapshot_setup_shot"
17
20
  OAV_SNAPSHOT_GROUP = "oav_snapshot_group"
@@ -28,7 +31,8 @@ def setup_beamline_for_OAV(
28
31
  smargon: Smargon,
29
32
  backlight: Backlight,
30
33
  aperture_scatterguard: ApertureScatterguard,
31
- group=CONST.WAIT.READY_FOR_OAV,
34
+ group=PlanGroupCheckpointConstants.READY_FOR_OAV,
35
+ wait=False,
32
36
  ):
33
37
  max_vel = yield from bps.rd(smargon.omega.max_velocity)
34
38
  yield from bps.abs_set(smargon.omega.velocity, max_vel, group=group)
@@ -36,6 +40,8 @@ def setup_beamline_for_OAV(
36
40
  yield from bps.abs_set(
37
41
  aperture_scatterguard.selected_aperture, ApertureValue.OUT_OF_BEAM, group=group
38
42
  )
43
+ if wait:
44
+ yield from bps.wait(group)
39
45
 
40
46
 
41
47
  def oav_snapshot_plan(
@@ -158,6 +158,6 @@ def create_beam_and_attenuator_parameters(
158
158
  tuple[Beam, Attenuator]: Descriptions of the beam and attenuator for nexgen.
159
159
  """
160
160
  return (
161
- Beam(convert_eV_to_angstrom(energy_kev * 1000), flux), # pyright: ignore
162
- Attenuator(transmission_fraction), # pyright: ignore
161
+ Beam(wavelength=convert_eV_to_angstrom(energy_kev * 1000), flux=flux),
162
+ Attenuator(transmission=transmission_fraction),
163
163
  )
@@ -136,7 +136,7 @@ class WithSnapshot(BaseModel):
136
136
 
137
137
  @model_validator(mode="after")
138
138
  def _validate_omegas_with_grid_snapshots(self) -> Self:
139
- assert not self.use_grid_snapshots or self.snapshot_omegas_deg is None, (
139
+ assert not self.use_grid_snapshots or not self.snapshot_omegas_deg, (
140
140
  "snapshot_omegas may not be specified with use_grid_snapshots"
141
141
  )
142
142
  return self
@@ -0,0 +1,65 @@
1
+ import pydantic
2
+ from dodal.devices.aperturescatterguard import (
3
+ ApertureScatterguard,
4
+ )
5
+ from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
6
+ from dodal.devices.backlight import Backlight
7
+ from dodal.devices.common_dcm import BaseDCM
8
+ from dodal.devices.detector.detector_motion import DetectorMotion
9
+ from dodal.devices.eiger import EigerDetector
10
+ from dodal.devices.fast_grid_scan import (
11
+ ZebraFastGridScan,
12
+ )
13
+ from dodal.devices.flux import Flux
14
+ from dodal.devices.i03 import Beamstop
15
+ from dodal.devices.oav.oav_detector import OAV
16
+ from dodal.devices.oav.pin_image_recognition import PinTipDetection
17
+ from dodal.devices.robot import BartRobot
18
+ from dodal.devices.s4_slit_gaps import S4SlitGaps
19
+ from dodal.devices.smargon import Smargon
20
+ from dodal.devices.synchrotron import Synchrotron
21
+ from dodal.devices.undulator import Undulator
22
+ from dodal.devices.xbpm_feedback import XBPMFeedback
23
+ from dodal.devices.zebra.zebra import Zebra
24
+ from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
25
+ from dodal.devices.zocalo import ZocaloResults
26
+
27
+
28
+ @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
29
+ class FlyScanEssentialDevices:
30
+ eiger: EigerDetector
31
+ synchrotron: Synchrotron
32
+ zocalo: ZocaloResults
33
+ smargon: Smargon
34
+
35
+
36
+ @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
37
+ class OavGridDetectionComposite:
38
+ """All devices which are directly or indirectly required by this plan"""
39
+
40
+ backlight: Backlight
41
+ oav: OAV
42
+ smargon: Smargon
43
+ pin_tip_detection: PinTipDetection
44
+
45
+
46
+ @pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
47
+ class GridDetectThenXRayCentreComposite(FlyScanEssentialDevices):
48
+ """All devices which are directly or indirectly required by this plan"""
49
+
50
+ aperture_scatterguard: ApertureScatterguard
51
+ attenuator: BinaryFilterAttenuator
52
+ backlight: Backlight
53
+ beamstop: Beamstop
54
+ dcm: BaseDCM
55
+ detector_motion: DetectorMotion
56
+ zebra_fast_grid_scan: ZebraFastGridScan
57
+ flux: Flux
58
+ oav: OAV
59
+ pin_tip_detection: PinTipDetection
60
+ s4_slit_gaps: S4SlitGaps
61
+ undulator: Undulator
62
+ xbpm_feedback: XBPMFeedback
63
+ zebra: Zebra
64
+ robot: BartRobot
65
+ sample_shutter: ZebraShutter
File without changes
@@ -66,7 +66,7 @@ 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
- logging_path, debug_logging_path = _get_logging_dirs()
69
+ logging_path, debug_logging_path = _get_logging_dirs(dev_mode)
70
70
  handlers = set_up_all_logging_handlers(
71
71
  dodal_logger,
72
72
  logging_path,
@@ -103,7 +103,7 @@ def flush_debug_handler() -> str:
103
103
  return handler.target.baseFilename
104
104
 
105
105
 
106
- def _get_logging_dirs() -> tuple[Path, Path]:
106
+ def _get_logging_dirs(dev_mode: bool) -> tuple[Path, Path]:
107
107
  """Get the paths to write the mx_bluesky log files to.
108
108
 
109
109
  Log location can be specified in the LOG_DIR environment variable, otherwise MX bluesky logs are written to 'dls_sw/ixx/logs/bluesky'.
@@ -115,17 +115,18 @@ def _get_logging_dirs() -> tuple[Path, Path]:
115
115
  tuple[Path, Path]: Paths to the standard log file and to the debug log file, for the file handlers to write to
116
116
  """
117
117
 
118
- logging_str = environ.get("LOG_DIR")
119
118
  beamline = environ.get("BEAMLINE")
120
- if logging_str:
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/")
119
+
120
+ if beamline and not dev_mode:
121
+ default_logging_str = f"/dls_sw/{beamline}/logs/bluesky/"
122
+ default_debug_logging_str = f"/dls/tmp/{beamline}/logs/bluesky/"
126
123
  else:
127
- logging_path = Path("/tmp/logs/bluesky")
128
- debug_logging_path = logging_path
124
+ default_logging_str = "/tmp/logs/bluesky"
125
+ default_debug_logging_str = default_logging_str
126
+
127
+ logging_path = Path(environ.get("LOG_DIR", default_logging_str))
128
+ debug_logging_path = Path(environ.get("DEBUG_LOG_DIR", default_debug_logging_str))
129
+
129
130
  Path.mkdir(logging_path, exist_ok=True, parents=True)
130
131
  Path.mkdir(debug_logging_path, exist_ok=True, parents=True)
131
132
  return logging_path, debug_logging_path
@@ -19,9 +19,6 @@ from pydantic.dataclasses import dataclass
19
19
  from mx_bluesky.common.external_interaction.callbacks.common.log_uid_tag_callback import (
20
20
  LogUidTaggingCallback,
21
21
  )
22
- from mx_bluesky.common.external_interaction.callbacks.common.logging_callback import (
23
- VerbosePlanExecutionLoggingCallback,
24
- )
25
22
  from mx_bluesky.common.parameters.components import MxBlueskyParameters
26
23
  from mx_bluesky.common.parameters.constants import Actions, Status
27
24
  from mx_bluesky.common.utils.exceptions import WarningException
@@ -41,10 +38,9 @@ from mx_bluesky.hyperion.external_interaction.agamemnon import (
41
38
  )
42
39
  from mx_bluesky.hyperion.parameters.cli import parse_cli_args
43
40
  from mx_bluesky.hyperion.parameters.constants import CONST
41
+ from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
44
42
  from mx_bluesky.hyperion.utils.context import setup_context
45
43
 
46
- VERBOSE_EVENT_LOGGING: bool | None = None
47
-
48
44
 
49
45
  @dataclass
50
46
  class Command:
@@ -97,9 +93,6 @@ class BlueskyRunner:
97
93
  self.publisher = Publisher(f"localhost:{CONST.CALLBACK_0MQ_PROXY_PORTS[0]}")
98
94
  RE.subscribe(self.publisher)
99
95
 
100
- if VERBOSE_EVENT_LOGGING:
101
- RE.subscribe(VerbosePlanExecutionLoggingCallback())
102
-
103
96
  def start(
104
97
  self,
105
98
  experiment: Callable,
@@ -198,7 +191,8 @@ def compose_start_args(context: BlueskyContext, plan_name: str, action: Actions)
198
191
  try:
199
192
  parameters = experiment_internal_param_type(**json.loads(request.data))
200
193
  parameters = update_params_from_agamemnon(parameters)
201
- compare_params(parameters)
194
+ if isinstance(parameters, LoadCentreCollect):
195
+ compare_params(parameters)
202
196
  if parameters.model_extra:
203
197
  raise ValueError(f"Extra fields not allowed {parameters.model_extra}")
204
198
  except Exception as e:
@@ -271,8 +265,9 @@ class FlushLogs(Resource):
271
265
  def create_app(
272
266
  test_config=None,
273
267
  RE: RunEngine = RunEngine({}),
268
+ dev_mode: bool = False,
274
269
  ) -> tuple[Flask, BlueskyRunner]:
275
- context = setup_context()
270
+ context = setup_context(dev_mode=dev_mode)
276
271
  runner = BlueskyRunner(
277
272
  RE,
278
273
  context=context,
@@ -305,7 +300,7 @@ def create_targets():
305
300
  CONST.LOG_FILE_NAME, CONST.GRAYLOG_PORT, dev_mode=args.dev_mode
306
301
  )
307
302
  LOGGER.info(f"Hyperion launched with args:{argv}")
308
- app, runner = create_app()
303
+ app, runner = create_app(dev_mode=args.dev_mode)
309
304
  return app, runner, hyperion_port, args.dev_mode
310
305
 
311
306
 
@@ -1,3 +1,5 @@
1
+ from collections.abc import Sequence
2
+
1
3
  from bluesky import plan_stubs as bps
2
4
  from bluesky import preprocessors as bpp
3
5
  from dodal.devices.baton import Baton
@@ -37,9 +39,12 @@ def main_hyperion_loop(baton: Baton, composite: LoadCentreCollectComposite):
37
39
  while requested_user == HYPERION_USER:
38
40
 
39
41
  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)
42
+ parameter_list: Sequence[LoadCentreCollect] = (
43
+ create_parameters_from_agamemnon()
44
+ )
45
+ if parameter_list:
46
+ for parameters in parameter_list:
47
+ yield from load_centre_collect_full(composite, parameters)
43
48
  else:
44
49
  yield from bps.mv(baton.requested_user, NO_USER)
45
50
 
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
2
  from bluesky import plan_stubs as bps
3
- from dodal.devices.smargon import Smargon
3
+ from dodal.devices.smargon import CombinedMove, Smargon
4
4
 
5
5
  from mx_bluesky.common.utils.exceptions import SampleException
6
6
 
@@ -16,10 +16,5 @@ def move_smargon_warn_on_out_of_range(
16
16
  "Pin tip centring failed - pin too long/short/bent and out of range"
17
17
  )
18
18
  yield from bps.mv(
19
- smargon.x,
20
- position[0],
21
- smargon.y,
22
- position[1],
23
- smargon.z,
24
- position[2],
19
+ smargon, CombinedMove(x=position[0], y=position[1], z=position[2])
25
20
  )