mx-bluesky 1.4.0__py3-none-any.whl → 1.4.1__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.
- mx_bluesky/_version.py +2 -2
- mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +178 -0
- mx_bluesky/beamlines/i04/thawing_plan.py +1 -1
- mx_bluesky/beamlines/i24/serial/dcid.py +143 -171
- mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +1 -1
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +54 -21
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +2 -5
- mx_bluesky/beamlines/i24/serial/fixed_target/ft_utils.py +0 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +67 -50
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +26 -79
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -199
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +4 -6
- mx_bluesky/beamlines/i24/serial/log.py +1 -1
- mx_bluesky/beamlines/i24/serial/parameters/__init__.py +4 -0
- mx_bluesky/beamlines/i24/serial/parameters/constants.py +6 -1
- mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +42 -15
- mx_bluesky/beamlines/i24/serial/run_fixed_target.sh +4 -3
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +103 -81
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +1 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +24 -26
- mx_bluesky/beamlines/i24/serial/write_nexus.py +74 -72
- mx_bluesky/common/external_interaction/config_server.py +46 -0
- mx_bluesky/common/parameters/components.py +52 -15
- mx_bluesky/common/parameters/constants.py +11 -1
- mx_bluesky/common/parameters/gridscan.py +94 -0
- mx_bluesky/{hyperion → common}/parameters/robot_load.py +2 -2
- mx_bluesky/common/plans/do_fgs.py +2 -2
- mx_bluesky/common/utils/log.py +2 -0
- mx_bluesky/hyperion/__main__.py +2 -1
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +21 -31
- mx_bluesky/hyperion/device_setup_plans/setup_panda.py +4 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +1 -1
- mx_bluesky/hyperion/device_setup_plans/smargon.py +3 -3
- mx_bluesky/hyperion/exceptions.py +13 -1
- mx_bluesky/hyperion/experiment_plans/__init__.py +4 -0
- mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +83 -0
- mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +47 -0
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +133 -97
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +42 -18
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +75 -9
- mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +1 -1
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +36 -17
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +5 -5
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +28 -28
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +64 -16
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +11 -3
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +10 -10
- mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +4 -0
- mx_bluesky/hyperion/external_interaction/callbacks/common/abstract_event.py +66 -0
- mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +5 -0
- mx_bluesky/hyperion/external_interaction/callbacks/grid_detection_callback.py +15 -15
- mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +18 -10
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +3 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +5 -3
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +84 -0
- mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/ispyb_callback.py +15 -9
- mx_bluesky/hyperion/external_interaction/callbacks/xray_centre/nexus_callback.py +5 -4
- mx_bluesky/hyperion/external_interaction/config_server.py +8 -37
- mx_bluesky/hyperion/external_interaction/exceptions.py +0 -9
- mx_bluesky/hyperion/external_interaction/ispyb/exp_eye_store.py +65 -15
- mx_bluesky/hyperion/parameters/components.py +4 -9
- mx_bluesky/hyperion/parameters/constants.py +0 -1
- mx_bluesky/hyperion/parameters/gridscan.py +33 -76
- mx_bluesky/hyperion/parameters/load_centre_collect.py +14 -9
- mx_bluesky/hyperion/parameters/rotation.py +15 -6
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/METADATA +35 -34
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/RECORD +77 -70
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/WHEEL +1 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +0 -150
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/LICENSE +0 -0
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.0.dist-info → mx_bluesky-1.4.1.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import dataclasses
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
import pydantic
|
|
6
|
+
from blueapi.core import BlueskyContext
|
|
7
7
|
from bluesky import plan_stubs as bps
|
|
8
8
|
from bluesky import preprocessors as bpp
|
|
9
|
+
from bluesky.preprocessors import subs_decorator
|
|
10
|
+
from bluesky.utils import MsgGenerator
|
|
9
11
|
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
10
12
|
from dodal.devices.attenuator import Attenuator
|
|
11
13
|
from dodal.devices.backlight import Backlight, BacklightPosition
|
|
@@ -29,17 +31,22 @@ from dodal.devices.zocalo import ZocaloResults
|
|
|
29
31
|
from ophyd_async.fastcs.panda import HDFPanda
|
|
30
32
|
|
|
31
33
|
from mx_bluesky.common.parameters.constants import OavConstants
|
|
34
|
+
from mx_bluesky.common.parameters.gridscan import GridScanWithEdgeDetect
|
|
32
35
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
|
|
33
36
|
move_aperture_if_required,
|
|
34
37
|
)
|
|
35
38
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
36
39
|
start_preparing_data_collection_then_do_plan,
|
|
37
40
|
)
|
|
41
|
+
from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import (
|
|
42
|
+
change_aperture_then_move_to_xtal,
|
|
43
|
+
)
|
|
38
44
|
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
39
45
|
FlyScanXRayCentreComposite as FlyScanXRayCentreComposite,
|
|
40
46
|
)
|
|
41
47
|
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
42
|
-
|
|
48
|
+
XRayCentreEventHandler,
|
|
49
|
+
flyscan_xray_centre_no_move,
|
|
43
50
|
)
|
|
44
51
|
from mx_bluesky.hyperion.experiment_plans.oav_grid_detection_plan import (
|
|
45
52
|
OavGridDetectionComposite,
|
|
@@ -55,13 +62,12 @@ from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.ispyb_callba
|
|
|
55
62
|
from mx_bluesky.hyperion.log import LOGGER
|
|
56
63
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
57
64
|
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
58
|
-
|
|
59
|
-
ThreeDGridScan,
|
|
65
|
+
HyperionThreeDGridScan,
|
|
60
66
|
)
|
|
61
67
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
62
68
|
|
|
63
69
|
|
|
64
|
-
@dataclasses.dataclass
|
|
70
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
65
71
|
class GridDetectThenXRayCentreComposite:
|
|
66
72
|
"""All devices which are directly or indirectly required by this plan"""
|
|
67
73
|
|
|
@@ -87,6 +93,10 @@ class GridDetectThenXRayCentreComposite:
|
|
|
87
93
|
robot: BartRobot
|
|
88
94
|
sample_shutter: ZebraShutter
|
|
89
95
|
|
|
96
|
+
@property
|
|
97
|
+
def sample_motors(self):
|
|
98
|
+
return self.smargon
|
|
99
|
+
|
|
90
100
|
|
|
91
101
|
def create_devices(context: BlueskyContext) -> GridDetectThenXRayCentreComposite:
|
|
92
102
|
return device_composite_from_context(context, GridDetectThenXRayCentreComposite)
|
|
@@ -95,10 +105,10 @@ def create_devices(context: BlueskyContext) -> GridDetectThenXRayCentreComposite
|
|
|
95
105
|
def create_parameters_for_flyscan_xray_centre(
|
|
96
106
|
grid_scan_with_edge_params: GridScanWithEdgeDetect,
|
|
97
107
|
grid_parameters: GridParamUpdate,
|
|
98
|
-
) ->
|
|
108
|
+
) -> HyperionThreeDGridScan:
|
|
99
109
|
params_json = grid_scan_with_edge_params.model_dump()
|
|
100
110
|
params_json.update(grid_parameters)
|
|
101
|
-
flyscan_xray_centre_parameters =
|
|
111
|
+
flyscan_xray_centre_parameters = HyperionThreeDGridScan(**params_json)
|
|
102
112
|
LOGGER.info(f"Parameters for FGS: {flyscan_xray_centre_parameters}")
|
|
103
113
|
return flyscan_xray_centre_parameters
|
|
104
114
|
|
|
@@ -150,7 +160,7 @@ def detect_grid_and_do_gridscan(
|
|
|
150
160
|
group=CONST.WAIT.GRID_READY_FOR_DC,
|
|
151
161
|
)
|
|
152
162
|
|
|
153
|
-
yield from
|
|
163
|
+
yield from flyscan_xray_centre_no_move(
|
|
154
164
|
FlyScanXRayCentreComposite(
|
|
155
165
|
aperture_scatterguard=composite.aperture_scatterguard,
|
|
156
166
|
attenuator=composite.attenuator,
|
|
@@ -193,19 +203,33 @@ def grid_detect_then_xray_centre(
|
|
|
193
203
|
|
|
194
204
|
oav_params = OAVParameters("xrayCentring", oav_config)
|
|
195
205
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
206
|
+
flyscan_event_handler = XRayCentreEventHandler()
|
|
207
|
+
|
|
208
|
+
@subs_decorator(flyscan_event_handler)
|
|
209
|
+
def plan_to_perform():
|
|
210
|
+
yield from ispyb_activation_wrapper(
|
|
211
|
+
detect_grid_and_do_gridscan(
|
|
212
|
+
composite,
|
|
213
|
+
parameters,
|
|
214
|
+
oav_params,
|
|
215
|
+
),
|
|
199
216
|
parameters,
|
|
200
|
-
|
|
201
|
-
),
|
|
202
|
-
parameters,
|
|
203
|
-
)
|
|
217
|
+
)
|
|
204
218
|
|
|
205
|
-
|
|
219
|
+
yield from start_preparing_data_collection_then_do_plan(
|
|
206
220
|
eiger,
|
|
207
221
|
composite.detector_motion,
|
|
208
222
|
parameters.detector_params.detector_distance,
|
|
209
|
-
plan_to_perform,
|
|
223
|
+
plan_to_perform(),
|
|
210
224
|
group=CONST.WAIT.GRID_READY_FOR_DC,
|
|
211
225
|
)
|
|
226
|
+
|
|
227
|
+
assert (
|
|
228
|
+
flyscan_event_handler.xray_centre_results
|
|
229
|
+
), "Flyscan result event not received or no crystal found and exception not raised"
|
|
230
|
+
|
|
231
|
+
yield from change_aperture_then_move_to_xtal(
|
|
232
|
+
flyscan_event_handler.xray_centre_results[0],
|
|
233
|
+
composite.smargon,
|
|
234
|
+
composite.aperture_scatterguard,
|
|
235
|
+
)
|
|
@@ -1,25 +1,43 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
|
|
5
|
+
import pydantic
|
|
3
6
|
from blueapi.core import BlueskyContext
|
|
7
|
+
from bluesky.preprocessors import run_decorator, set_run_key_decorator, subs_wrapper
|
|
8
|
+
from bluesky.utils import MsgGenerator
|
|
4
9
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
10
|
+
from dodal.devices.smargon import Smargon
|
|
5
11
|
|
|
12
|
+
import mx_bluesky.hyperion.experiment_plans.common.xrc_result as flyscan_result
|
|
13
|
+
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
14
|
+
XRayCentreEventHandler,
|
|
15
|
+
)
|
|
6
16
|
from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
|
|
7
17
|
RobotLoadThenCentreComposite,
|
|
8
|
-
|
|
18
|
+
robot_load_then_xray_centre,
|
|
9
19
|
)
|
|
10
20
|
from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
|
|
21
|
+
MultiRotationScan,
|
|
11
22
|
RotationScanComposite,
|
|
12
23
|
multi_rotation_scan,
|
|
13
24
|
)
|
|
25
|
+
from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import (
|
|
26
|
+
sample_handling_callback_decorator,
|
|
27
|
+
)
|
|
28
|
+
from mx_bluesky.hyperion.log import LOGGER
|
|
29
|
+
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
14
30
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
15
31
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
16
32
|
|
|
17
33
|
|
|
18
|
-
@dataclasses.dataclass
|
|
34
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
19
35
|
class LoadCentreCollectComposite(RobotLoadThenCentreComposite, RotationScanComposite):
|
|
20
36
|
"""Composite that provides access to the required devices."""
|
|
21
37
|
|
|
22
|
-
|
|
38
|
+
@property
|
|
39
|
+
def sample_motors(self) -> Smargon:
|
|
40
|
+
return self.smargon
|
|
23
41
|
|
|
24
42
|
|
|
25
43
|
def create_devices(context: BlueskyContext) -> LoadCentreCollectComposite:
|
|
@@ -27,11 +45,11 @@ def create_devices(context: BlueskyContext) -> LoadCentreCollectComposite:
|
|
|
27
45
|
return device_composite_from_context(context, LoadCentreCollectComposite)
|
|
28
46
|
|
|
29
47
|
|
|
30
|
-
def
|
|
48
|
+
def load_centre_collect_full(
|
|
31
49
|
composite: LoadCentreCollectComposite,
|
|
32
|
-
|
|
50
|
+
parameters: LoadCentreCollect,
|
|
33
51
|
oav_params: OAVParameters | None = None,
|
|
34
|
-
):
|
|
52
|
+
) -> MsgGenerator:
|
|
35
53
|
"""Attempt a complete data collection experiment, consisting of the following:
|
|
36
54
|
* Load the sample if necessary
|
|
37
55
|
* Move to the specified goniometer start angles
|
|
@@ -41,6 +59,54 @@ def load_centre_collect_full_plan(
|
|
|
41
59
|
"""
|
|
42
60
|
if not oav_params:
|
|
43
61
|
oav_params = OAVParameters(context="xrayCentring")
|
|
44
|
-
yield from robot_load_then_centre(composite, params.robot_load_then_centre)
|
|
45
62
|
|
|
46
|
-
|
|
63
|
+
@set_run_key_decorator(CONST.PLAN.LOAD_CENTRE_COLLECT)
|
|
64
|
+
@run_decorator(
|
|
65
|
+
md={
|
|
66
|
+
"metadata": {"sample_id": parameters.sample_id},
|
|
67
|
+
"activate_callbacks": ["SampleHandlingCallback"],
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
@sample_handling_callback_decorator()
|
|
71
|
+
def plan_with_callback_subs():
|
|
72
|
+
flyscan_event_handler = XRayCentreEventHandler()
|
|
73
|
+
yield from subs_wrapper(
|
|
74
|
+
robot_load_then_xray_centre(composite, parameters.robot_load_then_centre),
|
|
75
|
+
flyscan_event_handler,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
assert flyscan_event_handler.xray_centre_results, "Flyscan result event not received or no crystal found and exception not raised"
|
|
79
|
+
|
|
80
|
+
selection_func = flyscan_result.resolve_selection_fn(
|
|
81
|
+
parameters.selection_params
|
|
82
|
+
)
|
|
83
|
+
hits: Sequence[flyscan_result.XRayCentreResult] = selection_func(
|
|
84
|
+
flyscan_event_handler.xray_centre_results
|
|
85
|
+
)
|
|
86
|
+
LOGGER.info(
|
|
87
|
+
f"Selected hits {hits} using {selection_func}, args={parameters.selection_params}"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
multi_rotation = parameters.multi_rotation_scan
|
|
91
|
+
rotation_template = multi_rotation.rotation_scans.copy()
|
|
92
|
+
|
|
93
|
+
multi_rotation.rotation_scans.clear()
|
|
94
|
+
|
|
95
|
+
for hit in hits:
|
|
96
|
+
for rot in rotation_template:
|
|
97
|
+
combination = rot.model_copy()
|
|
98
|
+
(
|
|
99
|
+
combination.x_start_um,
|
|
100
|
+
combination.y_start_um,
|
|
101
|
+
combination.z_start_um,
|
|
102
|
+
) = (axis * 1000 for axis in hit.centre_of_mass_mm)
|
|
103
|
+
multi_rotation.rotation_scans.append(combination)
|
|
104
|
+
multi_rotation = MultiRotationScan.model_validate(multi_rotation)
|
|
105
|
+
|
|
106
|
+
assert (
|
|
107
|
+
multi_rotation.demand_energy_ev
|
|
108
|
+
== parameters.robot_load_then_centre.demand_energy_ev
|
|
109
|
+
), "Setting a different energy for gridscan and rotation is not supported"
|
|
110
|
+
yield from multi_rotation_scan(composite, multi_rotation, oav_params)
|
|
111
|
+
|
|
112
|
+
yield from plan_with_callback_subs()
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import dataclasses
|
|
4
3
|
import math
|
|
5
4
|
from typing import TYPE_CHECKING
|
|
6
5
|
|
|
7
6
|
import bluesky.plan_stubs as bps
|
|
8
7
|
import numpy as np
|
|
8
|
+
import pydantic
|
|
9
9
|
from blueapi.core import BlueskyContext
|
|
10
10
|
from dodal.devices.backlight import Backlight
|
|
11
11
|
from dodal.devices.oav.oav_detector import OAV
|
|
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
26
26
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
@dataclasses.dataclass
|
|
29
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
30
30
|
class OavGridDetectionComposite:
|
|
31
31
|
"""All devices which are directly or indirectly required by this plan"""
|
|
32
32
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import Protocol
|
|
3
3
|
|
|
4
|
-
from blueapi.core import MsgGenerator
|
|
5
4
|
from bluesky import plan_stubs as bps
|
|
5
|
+
from bluesky.utils import MsgGenerator
|
|
6
6
|
from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
|
|
7
7
|
from dodal.devices.backlight import Backlight, BacklightPosition
|
|
8
8
|
from dodal.devices.oav.oav_detector import OAV
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import dataclasses
|
|
2
1
|
from enum import Enum
|
|
3
2
|
|
|
4
3
|
import bluesky.plan_stubs as bps
|
|
5
4
|
import bluesky.preprocessors as bpp
|
|
6
5
|
import numpy as np
|
|
6
|
+
import pydantic
|
|
7
7
|
from blueapi.core import BlueskyContext
|
|
8
8
|
from dodal.devices.attenuator import Attenuator
|
|
9
9
|
from dodal.devices.xspress3.xspress3 import Xspress3
|
|
@@ -22,7 +22,7 @@ class Direction(Enum):
|
|
|
22
22
|
NEGATIVE = "negative"
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@dataclasses.dataclass
|
|
25
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
26
26
|
class OptimizeAttenuationComposite:
|
|
27
27
|
"""All devices which are directly or indirectly required by this plan"""
|
|
28
28
|
|
|
@@ -2,15 +2,27 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import bluesky.preprocessors as bpp
|
|
6
|
+
from blueapi.core import BlueskyContext
|
|
7
|
+
from bluesky.utils import MsgGenerator
|
|
6
8
|
from dodal.devices.eiger import EigerDetector
|
|
7
9
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
8
10
|
|
|
9
11
|
from mx_bluesky.common.parameters.constants import OavConstants
|
|
12
|
+
from mx_bluesky.common.parameters.gridscan import (
|
|
13
|
+
GridScanWithEdgeDetect,
|
|
14
|
+
PinTipCentreThenXrayCentre,
|
|
15
|
+
)
|
|
10
16
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_phi_chi_omega
|
|
11
17
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
12
18
|
start_preparing_data_collection_then_do_plan,
|
|
13
19
|
)
|
|
20
|
+
from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import (
|
|
21
|
+
change_aperture_then_move_to_xtal,
|
|
22
|
+
)
|
|
23
|
+
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
24
|
+
XRayCentreEventHandler,
|
|
25
|
+
)
|
|
14
26
|
from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import (
|
|
15
27
|
GridDetectThenXRayCentreComposite,
|
|
16
28
|
detect_grid_and_do_gridscan,
|
|
@@ -27,10 +39,6 @@ from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.ispyb_callba
|
|
|
27
39
|
)
|
|
28
40
|
from mx_bluesky.hyperion.log import LOGGER
|
|
29
41
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
30
|
-
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
31
|
-
GridScanWithEdgeDetect,
|
|
32
|
-
PinTipCentreThenXrayCentre,
|
|
33
|
-
)
|
|
34
42
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
35
43
|
|
|
36
44
|
|
|
@@ -53,13 +61,12 @@ def create_parameters_for_grid_detection(
|
|
|
53
61
|
return grid_detect_and_xray_centre
|
|
54
62
|
|
|
55
63
|
|
|
56
|
-
def
|
|
64
|
+
def pin_centre_then_flyscan_plan(
|
|
57
65
|
composite: GridDetectThenXRayCentreComposite,
|
|
58
66
|
parameters: PinTipCentreThenXrayCentre,
|
|
59
67
|
oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
|
|
60
68
|
):
|
|
61
|
-
"""Plan that
|
|
62
|
-
centre the sample"""
|
|
69
|
+
"""Plan that performs a pin tip centre followed by a flyscan to determine the centres of interest"""
|
|
63
70
|
|
|
64
71
|
pin_tip_centring_composite = PinTipCentringComposite(
|
|
65
72
|
oav=composite.oav,
|
|
@@ -68,7 +75,7 @@ def pin_centre_then_xray_centre_plan(
|
|
|
68
75
|
pin_tip_detection=composite.pin_tip_detection,
|
|
69
76
|
)
|
|
70
77
|
|
|
71
|
-
def
|
|
78
|
+
def _pin_centre_then_flyscan_plan():
|
|
72
79
|
yield from setup_beamline_for_OAV(
|
|
73
80
|
composite.smargon, composite.backlight, composite.aperture_scatterguard
|
|
74
81
|
)
|
|
@@ -96,7 +103,7 @@ def pin_centre_then_xray_centre_plan(
|
|
|
96
103
|
oav_params,
|
|
97
104
|
)
|
|
98
105
|
|
|
99
|
-
yield from ispyb_activation_wrapper(
|
|
106
|
+
yield from ispyb_activation_wrapper(_pin_centre_then_flyscan_plan(), parameters)
|
|
100
107
|
|
|
101
108
|
|
|
102
109
|
def pin_tip_centre_then_xray_centre(
|
|
@@ -105,15 +112,27 @@ def pin_tip_centre_then_xray_centre(
|
|
|
105
112
|
oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
|
|
106
113
|
) -> MsgGenerator:
|
|
107
114
|
"""Starts preparing for collection then performs the pin tip centre and xray centre"""
|
|
108
|
-
|
|
109
115
|
eiger: EigerDetector = composite.eiger
|
|
110
116
|
|
|
111
117
|
eiger.set_detector_parameters(parameters.detector_params)
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
flyscan_event_handler = XRayCentreEventHandler()
|
|
120
|
+
|
|
121
|
+
@bpp.subs_decorator(flyscan_event_handler)
|
|
122
|
+
def pin_centre_flyscan_then_fetch_results() -> MsgGenerator:
|
|
123
|
+
yield from start_preparing_data_collection_then_do_plan(
|
|
124
|
+
eiger,
|
|
125
|
+
composite.detector_motion,
|
|
126
|
+
parameters.detector_params.detector_distance,
|
|
127
|
+
pin_centre_then_flyscan_plan(composite, parameters, oav_config_file),
|
|
128
|
+
group=CONST.WAIT.GRID_READY_FOR_DC,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
yield from pin_centre_flyscan_then_fetch_results()
|
|
132
|
+
flyscan_results = flyscan_event_handler.xray_centre_results
|
|
133
|
+
assert (
|
|
134
|
+
flyscan_results
|
|
135
|
+
), "Flyscan result event not received or no crystal found and exception not raised"
|
|
136
|
+
yield from change_aperture_then_move_to_xtal(
|
|
137
|
+
flyscan_results[0], composite.smargon, composite.aperture_scatterguard
|
|
119
138
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import dataclasses
|
|
2
1
|
from collections.abc import Generator
|
|
3
2
|
|
|
4
3
|
import bluesky.plan_stubs as bps
|
|
4
|
+
import pydantic
|
|
5
5
|
from blueapi.core import BlueskyContext
|
|
6
6
|
from bluesky.utils import Msg
|
|
7
7
|
from dodal.devices.backlight import Backlight
|
|
@@ -19,7 +19,7 @@ from mx_bluesky.hyperion.device_setup_plans.setup_oav import pre_centring_setup_
|
|
|
19
19
|
from mx_bluesky.hyperion.device_setup_plans.smargon import (
|
|
20
20
|
move_smargon_warn_on_out_of_range,
|
|
21
21
|
)
|
|
22
|
-
from mx_bluesky.hyperion.exceptions import
|
|
22
|
+
from mx_bluesky.hyperion.exceptions import SampleException
|
|
23
23
|
from mx_bluesky.hyperion.log import LOGGER
|
|
24
24
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
25
25
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
@@ -27,7 +27,7 @@ from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
|
27
27
|
DEFAULT_STEP_SIZE = 0.5
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
@dataclasses.dataclass
|
|
30
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
31
31
|
class PinTipCentringComposite:
|
|
32
32
|
"""All devices which are directly or indirectly required by this plan"""
|
|
33
33
|
|
|
@@ -68,7 +68,7 @@ def move_pin_into_view(
|
|
|
68
68
|
max_steps (int, optional): The number of steps to search with. Defaults to 2.
|
|
69
69
|
|
|
70
70
|
Raises:
|
|
71
|
-
|
|
71
|
+
SampleException: Error if the pin tip is never found
|
|
72
72
|
|
|
73
73
|
Returns:
|
|
74
74
|
Tuple[int, int]: The location of the pin tip in pixels
|
|
@@ -105,7 +105,7 @@ def move_pin_into_view(
|
|
|
105
105
|
tip_xy_px = yield from trigger_and_return_pin_tip(pin_tip_device)
|
|
106
106
|
|
|
107
107
|
if not pin_tip_valid(tip_xy_px):
|
|
108
|
-
raise
|
|
108
|
+
raise SampleException(
|
|
109
109
|
"Pin tip centring failed - pin too long/short/bent and out of range"
|
|
110
110
|
)
|
|
111
111
|
else:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import dataclasses
|
|
4
3
|
from collections.abc import Generator
|
|
5
4
|
from datetime import datetime
|
|
6
5
|
from pathlib import Path
|
|
@@ -8,6 +7,7 @@ from typing import cast
|
|
|
8
7
|
|
|
9
8
|
import bluesky.plan_stubs as bps
|
|
10
9
|
import bluesky.preprocessors as bpp
|
|
10
|
+
import pydantic
|
|
11
11
|
from blueapi.core import BlueskyContext
|
|
12
12
|
from bluesky.utils import Msg
|
|
13
13
|
from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
|
|
@@ -22,18 +22,18 @@ from dodal.devices.thawer import Thawer
|
|
|
22
22
|
from dodal.devices.undulator_dcm import UndulatorDCM
|
|
23
23
|
from dodal.devices.webcam import Webcam
|
|
24
24
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
25
|
-
from dodal.
|
|
25
|
+
from dodal.plan_stubs.motor_utils import MoveTooLarge, home_and_reset_wrapper
|
|
26
26
|
|
|
27
|
+
from mx_bluesky.common.parameters.robot_load import RobotLoadAndEnergyChange
|
|
27
28
|
from mx_bluesky.hyperion.experiment_plans.set_energy_plan import (
|
|
28
29
|
SetEnergyComposite,
|
|
29
30
|
set_energy_plan,
|
|
30
31
|
)
|
|
31
32
|
from mx_bluesky.hyperion.log import LOGGER
|
|
32
33
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
33
|
-
from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
@dataclasses.dataclass
|
|
36
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
37
37
|
class RobotLoadAndEnergyChangeComposite:
|
|
38
38
|
# SetEnergyComposite fields
|
|
39
39
|
vfm: FocusingMirrorWithStripes
|
|
@@ -128,11 +128,7 @@ def do_robot_load(
|
|
|
128
128
|
group="robot_load",
|
|
129
129
|
)
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
yield from set_energy_plan(
|
|
133
|
-
demand_energy_ev / 1000,
|
|
134
|
-
cast(SetEnergyComposite, composite),
|
|
135
|
-
)
|
|
131
|
+
yield from set_energy_plan(demand_energy_ev, cast(SetEnergyComposite, composite))
|
|
136
132
|
|
|
137
133
|
yield from bps.wait("robot_load")
|
|
138
134
|
|
|
@@ -218,24 +214,28 @@ def robot_load_and_change_energy_plan(
|
|
|
218
214
|
yield from prepare_for_robot_load(
|
|
219
215
|
composite.aperture_scatterguard, composite.smargon
|
|
220
216
|
)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
|
|
235
|
-
|
|
217
|
+
|
|
218
|
+
yield from bpp.set_run_key_wrapper(
|
|
219
|
+
bpp.run_wrapper(
|
|
220
|
+
robot_load_and_snapshots(
|
|
221
|
+
composite,
|
|
222
|
+
sample_location,
|
|
223
|
+
params.snapshot_directory,
|
|
224
|
+
params.thawing_time,
|
|
225
|
+
params.demand_energy_ev,
|
|
226
|
+
),
|
|
227
|
+
md={
|
|
228
|
+
"subplan_name": CONST.PLAN.ROBOT_LOAD,
|
|
229
|
+
"metadata": {
|
|
230
|
+
"visit": params.visit,
|
|
231
|
+
"sample_id": params.sample_id,
|
|
232
|
+
"sample_puck": sample_location.puck,
|
|
233
|
+
"sample_pin": sample_location.pin,
|
|
234
|
+
},
|
|
235
|
+
"activate_callbacks": [
|
|
236
|
+
"RobotLoadISPyBCallback",
|
|
237
|
+
],
|
|
236
238
|
},
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
],
|
|
240
|
-
},
|
|
239
|
+
),
|
|
240
|
+
CONST.PLAN.ROBOT_LOAD_AND_SNAPSHOTS,
|
|
241
241
|
)
|