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.
- mx_bluesky/_version.py +2 -2
- mx_bluesky/beamlines/aithre_lasershaping/__init__.py +8 -0
- mx_bluesky/beamlines/aithre_lasershaping/beamline_safe.py +36 -0
- mx_bluesky/beamlines/aithre_lasershaping/goniometer_controls.py +43 -0
- mx_bluesky/beamlines/i24/serial/__init__.py +4 -2
- mx_bluesky/beamlines/i24/serial/blueapi_config.yaml +6 -1
- mx_bluesky/beamlines/i24/serial/dcid.py +5 -5
- mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DetStage.edl +2 -2
- mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +9 -9
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +18 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DetStage.edl +2 -2
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +14 -14
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +2 -2
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +55 -4
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +9 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +0 -8
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +77 -8
- mx_bluesky/common/device_setup_plans/manipulate_sample.py +9 -14
- mx_bluesky/common/device_setup_plans/utils.py +49 -0
- mx_bluesky/common/{plans → experiment_plans}/common_flyscan_xray_centre_plan.py +11 -19
- 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
- mx_bluesky/common/{plans → experiment_plans}/inner_plans/do_fgs.py +1 -1
- mx_bluesky/common/experiment_plans/oav_grid_detection_plan.py +5 -13
- mx_bluesky/{hyperion → common}/experiment_plans/oav_snapshot_plan.py +8 -2
- mx_bluesky/common/external_interaction/nexus/nexus_utils.py +2 -2
- mx_bluesky/common/parameters/components.py +1 -1
- mx_bluesky/common/parameters/device_composites.py +65 -0
- mx_bluesky/common/utils/__init__.py +0 -0
- mx_bluesky/common/utils/log.py +12 -11
- mx_bluesky/hyperion/__main__.py +6 -11
- mx_bluesky/hyperion/baton_handler.py +8 -3
- mx_bluesky/hyperion/device_setup_plans/smargon.py +2 -7
- mx_bluesky/hyperion/device_setup_plans/utils.py +0 -47
- mx_bluesky/hyperion/experiment_plans/__init__.py +5 -5
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +6 -7
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +40 -41
- mx_bluesky/hyperion/experiment_plans/hyperion_grid_detect_then_xray_centre_plan.py +60 -0
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +40 -10
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +26 -15
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +2 -11
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +8 -6
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -36
- mx_bluesky/hyperion/external_interaction/agamemnon.py +68 -62
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +3 -3
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +6 -3
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +2 -2
- mx_bluesky/hyperion/external_interaction/config_server.py +4 -1
- mx_bluesky/hyperion/parameters/cli.py +3 -10
- mx_bluesky/hyperion/parameters/constants.py +1 -1
- mx_bluesky/hyperion/parameters/device_composites.py +5 -27
- mx_bluesky/hyperion/parameters/load_centre_collect.py +4 -4
- mx_bluesky/hyperion/parameters/rotation.py +9 -8
- mx_bluesky/hyperion/utils/context.py +5 -2
- mx_bluesky/hyperion/utils/validation.py +11 -18
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/METADATA +5 -5
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/RECORD +65 -62
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/WHEEL +1 -1
- mx_bluesky/common/device_setup_plans/check_beamstop.py +0 -27
- mx_bluesky/common/external_interaction/test_config_server.py +0 -38
- /mx_bluesky/common/{plans → experiment_plans}/__init__.py +0 -0
- /mx_bluesky/common/{plans → experiment_plans}/inner_plans/__init__ .py +0 -0
- /mx_bluesky/common/{plans → experiment_plans}/read_hardware.py +0 -0
- /mx_bluesky/common/{plans → experiment_plans}/write_sample_status.py +0 -0
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.4.8.dist-info → mx_bluesky-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,59 +1,12 @@
|
|
|
1
|
-
from collections.abc import Generator
|
|
2
|
-
|
|
3
1
|
from bluesky import plan_stubs as bps
|
|
4
|
-
from bluesky import preprocessors as bpp
|
|
5
|
-
from bluesky.utils import Msg
|
|
6
2
|
from dodal.devices.detector import (
|
|
7
3
|
DetectorParams,
|
|
8
4
|
)
|
|
9
|
-
from dodal.devices.detector.detector_motion import DetectorMotion, ShutterState
|
|
10
|
-
from dodal.devices.eiger import EigerDetector
|
|
11
|
-
from dodal.devices.i03 import Beamstop
|
|
12
5
|
from dodal.devices.i03.dcm import DCM
|
|
13
6
|
|
|
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
|
-
set_detector_z_position,
|
|
17
|
-
set_shutter,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
7
|
|
|
21
8
|
def fill_in_energy_if_not_supplied(dcm: DCM, detector_params: DetectorParams):
|
|
22
9
|
if not detector_params.expected_energy_ev:
|
|
23
10
|
actual_energy_ev = 1000 * (yield from bps.rd(dcm.energy_in_kev))
|
|
24
11
|
detector_params.expected_energy_ev = actual_energy_ev
|
|
25
12
|
return detector_params
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def start_preparing_data_collection_then_do_plan(
|
|
29
|
-
beamstop: Beamstop,
|
|
30
|
-
eiger: EigerDetector,
|
|
31
|
-
detector_motion: DetectorMotion,
|
|
32
|
-
detector_distance_mm: float | None,
|
|
33
|
-
plan_to_run: Generator[Msg, None, None],
|
|
34
|
-
group="ready_for_data_collection",
|
|
35
|
-
) -> Generator[Msg, None, None]:
|
|
36
|
-
"""Starts preparing for the next data collection and then runs the
|
|
37
|
-
given plan.
|
|
38
|
-
|
|
39
|
-
Preparation consists of:
|
|
40
|
-
* Arming the Eiger
|
|
41
|
-
* Moving the detector to the specified position
|
|
42
|
-
* Opening the detect shutter
|
|
43
|
-
If the plan fails it will disarm the eiger.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
def wrapped_plan():
|
|
47
|
-
yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
48
|
-
if detector_distance_mm:
|
|
49
|
-
yield from set_detector_z_position(
|
|
50
|
-
detector_motion, detector_distance_mm, group
|
|
51
|
-
)
|
|
52
|
-
yield from set_shutter(detector_motion, ShutterState.OPEN, group)
|
|
53
|
-
yield from plan_to_run
|
|
54
|
-
|
|
55
|
-
yield from check_beamstop(beamstop)
|
|
56
|
-
yield from bpp.contingency_wrapper(
|
|
57
|
-
wrapped_plan(),
|
|
58
|
-
except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
59
|
-
)
|
|
@@ -3,8 +3,8 @@
|
|
|
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.
|
|
7
|
-
|
|
6
|
+
from mx_bluesky.hyperion.experiment_plans.hyperion_grid_detect_then_xray_centre_plan import (
|
|
7
|
+
hyperion_grid_detect_then_xray_centre,
|
|
8
8
|
)
|
|
9
9
|
from mx_bluesky.hyperion.experiment_plans.load_centre_collect_full_plan import (
|
|
10
10
|
load_centre_collect_full,
|
|
@@ -13,12 +13,12 @@ from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan impor
|
|
|
13
13
|
pin_tip_centre_then_xray_centre,
|
|
14
14
|
)
|
|
15
15
|
from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
|
|
16
|
-
|
|
16
|
+
rotation_scan,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
__all__ = [
|
|
20
|
-
"
|
|
20
|
+
"hyperion_grid_detect_then_xray_centre",
|
|
21
21
|
"pin_tip_centre_then_xray_centre",
|
|
22
|
-
"
|
|
22
|
+
"rotation_scan",
|
|
23
23
|
"load_centre_collect_full",
|
|
24
24
|
]
|
|
@@ -5,7 +5,7 @@ from typing import TypedDict
|
|
|
5
5
|
|
|
6
6
|
import mx_bluesky.hyperion.experiment_plans.rotation_scan_plan as rotation_scan_plan
|
|
7
7
|
from mx_bluesky.hyperion.experiment_plans import (
|
|
8
|
-
|
|
8
|
+
hyperion_grid_detect_then_xray_centre_plan,
|
|
9
9
|
load_centre_collect_full_plan,
|
|
10
10
|
pin_centre_then_xray_centre_plan,
|
|
11
11
|
)
|
|
@@ -15,7 +15,7 @@ from mx_bluesky.hyperion.parameters.gridscan import (
|
|
|
15
15
|
PinTipCentreThenXrayCentre,
|
|
16
16
|
)
|
|
17
17
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
18
|
-
from mx_bluesky.hyperion.parameters.rotation import
|
|
18
|
+
from mx_bluesky.hyperion.parameters.rotation import RotationScan
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def not_implemented():
|
|
@@ -32,24 +32,23 @@ class ExperimentRegistryEntry(TypedDict):
|
|
|
32
32
|
HyperionSpecifiedThreeDGridScan
|
|
33
33
|
| GridScanWithEdgeDetect
|
|
34
34
|
| RotationScan
|
|
35
|
-
| MultiRotationScan
|
|
36
35
|
| PinTipCentreThenXrayCentre
|
|
37
36
|
| LoadCentreCollect
|
|
38
37
|
]
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
PLAN_REGISTRY: dict[str, ExperimentRegistryEntry] = {
|
|
42
|
-
"
|
|
43
|
-
"setup":
|
|
41
|
+
"hyperion_grid_detect_then_xray_centre": {
|
|
42
|
+
"setup": hyperion_grid_detect_then_xray_centre_plan.create_devices,
|
|
44
43
|
"param_type": GridScanWithEdgeDetect,
|
|
45
44
|
},
|
|
46
45
|
"pin_tip_centre_then_xray_centre": {
|
|
47
46
|
"setup": pin_centre_then_xray_centre_plan.create_devices,
|
|
48
47
|
"param_type": PinTipCentreThenXrayCentre,
|
|
49
48
|
},
|
|
50
|
-
"
|
|
49
|
+
"rotation_scan": {
|
|
51
50
|
"setup": rotation_scan_plan.create_devices,
|
|
52
|
-
"param_type":
|
|
51
|
+
"param_type": RotationScan,
|
|
53
52
|
},
|
|
54
53
|
"load_centre_collect_full": {
|
|
55
54
|
"setup": load_centre_collect_full_plan.create_devices,
|
|
@@ -9,7 +9,7 @@ from dodal.devices.fast_grid_scan import (
|
|
|
9
9
|
set_fast_grid_scan_params,
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
-
from mx_bluesky.common.
|
|
12
|
+
from mx_bluesky.common.experiment_plans.common_flyscan_xray_centre_plan import (
|
|
13
13
|
construct_beamline_specific_FGS_features,
|
|
14
14
|
)
|
|
15
15
|
from mx_bluesky.common.utils.log import LOGGER
|
|
@@ -34,51 +34,50 @@ class SmargonSpeedException(Exception):
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def construct_hyperion_specific_features(
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
xrc_composite: HyperionFlyScanXRayCentreComposite,
|
|
38
|
+
xrc_parameters: HyperionSpecifiedThreeDGridScan,
|
|
39
39
|
):
|
|
40
40
|
"""
|
|
41
41
|
Get all the information needed to do the Hyperion-specific parts of the XRC flyscan.
|
|
42
42
|
"""
|
|
43
|
-
|
|
44
43
|
signals_to_read_pre_flyscan = [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
xrc_composite.undulator.current_gap,
|
|
45
|
+
xrc_composite.synchrotron.synchrotron_mode,
|
|
46
|
+
xrc_composite.s4_slit_gaps.xgap,
|
|
47
|
+
xrc_composite.s4_slit_gaps.ygap,
|
|
48
|
+
xrc_composite.smargon.x,
|
|
49
|
+
xrc_composite.smargon.y,
|
|
50
|
+
xrc_composite.smargon.z,
|
|
51
|
+
xrc_composite.dcm.energy_in_kev,
|
|
53
52
|
]
|
|
54
53
|
|
|
55
54
|
signals_to_read_during_collection = [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
xrc_composite.aperture_scatterguard,
|
|
56
|
+
xrc_composite.attenuator.actual_transmission,
|
|
57
|
+
xrc_composite.flux.flux_reading,
|
|
58
|
+
xrc_composite.dcm.energy_in_kev,
|
|
59
|
+
xrc_composite.eiger.bit_depth,
|
|
61
60
|
]
|
|
62
61
|
|
|
63
|
-
if
|
|
62
|
+
if xrc_parameters.features.use_panda_for_gridscan:
|
|
64
63
|
setup_trigger_plan = _panda_triggering_setup
|
|
65
64
|
tidy_plan = _panda_tidy
|
|
66
65
|
set_flyscan_params_plan = partial(
|
|
67
66
|
set_fast_grid_scan_params,
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
xrc_composite.panda_fast_grid_scan,
|
|
68
|
+
xrc_parameters.panda_FGS_params,
|
|
70
69
|
)
|
|
71
|
-
fgs_motors =
|
|
70
|
+
fgs_motors = xrc_composite.panda_fast_grid_scan
|
|
72
71
|
|
|
73
72
|
else:
|
|
74
73
|
setup_trigger_plan = _zebra_triggering_setup
|
|
75
74
|
tidy_plan = partial(_generic_tidy, group="flyscan_zebra_tidy", wait=True)
|
|
76
75
|
set_flyscan_params_plan = partial(
|
|
77
76
|
set_fast_grid_scan_params,
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
xrc_composite.zebra_fast_grid_scan,
|
|
78
|
+
xrc_parameters.FGS_params,
|
|
80
79
|
)
|
|
81
|
-
fgs_motors =
|
|
80
|
+
fgs_motors = xrc_composite.zebra_fast_grid_scan
|
|
82
81
|
return construct_beamline_specific_FGS_features(
|
|
83
82
|
setup_trigger_plan,
|
|
84
83
|
tidy_plan,
|
|
@@ -91,47 +90,47 @@ def construct_hyperion_specific_features(
|
|
|
91
90
|
|
|
92
91
|
|
|
93
92
|
def _generic_tidy(
|
|
94
|
-
|
|
93
|
+
xrc_composite: HyperionFlyScanXRayCentreComposite, group, wait=True
|
|
95
94
|
) -> MsgGenerator:
|
|
96
95
|
LOGGER.info("Tidying up Zebra")
|
|
97
96
|
yield from tidy_up_zebra_after_gridscan(
|
|
98
|
-
|
|
97
|
+
xrc_composite.zebra, xrc_composite.sample_shutter, group=group, wait=wait
|
|
99
98
|
)
|
|
100
99
|
LOGGER.info("Tidying up Zocalo")
|
|
101
100
|
# make sure we don't consume any other results
|
|
102
|
-
yield from bps.unstage(
|
|
101
|
+
yield from bps.unstage(xrc_composite.zocalo, group=group, wait=wait)
|
|
103
102
|
|
|
104
103
|
# Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
|
|
105
104
|
LOGGER.info("Turning off Eiger dev/shm streaming")
|
|
106
|
-
yield from bps.abs_set(
|
|
105
|
+
yield from bps.abs_set(xrc_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
107
106
|
|
|
108
107
|
|
|
109
|
-
def _panda_tidy(
|
|
108
|
+
def _panda_tidy(xrc_composite: HyperionFlyScanXRayCentreComposite):
|
|
110
109
|
group = "panda_flyscan_tidy"
|
|
111
110
|
LOGGER.info("Disabling panda blocks")
|
|
112
|
-
yield from disarm_panda_for_gridscan(
|
|
113
|
-
yield from _generic_tidy(
|
|
111
|
+
yield from disarm_panda_for_gridscan(xrc_composite.panda, group)
|
|
112
|
+
yield from _generic_tidy(xrc_composite, group, False)
|
|
114
113
|
yield from bps.wait(group, timeout=10)
|
|
115
|
-
yield from bps.unstage(
|
|
114
|
+
yield from bps.unstage(xrc_composite.panda)
|
|
116
115
|
|
|
117
116
|
|
|
118
117
|
def _zebra_triggering_setup(
|
|
119
|
-
|
|
118
|
+
xrc_composite: HyperionFlyScanXRayCentreComposite,
|
|
120
119
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
121
120
|
) -> MsgGenerator:
|
|
122
121
|
yield from setup_zebra_for_gridscan(
|
|
123
|
-
|
|
122
|
+
xrc_composite.zebra, xrc_composite.sample_shutter, wait=True
|
|
124
123
|
)
|
|
125
124
|
|
|
126
125
|
|
|
127
126
|
def _panda_triggering_setup(
|
|
128
|
-
|
|
127
|
+
xrc_composite: HyperionFlyScanXRayCentreComposite,
|
|
129
128
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
130
129
|
) -> MsgGenerator:
|
|
131
130
|
LOGGER.info("Setting up Panda for flyscan")
|
|
132
131
|
|
|
133
132
|
run_up_distance_mm = yield from bps.rd(
|
|
134
|
-
|
|
133
|
+
xrc_composite.panda_fast_grid_scan.run_up_distance_mm
|
|
135
134
|
)
|
|
136
135
|
|
|
137
136
|
# Set the time between x steps pv
|
|
@@ -140,7 +139,7 @@ def _panda_triggering_setup(
|
|
|
140
139
|
time_between_x_steps_ms = (DEADTIME_S + parameters.exposure_time_s) * 1e3
|
|
141
140
|
|
|
142
141
|
smargon_speed_limit_mm_per_s = yield from bps.rd(
|
|
143
|
-
|
|
142
|
+
xrc_composite.smargon.x.max_velocity
|
|
144
143
|
)
|
|
145
144
|
|
|
146
145
|
sample_velocity_mm_per_s = (
|
|
@@ -161,7 +160,7 @@ def _panda_triggering_setup(
|
|
|
161
160
|
)
|
|
162
161
|
|
|
163
162
|
yield from bps.mv(
|
|
164
|
-
|
|
163
|
+
xrc_composite.panda_fast_grid_scan.time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
165
164
|
time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
166
165
|
)
|
|
167
166
|
|
|
@@ -169,9 +168,9 @@ def _panda_triggering_setup(
|
|
|
169
168
|
yield from set_panda_directory(directory_provider_root)
|
|
170
169
|
|
|
171
170
|
yield from setup_panda_for_flyscan(
|
|
172
|
-
|
|
171
|
+
xrc_composite.panda,
|
|
173
172
|
parameters.panda_FGS_params,
|
|
174
|
-
|
|
173
|
+
xrc_composite.smargon,
|
|
175
174
|
parameters.exposure_time_s,
|
|
176
175
|
time_between_x_steps_ms,
|
|
177
176
|
sample_velocity_mm_per_s,
|
|
@@ -179,5 +178,5 @@ def _panda_triggering_setup(
|
|
|
179
178
|
|
|
180
179
|
LOGGER.info("Setting up Zebra for panda flyscan")
|
|
181
180
|
yield from setup_zebra_for_panda_flyscan(
|
|
182
|
-
|
|
181
|
+
xrc_composite.zebra, xrc_composite.sample_shutter, wait=True
|
|
183
182
|
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from blueapi.core import BlueskyContext
|
|
4
|
+
from bluesky.utils import MsgGenerator
|
|
5
|
+
from dodal.plans.preprocessors.verify_undulator_gap import (
|
|
6
|
+
verify_undulator_gap_before_run_decorator,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from mx_bluesky.common.experiment_plans.common_grid_detect_then_xray_centre_plan import (
|
|
10
|
+
grid_detect_then_xray_centre,
|
|
11
|
+
)
|
|
12
|
+
from mx_bluesky.common.parameters.constants import OavConstants, PlanNameConstants
|
|
13
|
+
from mx_bluesky.common.preprocessors.preprocessors import (
|
|
14
|
+
transmission_and_xbpm_feedback_for_collection_decorator,
|
|
15
|
+
)
|
|
16
|
+
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
17
|
+
from mx_bluesky.hyperion.experiment_plans.hyperion_flyscan_xray_centre_plan import (
|
|
18
|
+
construct_hyperion_specific_features,
|
|
19
|
+
)
|
|
20
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
21
|
+
HyperionGridDetectThenXRayCentreComposite,
|
|
22
|
+
)
|
|
23
|
+
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
24
|
+
GridScanWithEdgeDetect,
|
|
25
|
+
HyperionSpecifiedThreeDGridScan,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def create_devices(
|
|
30
|
+
context: BlueskyContext,
|
|
31
|
+
) -> HyperionGridDetectThenXRayCentreComposite:
|
|
32
|
+
return device_composite_from_context(
|
|
33
|
+
context, HyperionGridDetectThenXRayCentreComposite
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def hyperion_grid_detect_then_xray_centre(
|
|
38
|
+
composite: HyperionGridDetectThenXRayCentreComposite,
|
|
39
|
+
parameters: GridScanWithEdgeDetect,
|
|
40
|
+
oav_config: str = OavConstants.OAV_CONFIG_JSON,
|
|
41
|
+
) -> MsgGenerator:
|
|
42
|
+
"""
|
|
43
|
+
A plan which combines the collection of snapshots from the OAV and the determination
|
|
44
|
+
of the grid dimensions to use for the following grid scan.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
@verify_undulator_gap_before_run_decorator(composite)
|
|
48
|
+
@transmission_and_xbpm_feedback_for_collection_decorator(
|
|
49
|
+
composite, parameters.transmission_frac, PlanNameConstants.GRIDSCAN_OUTER
|
|
50
|
+
)
|
|
51
|
+
def plan_to_perform():
|
|
52
|
+
yield from grid_detect_then_xray_centre(
|
|
53
|
+
composite=composite,
|
|
54
|
+
parameters=parameters,
|
|
55
|
+
xrc_params_type=HyperionSpecifiedThreeDGridScan,
|
|
56
|
+
construct_beamline_specific=construct_hyperion_specific_features,
|
|
57
|
+
oav_config=oav_config,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
yield from plan_to_perform()
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Generator
|
|
4
|
+
|
|
3
5
|
import bluesky.plan_stubs as bps
|
|
4
6
|
import numpy as np
|
|
5
7
|
import pydantic
|
|
@@ -18,12 +20,13 @@ from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
|
|
|
18
20
|
robot_load_then_xray_centre,
|
|
19
21
|
)
|
|
20
22
|
from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
|
|
21
|
-
|
|
23
|
+
RotationScan,
|
|
22
24
|
RotationScanComposite,
|
|
23
|
-
|
|
25
|
+
rotation_scan_internal,
|
|
24
26
|
)
|
|
25
27
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
26
28
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
29
|
+
from mx_bluesky.hyperion.parameters.rotation import RotationScanPerSweep
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
@@ -48,6 +51,8 @@ def load_centre_collect_full(
|
|
|
48
51
|
* If X-ray centring finds a diffracting centre then move to that centre and
|
|
49
52
|
* do a collection with the specified parameters.
|
|
50
53
|
"""
|
|
54
|
+
parameters.features.update_self_from_server()
|
|
55
|
+
|
|
51
56
|
if not oav_params:
|
|
52
57
|
oav_params = OAVParameters(context="xrayCentring")
|
|
53
58
|
oav_config_file = oav_params.oav_config_json
|
|
@@ -99,21 +104,46 @@ def load_centre_collect_full(
|
|
|
99
104
|
|
|
100
105
|
multi_rotation.rotation_scans.clear()
|
|
101
106
|
|
|
107
|
+
is_alternating = parameters.features.alternate_rotation_direction
|
|
108
|
+
|
|
109
|
+
generator = rotation_scan_generator(is_alternating)
|
|
110
|
+
next(generator)
|
|
102
111
|
for location in locations_to_collect_um:
|
|
103
112
|
for rot in rotation_template:
|
|
104
|
-
combination =
|
|
105
|
-
(
|
|
106
|
-
combination.x_start_um,
|
|
107
|
-
combination.y_start_um,
|
|
108
|
-
combination.z_start_um,
|
|
109
|
-
) = location
|
|
113
|
+
combination = generator.send((rot, location))
|
|
110
114
|
multi_rotation.rotation_scans.append(combination)
|
|
111
|
-
multi_rotation =
|
|
115
|
+
multi_rotation = RotationScan.model_validate(multi_rotation)
|
|
112
116
|
|
|
113
117
|
assert (
|
|
114
118
|
multi_rotation.demand_energy_ev
|
|
115
119
|
== parameters.robot_load_then_centre.demand_energy_ev
|
|
116
120
|
), "Setting a different energy for gridscan and rotation is not supported"
|
|
117
|
-
yield from
|
|
121
|
+
yield from rotation_scan_internal(composite, multi_rotation, oav_params)
|
|
118
122
|
|
|
119
123
|
yield from plan_with_callback_subs()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def rotation_scan_generator(
|
|
127
|
+
is_alternating: bool,
|
|
128
|
+
) -> Generator[RotationScanPerSweep, tuple[RotationScanPerSweep, np.ndarray], None]:
|
|
129
|
+
scan_template, location = yield # type: ignore
|
|
130
|
+
next_rotation_direction = scan_template.rotation_direction
|
|
131
|
+
while True:
|
|
132
|
+
scan = scan_template.model_copy()
|
|
133
|
+
(
|
|
134
|
+
scan.x_start_um,
|
|
135
|
+
scan.y_start_um,
|
|
136
|
+
scan.z_start_um,
|
|
137
|
+
) = location
|
|
138
|
+
if is_alternating:
|
|
139
|
+
if next_rotation_direction != scan.rotation_direction:
|
|
140
|
+
# If originally specified direction of the current scan is different
|
|
141
|
+
# from that required, swap the start and ends.
|
|
142
|
+
start = scan.omega_start_deg
|
|
143
|
+
rotation_sign = scan.rotation_direction.multiplier
|
|
144
|
+
end = start + rotation_sign * scan.scan_width_deg
|
|
145
|
+
scan.omega_start_deg = end
|
|
146
|
+
scan.rotation_direction = next_rotation_direction
|
|
147
|
+
next_rotation_direction = next_rotation_direction.opposite
|
|
148
|
+
|
|
149
|
+
scan_template, location = yield scan
|
|
@@ -9,9 +9,18 @@ from dodal.devices.eiger import EigerDetector
|
|
|
9
9
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
10
10
|
|
|
11
11
|
from mx_bluesky.common.device_setup_plans.manipulate_sample import move_phi_chi_omega
|
|
12
|
+
from mx_bluesky.common.device_setup_plans.utils import (
|
|
13
|
+
start_preparing_data_collection_then_do_plan,
|
|
14
|
+
)
|
|
12
15
|
from mx_bluesky.common.experiment_plans.change_aperture_then_move_plan import (
|
|
13
16
|
change_aperture_then_move_to_xtal,
|
|
14
17
|
)
|
|
18
|
+
from mx_bluesky.common.experiment_plans.common_grid_detect_then_xray_centre_plan import (
|
|
19
|
+
detect_grid_and_do_gridscan,
|
|
20
|
+
)
|
|
21
|
+
from mx_bluesky.common.experiment_plans.oav_snapshot_plan import (
|
|
22
|
+
setup_beamline_for_OAV,
|
|
23
|
+
)
|
|
15
24
|
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
16
25
|
ispyb_activation_wrapper,
|
|
17
26
|
)
|
|
@@ -19,32 +28,33 @@ from mx_bluesky.common.parameters.constants import OavConstants
|
|
|
19
28
|
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
20
29
|
from mx_bluesky.common.utils.log import LOGGER
|
|
21
30
|
from mx_bluesky.common.xrc_result import XRayCentreEventHandler
|
|
22
|
-
from mx_bluesky.hyperion.
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import (
|
|
26
|
-
GridDetectThenXRayCentreComposite,
|
|
27
|
-
detect_grid_and_do_gridscan,
|
|
28
|
-
)
|
|
29
|
-
from mx_bluesky.hyperion.experiment_plans.oav_snapshot_plan import (
|
|
30
|
-
setup_beamline_for_OAV,
|
|
31
|
+
from mx_bluesky.hyperion.experiment_plans.hyperion_flyscan_xray_centre_plan import (
|
|
32
|
+
construct_hyperion_specific_features,
|
|
31
33
|
)
|
|
32
34
|
from mx_bluesky.hyperion.experiment_plans.pin_tip_centring_plan import (
|
|
33
35
|
PinTipCentringComposite,
|
|
34
36
|
pin_tip_centre_plan,
|
|
35
37
|
)
|
|
36
38
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
39
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
40
|
+
HyperionGridDetectThenXRayCentreComposite,
|
|
41
|
+
)
|
|
37
42
|
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
38
43
|
GridScanWithEdgeDetect,
|
|
44
|
+
HyperionSpecifiedThreeDGridScan,
|
|
39
45
|
PinTipCentreThenXrayCentre,
|
|
40
46
|
)
|
|
41
47
|
|
|
42
48
|
|
|
43
|
-
def create_devices(
|
|
49
|
+
def create_devices(
|
|
50
|
+
context: BlueskyContext,
|
|
51
|
+
) -> HyperionGridDetectThenXRayCentreComposite:
|
|
44
52
|
"""
|
|
45
|
-
|
|
53
|
+
HyperionGridDetectThenXRayCentreComposite contains all the devices we need, reuse that.
|
|
46
54
|
"""
|
|
47
|
-
return device_composite_from_context(
|
|
55
|
+
return device_composite_from_context(
|
|
56
|
+
context, HyperionGridDetectThenXRayCentreComposite
|
|
57
|
+
)
|
|
48
58
|
|
|
49
59
|
|
|
50
60
|
def create_parameters_for_grid_detection(
|
|
@@ -60,7 +70,7 @@ def create_parameters_for_grid_detection(
|
|
|
60
70
|
|
|
61
71
|
|
|
62
72
|
def pin_centre_then_flyscan_plan(
|
|
63
|
-
composite:
|
|
73
|
+
composite: HyperionGridDetectThenXRayCentreComposite,
|
|
64
74
|
parameters: PinTipCentreThenXrayCentre,
|
|
65
75
|
oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
|
|
66
76
|
):
|
|
@@ -92,20 +102,21 @@ def pin_centre_then_flyscan_plan(
|
|
|
92
102
|
)
|
|
93
103
|
|
|
94
104
|
grid_detect_params = create_parameters_for_grid_detection(parameters)
|
|
95
|
-
|
|
96
105
|
oav_params = OAVParameters("xrayCentring", oav_config_file)
|
|
97
106
|
|
|
98
107
|
yield from detect_grid_and_do_gridscan(
|
|
99
108
|
composite,
|
|
100
109
|
grid_detect_params,
|
|
101
110
|
oav_params,
|
|
111
|
+
HyperionSpecifiedThreeDGridScan,
|
|
112
|
+
construct_hyperion_specific_features,
|
|
102
113
|
)
|
|
103
114
|
|
|
104
115
|
yield from ispyb_activation_wrapper(_pin_centre_then_flyscan_plan(), parameters)
|
|
105
116
|
|
|
106
117
|
|
|
107
118
|
def pin_tip_centre_then_xray_centre(
|
|
108
|
-
composite:
|
|
119
|
+
composite: HyperionGridDetectThenXRayCentreComposite,
|
|
109
120
|
parameters: PinTipCentreThenXrayCentre,
|
|
110
121
|
oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
|
|
111
122
|
) -> MsgGenerator:
|
|
@@ -19,7 +19,7 @@ from dodal.devices.i03.undulator_dcm import UndulatorDCM
|
|
|
19
19
|
from dodal.devices.motors import XYZPositioner
|
|
20
20
|
from dodal.devices.oav.oav_detector import OAV
|
|
21
21
|
from dodal.devices.robot import BartRobot, SampleLocation
|
|
22
|
-
from dodal.devices.smargon import Smargon, StubPosition
|
|
22
|
+
from dodal.devices.smargon import CombinedMove, Smargon, StubPosition
|
|
23
23
|
from dodal.devices.thawer import Thawer
|
|
24
24
|
from dodal.devices.webcam import Webcam
|
|
25
25
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
@@ -104,16 +104,7 @@ def prepare_for_robot_load(
|
|
|
104
104
|
|
|
105
105
|
yield from bps.mv(smargon.stub_offsets, StubPosition.RESET_TO_ROBOT_LOAD)
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
yield from bps.mv(
|
|
109
|
-
smargon.x, 0,
|
|
110
|
-
smargon.y, 0,
|
|
111
|
-
smargon.z, 0,
|
|
112
|
-
smargon.omega, 0,
|
|
113
|
-
smargon.chi, 0,
|
|
114
|
-
smargon.phi, 0
|
|
115
|
-
)
|
|
116
|
-
# fmt: on
|
|
107
|
+
yield from bps.mv(smargon, CombinedMove(x=0, y=0, z=0, chi=0, phi=0, omega=0))
|
|
117
108
|
|
|
118
109
|
yield from bps.wait("prepare_robot_load")
|
|
119
110
|
|
|
@@ -35,13 +35,12 @@ from dodal.devices.zocalo import ZocaloResults
|
|
|
35
35
|
from dodal.log import LOGGER
|
|
36
36
|
from ophyd_async.fastcs.panda import HDFPanda
|
|
37
37
|
|
|
38
|
+
from mx_bluesky.common.device_setup_plans.utils import (
|
|
39
|
+
start_preparing_data_collection_then_do_plan,
|
|
40
|
+
)
|
|
38
41
|
from mx_bluesky.common.parameters.constants import OavConstants
|
|
39
42
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
40
43
|
fill_in_energy_if_not_supplied,
|
|
41
|
-
start_preparing_data_collection_then_do_plan,
|
|
42
|
-
)
|
|
43
|
-
from mx_bluesky.hyperion.experiment_plans.grid_detect_then_xray_centre_plan import (
|
|
44
|
-
GridDetectThenXRayCentreComposite,
|
|
45
44
|
)
|
|
46
45
|
from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan import (
|
|
47
46
|
pin_centre_then_flyscan_plan,
|
|
@@ -56,6 +55,9 @@ from mx_bluesky.hyperion.experiment_plans.set_energy_plan import (
|
|
|
56
55
|
set_energy_plan,
|
|
57
56
|
)
|
|
58
57
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
58
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
59
|
+
HyperionGridDetectThenXRayCentreComposite,
|
|
60
|
+
)
|
|
59
61
|
from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre
|
|
60
62
|
|
|
61
63
|
|
|
@@ -65,7 +67,7 @@ class RobotLoadThenCentreComposite:
|
|
|
65
67
|
xbpm_feedback: XBPMFeedback
|
|
66
68
|
attenuator: BinaryFilterAttenuator
|
|
67
69
|
|
|
68
|
-
#
|
|
70
|
+
# HyperionGridDetectThenXRayCentreComposite fields
|
|
69
71
|
aperture_scatterguard: ApertureScatterguard
|
|
70
72
|
backlight: Backlight
|
|
71
73
|
detector_motion: DetectorMotion
|
|
@@ -110,7 +112,7 @@ def _flyscan_plan_from_robot_load_params(
|
|
|
110
112
|
oav_config_file: str = OavConstants.OAV_CONFIG_JSON,
|
|
111
113
|
):
|
|
112
114
|
yield from pin_centre_then_flyscan_plan(
|
|
113
|
-
cast(
|
|
115
|
+
cast(HyperionGridDetectThenXRayCentreComposite, composite),
|
|
114
116
|
params.pin_centre_then_xray_centre_params,
|
|
115
117
|
oav_config_file,
|
|
116
118
|
)
|