mx-bluesky 1.4.7__py3-none-any.whl → 1.4.9__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/i04/redis_to_murko_forwarder.py +4 -4
- mx_bluesky/beamlines/i04/thawing_plan.py +8 -2
- mx_bluesky/beamlines/i23/__init__.py +3 -0
- mx_bluesky/beamlines/i23/serial.py +71 -0
- mx_bluesky/beamlines/i24/serial/__init__.py +2 -0
- mx_bluesky/beamlines/i24/serial/blueapi_config.yaml +2 -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 +25 -5
- 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 +5 -5
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +29 -60
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +7 -1
- mx_bluesky/beamlines/i24/serial/log.py +9 -10
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +36 -7
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +0 -1
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv_abstract.py +4 -4
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +4 -12
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +2 -1
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +71 -11
- mx_bluesky/beamlines/i24/serial/write_nexus.py +3 -3
- mx_bluesky/{hyperion → common}/device_setup_plans/manipulate_sample.py +6 -14
- mx_bluesky/{hyperion → common}/device_setup_plans/setup_oav.py +12 -6
- mx_bluesky/{hyperion → common}/experiment_plans/change_aperture_then_move_plan.py +4 -5
- mx_bluesky/{hyperion → common}/experiment_plans/oav_grid_detection_plan.py +6 -6
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +6 -5
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +16 -47
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +4 -1
- mx_bluesky/common/external_interaction/ispyb/ispyb_utils.py +4 -4
- mx_bluesky/common/external_interaction/nexus/nexus_utils.py +2 -2
- mx_bluesky/common/parameters/components.py +22 -2
- mx_bluesky/common/parameters/constants.py +4 -16
- mx_bluesky/common/parameters/gridscan.py +36 -32
- mx_bluesky/common/plans/common_flyscan_xray_centre_plan.py +316 -0
- mx_bluesky/common/plans/inner_plans/__init__ .py +0 -0
- mx_bluesky/common/plans/read_hardware.py +3 -3
- mx_bluesky/common/utils/log.py +19 -15
- mx_bluesky/hyperion/__main__.py +6 -24
- mx_bluesky/hyperion/baton_handler.py +8 -3
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +4 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +0 -33
- mx_bluesky/hyperion/device_setup_plans/smargon.py +2 -7
- mx_bluesky/hyperion/device_setup_plans/utils.py +6 -5
- mx_bluesky/hyperion/experiment_plans/__init__.py +1 -7
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +3 -13
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +80 -87
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +183 -0
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +50 -15
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +31 -7
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +4 -4
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +1 -1
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +13 -14
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +9 -8
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +30 -71
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +2 -2
- mx_bluesky/hyperion/external_interaction/agamemnon.py +78 -80
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +8 -6
- 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/callbacks/snapshot_callback.py +183 -31
- mx_bluesky/hyperion/external_interaction/config_server.py +4 -1
- mx_bluesky/hyperion/parameters/cli.py +4 -19
- mx_bluesky/hyperion/parameters/constants.py +1 -5
- mx_bluesky/hyperion/parameters/device_composites.py +40 -5
- mx_bluesky/hyperion/parameters/gridscan.py +9 -58
- mx_bluesky/hyperion/parameters/load_centre_collect.py +4 -4
- mx_bluesky/hyperion/parameters/rotation.py +9 -12
- mx_bluesky/hyperion/utils/context.py +2 -2
- mx_bluesky/hyperion/utils/validation.py +15 -19
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/METADATA +7 -6
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/RECORD +86 -83
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/WHEEL +1 -1
- mx_bluesky/common/external_interaction/test_config_server.py +0 -38
- mx_bluesky/hyperion/device_setup_plans/check_beamstop.py +0 -27
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +0 -467
- /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short1-laser.png → s1l.png} +0 -0
- /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short2-laser.png → s2l.png} +0 -0
- /mx_bluesky/{hyperion → common}/device_setup_plans/position_detector.py +0 -0
- /mx_bluesky/common/plans/{do_fgs.py → inner_plans/do_fgs.py} +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.9.dist-info}/top_level.txt +0 -0
|
@@ -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
|
)
|
|
@@ -16,15 +13,12 @@ from mx_bluesky.hyperion.experiment_plans.pin_centre_then_xray_centre_plan impor
|
|
|
16
13
|
pin_tip_centre_then_xray_centre,
|
|
17
14
|
)
|
|
18
15
|
from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
|
|
19
|
-
multi_rotation_scan,
|
|
20
16
|
rotation_scan,
|
|
21
17
|
)
|
|
22
18
|
|
|
23
19
|
__all__ = [
|
|
24
|
-
"flyscan_xray_centre",
|
|
25
20
|
"grid_detect_then_xray_centre",
|
|
26
|
-
"rotation_scan",
|
|
27
21
|
"pin_tip_centre_then_xray_centre",
|
|
28
|
-
"
|
|
22
|
+
"rotation_scan",
|
|
29
23
|
"load_centre_collect_full",
|
|
30
24
|
]
|
|
@@ -3,7 +3,6 @@ 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,
|
|
@@ -16,7 +15,7 @@ from mx_bluesky.hyperion.parameters.gridscan import (
|
|
|
16
15
|
PinTipCentreThenXrayCentre,
|
|
17
16
|
)
|
|
18
17
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
19
|
-
from mx_bluesky.hyperion.parameters.rotation import
|
|
18
|
+
from mx_bluesky.hyperion.parameters.rotation import RotationScan
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
def not_implemented():
|
|
@@ -33,32 +32,23 @@ class ExperimentRegistryEntry(TypedDict):
|
|
|
33
32
|
HyperionSpecifiedThreeDGridScan
|
|
34
33
|
| GridScanWithEdgeDetect
|
|
35
34
|
| RotationScan
|
|
36
|
-
| MultiRotationScan
|
|
37
35
|
| PinTipCentreThenXrayCentre
|
|
38
36
|
| LoadCentreCollect
|
|
39
37
|
]
|
|
40
38
|
|
|
41
39
|
|
|
42
40
|
PLAN_REGISTRY: dict[str, ExperimentRegistryEntry] = {
|
|
43
|
-
"flyscan_xray_centre": {
|
|
44
|
-
"setup": flyscan_xray_centre_plan.create_devices,
|
|
45
|
-
"param_type": HyperionSpecifiedThreeDGridScan,
|
|
46
|
-
},
|
|
47
41
|
"grid_detect_then_xray_centre": {
|
|
48
42
|
"setup": grid_detect_then_xray_centre_plan.create_devices,
|
|
49
43
|
"param_type": GridScanWithEdgeDetect,
|
|
50
44
|
},
|
|
51
|
-
"rotation_scan": {
|
|
52
|
-
"setup": rotation_scan_plan.create_devices,
|
|
53
|
-
"param_type": RotationScan,
|
|
54
|
-
},
|
|
55
45
|
"pin_tip_centre_then_xray_centre": {
|
|
56
46
|
"setup": pin_centre_then_xray_centre_plan.create_devices,
|
|
57
47
|
"param_type": PinTipCentreThenXrayCentre,
|
|
58
48
|
},
|
|
59
|
-
"
|
|
49
|
+
"rotation_scan": {
|
|
60
50
|
"setup": rotation_scan_plan.create_devices,
|
|
61
|
-
"param_type":
|
|
51
|
+
"param_type": RotationScan,
|
|
62
52
|
},
|
|
63
53
|
"load_centre_collect_full": {
|
|
64
54
|
"setup": load_centre_collect_full_plan.create_devices,
|
|
@@ -2,35 +2,28 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
import pydantic
|
|
6
5
|
from blueapi.core import BlueskyContext
|
|
7
6
|
from bluesky import plan_stubs as bps
|
|
8
7
|
from bluesky import preprocessors as bpp
|
|
9
8
|
from bluesky.preprocessors import subs_decorator
|
|
10
9
|
from bluesky.utils import MsgGenerator
|
|
11
|
-
from dodal.devices.
|
|
12
|
-
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
13
|
-
from dodal.devices.backlight import Backlight, BacklightPosition
|
|
14
|
-
from dodal.devices.dcm import DCM
|
|
15
|
-
from dodal.devices.detector.detector_motion import DetectorMotion
|
|
10
|
+
from dodal.devices.backlight import BacklightPosition
|
|
16
11
|
from dodal.devices.eiger import EigerDetector
|
|
17
|
-
from dodal.devices.fast_grid_scan import PandAFastGridScan, ZebraFastGridScan
|
|
18
|
-
from dodal.devices.flux import Flux
|
|
19
|
-
from dodal.devices.i03.beamstop import Beamstop
|
|
20
|
-
from dodal.devices.oav.oav_detector import OAV
|
|
21
12
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
22
|
-
from dodal.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
from dodal.devices.smargon import Smargon
|
|
26
|
-
from dodal.devices.synchrotron import Synchrotron
|
|
27
|
-
from dodal.devices.undulator import Undulator
|
|
28
|
-
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
29
|
-
from dodal.devices.zebra.zebra import Zebra
|
|
30
|
-
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
31
|
-
from dodal.devices.zocalo import ZocaloResults
|
|
32
|
-
from ophyd_async.fastcs.panda import HDFPanda
|
|
13
|
+
from dodal.plans.preprocessors.verify_undulator_gap import (
|
|
14
|
+
verify_undulator_gap_before_run_decorator,
|
|
15
|
+
)
|
|
33
16
|
|
|
17
|
+
from mx_bluesky.common.device_setup_plans.manipulate_sample import (
|
|
18
|
+
move_aperture_if_required,
|
|
19
|
+
)
|
|
20
|
+
from mx_bluesky.common.experiment_plans.change_aperture_then_move_plan import (
|
|
21
|
+
change_aperture_then_move_to_xtal,
|
|
22
|
+
)
|
|
23
|
+
from mx_bluesky.common.experiment_plans.oav_grid_detection_plan import (
|
|
24
|
+
OavGridDetectionComposite,
|
|
25
|
+
grid_detection_plan,
|
|
26
|
+
)
|
|
34
27
|
from mx_bluesky.common.external_interaction.callbacks.common.grid_detection_callback import (
|
|
35
28
|
GridDetectionCallback,
|
|
36
29
|
GridParamUpdate,
|
|
@@ -39,27 +32,29 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback
|
|
|
39
32
|
ispyb_activation_wrapper,
|
|
40
33
|
)
|
|
41
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,
|
|
39
|
+
)
|
|
40
|
+
from mx_bluesky.common.preprocessors.preprocessors import (
|
|
41
|
+
transmission_and_xbpm_feedback_for_collection_decorator,
|
|
42
|
+
)
|
|
42
43
|
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
43
44
|
from mx_bluesky.common.utils.log import LOGGER
|
|
44
45
|
from mx_bluesky.common.xrc_result import XRayCentreEventHandler
|
|
45
|
-
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
|
|
46
|
-
move_aperture_if_required,
|
|
47
|
-
)
|
|
48
46
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
49
47
|
start_preparing_data_collection_then_do_plan,
|
|
50
48
|
)
|
|
51
|
-
from mx_bluesky.hyperion.experiment_plans.
|
|
52
|
-
|
|
53
|
-
)
|
|
54
|
-
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
55
|
-
flyscan_xray_centre_no_move,
|
|
49
|
+
from mx_bluesky.hyperion.experiment_plans.hyperion_flyscan_xray_centre_plan import (
|
|
50
|
+
construct_hyperion_specific_features,
|
|
56
51
|
)
|
|
57
|
-
from mx_bluesky.hyperion.experiment_plans.
|
|
58
|
-
|
|
59
|
-
grid_detection_plan,
|
|
52
|
+
from mx_bluesky.hyperion.experiment_plans.oav_snapshot_plan import (
|
|
53
|
+
setup_beamline_for_OAV,
|
|
60
54
|
)
|
|
61
55
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
62
56
|
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
57
|
+
GridDetectThenXRayCentreComposite,
|
|
63
58
|
HyperionFlyScanXRayCentreComposite,
|
|
64
59
|
)
|
|
65
60
|
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
@@ -68,40 +63,12 @@ from mx_bluesky.hyperion.parameters.gridscan import (
|
|
|
68
63
|
)
|
|
69
64
|
|
|
70
65
|
|
|
71
|
-
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
72
|
-
class GridDetectThenXRayCentreComposite:
|
|
73
|
-
"""All devices which are directly or indirectly required by this plan"""
|
|
74
|
-
|
|
75
|
-
aperture_scatterguard: ApertureScatterguard
|
|
76
|
-
attenuator: BinaryFilterAttenuator
|
|
77
|
-
backlight: Backlight
|
|
78
|
-
beamstop: Beamstop
|
|
79
|
-
dcm: DCM
|
|
80
|
-
detector_motion: DetectorMotion
|
|
81
|
-
eiger: EigerDetector
|
|
82
|
-
zebra_fast_grid_scan: ZebraFastGridScan
|
|
83
|
-
flux: Flux
|
|
84
|
-
oav: OAV
|
|
85
|
-
pin_tip_detection: PinTipDetection
|
|
86
|
-
smargon: Smargon
|
|
87
|
-
synchrotron: Synchrotron
|
|
88
|
-
s4_slit_gaps: S4SlitGaps
|
|
89
|
-
undulator: Undulator
|
|
90
|
-
xbpm_feedback: XBPMFeedback
|
|
91
|
-
zebra: Zebra
|
|
92
|
-
zocalo: ZocaloResults
|
|
93
|
-
panda: HDFPanda
|
|
94
|
-
panda_fast_grid_scan: PandAFastGridScan
|
|
95
|
-
robot: BartRobot
|
|
96
|
-
sample_shutter: ZebraShutter
|
|
97
|
-
|
|
98
|
-
|
|
99
66
|
def create_devices(context: BlueskyContext) -> GridDetectThenXRayCentreComposite:
|
|
100
67
|
return device_composite_from_context(context, GridDetectThenXRayCentreComposite)
|
|
101
68
|
|
|
102
69
|
|
|
103
70
|
def create_parameters_for_flyscan_xray_centre(
|
|
104
|
-
grid_scan_with_edge_params:
|
|
71
|
+
grid_scan_with_edge_params: GridCommon,
|
|
105
72
|
grid_parameters: GridParamUpdate,
|
|
106
73
|
) -> HyperionSpecifiedThreeDGridScan:
|
|
107
74
|
params_json = grid_scan_with_edge_params.model_dump()
|
|
@@ -113,7 +80,7 @@ def create_parameters_for_flyscan_xray_centre(
|
|
|
113
80
|
|
|
114
81
|
def detect_grid_and_do_gridscan(
|
|
115
82
|
composite: GridDetectThenXRayCentreComposite,
|
|
116
|
-
parameters:
|
|
83
|
+
parameters: GridCommon,
|
|
117
84
|
oav_params: OAVParameters,
|
|
118
85
|
):
|
|
119
86
|
snapshot_template = f"{parameters.detector_params.prefix}_{parameters.detector_params.run_number}_{{angle}}"
|
|
@@ -142,12 +109,19 @@ def detect_grid_and_do_gridscan(
|
|
|
142
109
|
parameters.box_size_um,
|
|
143
110
|
)
|
|
144
111
|
|
|
112
|
+
yield from setup_beamline_for_OAV(
|
|
113
|
+
composite.smargon,
|
|
114
|
+
composite.backlight,
|
|
115
|
+
composite.aperture_scatterguard,
|
|
116
|
+
wait=True,
|
|
117
|
+
)
|
|
118
|
+
|
|
145
119
|
if parameters.selected_aperture:
|
|
146
120
|
# Start moving the aperture/scatterguard into position without moving it in
|
|
147
121
|
yield from bps.prepare(
|
|
148
122
|
composite.aperture_scatterguard,
|
|
149
123
|
parameters.selected_aperture,
|
|
150
|
-
group=CONST.WAIT.
|
|
124
|
+
group=CONST.WAIT.PREPARE_APERTURE,
|
|
151
125
|
)
|
|
152
126
|
|
|
153
127
|
yield from run_grid_detection_plan(
|
|
@@ -160,38 +134,57 @@ def detect_grid_and_do_gridscan(
|
|
|
160
134
|
composite.backlight, BacklightPosition.OUT, group=CONST.WAIT.GRID_READY_FOR_DC
|
|
161
135
|
)
|
|
162
136
|
|
|
137
|
+
yield from bps.wait(CONST.WAIT.PREPARE_APERTURE)
|
|
163
138
|
yield from move_aperture_if_required(
|
|
164
139
|
composite.aperture_scatterguard,
|
|
165
140
|
parameters.selected_aperture,
|
|
166
141
|
group=CONST.WAIT.GRID_READY_FOR_DC,
|
|
167
142
|
)
|
|
168
143
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
sample_shutter=composite.sample_shutter,
|
|
189
|
-
),
|
|
190
|
-
create_parameters_for_flyscan_xray_centre(
|
|
191
|
-
parameters, grid_params_callback.get_grid_parameters()
|
|
192
|
-
),
|
|
144
|
+
xrc_composite = HyperionFlyScanXRayCentreComposite(
|
|
145
|
+
aperture_scatterguard=composite.aperture_scatterguard,
|
|
146
|
+
attenuator=composite.attenuator,
|
|
147
|
+
backlight=composite.backlight,
|
|
148
|
+
eiger=composite.eiger,
|
|
149
|
+
panda_fast_grid_scan=composite.panda_fast_grid_scan,
|
|
150
|
+
flux=composite.flux,
|
|
151
|
+
s4_slit_gaps=composite.s4_slit_gaps,
|
|
152
|
+
smargon=composite.smargon,
|
|
153
|
+
undulator=composite.undulator,
|
|
154
|
+
synchrotron=composite.synchrotron,
|
|
155
|
+
xbpm_feedback=composite.xbpm_feedback,
|
|
156
|
+
zebra=composite.zebra,
|
|
157
|
+
zocalo=composite.zocalo,
|
|
158
|
+
panda=composite.panda,
|
|
159
|
+
zebra_fast_grid_scan=composite.zebra_fast_grid_scan,
|
|
160
|
+
dcm=composite.dcm,
|
|
161
|
+
robot=composite.robot,
|
|
162
|
+
sample_shutter=composite.sample_shutter,
|
|
193
163
|
)
|
|
194
164
|
|
|
165
|
+
params = create_parameters_for_flyscan_xray_centre(
|
|
166
|
+
parameters, grid_params_callback.get_grid_parameters()
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
beamline_specific = construct_hyperion_specific_features(xrc_composite, params)
|
|
170
|
+
|
|
171
|
+
yield from _gridscan_with_undulator_checks(xrc_composite, params, beamline_specific)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _gridscan_with_undulator_checks(
|
|
175
|
+
composite: HyperionFlyScanXRayCentreComposite,
|
|
176
|
+
params: HyperionSpecifiedThreeDGridScan,
|
|
177
|
+
beamline_specific: BeamlineSpecificFGSFeatures,
|
|
178
|
+
):
|
|
179
|
+
@transmission_and_xbpm_feedback_for_collection_decorator(
|
|
180
|
+
composite, params.transmission_frac
|
|
181
|
+
)
|
|
182
|
+
@verify_undulator_gap_before_run_decorator(composite)
|
|
183
|
+
def _inner():
|
|
184
|
+
yield from common_flyscan_xray_centre(composite, params, beamline_specific)
|
|
185
|
+
|
|
186
|
+
yield from _inner()
|
|
187
|
+
|
|
195
188
|
|
|
196
189
|
def grid_detect_then_xray_centre(
|
|
197
190
|
composite: GridDetectThenXRayCentreComposite,
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from functools import partial
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import bluesky.plan_stubs as bps
|
|
7
|
+
from bluesky.utils import MsgGenerator
|
|
8
|
+
from dodal.devices.fast_grid_scan import (
|
|
9
|
+
set_fast_grid_scan_params,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from mx_bluesky.common.plans.common_flyscan_xray_centre_plan import (
|
|
13
|
+
construct_beamline_specific_FGS_features,
|
|
14
|
+
)
|
|
15
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
16
|
+
from mx_bluesky.hyperion.device_setup_plans.setup_panda import (
|
|
17
|
+
disarm_panda_for_gridscan,
|
|
18
|
+
set_panda_directory,
|
|
19
|
+
setup_panda_for_flyscan,
|
|
20
|
+
)
|
|
21
|
+
from mx_bluesky.hyperion.device_setup_plans.setup_zebra import (
|
|
22
|
+
setup_zebra_for_gridscan,
|
|
23
|
+
setup_zebra_for_panda_flyscan,
|
|
24
|
+
tidy_up_zebra_after_gridscan,
|
|
25
|
+
)
|
|
26
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
27
|
+
HyperionFlyScanXRayCentreComposite,
|
|
28
|
+
)
|
|
29
|
+
from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SmargonSpeedException(Exception):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def construct_hyperion_specific_features(
|
|
37
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
38
|
+
parameters: HyperionSpecifiedThreeDGridScan,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Get all the information needed to do the Hyperion-specific parts of the XRC flyscan.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
signals_to_read_pre_flyscan = [
|
|
45
|
+
fgs_composite.undulator.current_gap,
|
|
46
|
+
fgs_composite.synchrotron.synchrotron_mode,
|
|
47
|
+
fgs_composite.s4_slit_gaps.xgap,
|
|
48
|
+
fgs_composite.s4_slit_gaps.ygap,
|
|
49
|
+
fgs_composite.smargon.x,
|
|
50
|
+
fgs_composite.smargon.y,
|
|
51
|
+
fgs_composite.smargon.z,
|
|
52
|
+
fgs_composite.dcm.energy_in_kev,
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
signals_to_read_during_collection = [
|
|
56
|
+
fgs_composite.aperture_scatterguard,
|
|
57
|
+
fgs_composite.attenuator.actual_transmission,
|
|
58
|
+
fgs_composite.flux.flux_reading,
|
|
59
|
+
fgs_composite.dcm.energy_in_kev,
|
|
60
|
+
fgs_composite.eiger.bit_depth,
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
if parameters.features.use_panda_for_gridscan:
|
|
64
|
+
setup_trigger_plan = _panda_triggering_setup
|
|
65
|
+
tidy_plan = _panda_tidy
|
|
66
|
+
set_flyscan_params_plan = partial(
|
|
67
|
+
set_fast_grid_scan_params,
|
|
68
|
+
fgs_composite.panda_fast_grid_scan,
|
|
69
|
+
parameters.panda_FGS_params,
|
|
70
|
+
)
|
|
71
|
+
fgs_motors = fgs_composite.panda_fast_grid_scan
|
|
72
|
+
|
|
73
|
+
else:
|
|
74
|
+
setup_trigger_plan = _zebra_triggering_setup
|
|
75
|
+
tidy_plan = partial(_generic_tidy, group="flyscan_zebra_tidy", wait=True)
|
|
76
|
+
set_flyscan_params_plan = partial(
|
|
77
|
+
set_fast_grid_scan_params,
|
|
78
|
+
fgs_composite.zebra_fast_grid_scan,
|
|
79
|
+
parameters.FGS_params,
|
|
80
|
+
)
|
|
81
|
+
fgs_motors = fgs_composite.zebra_fast_grid_scan
|
|
82
|
+
return construct_beamline_specific_FGS_features(
|
|
83
|
+
setup_trigger_plan,
|
|
84
|
+
tidy_plan,
|
|
85
|
+
set_flyscan_params_plan,
|
|
86
|
+
fgs_motors,
|
|
87
|
+
signals_to_read_pre_flyscan,
|
|
88
|
+
signals_to_read_during_collection,
|
|
89
|
+
get_xrc_results_from_zocalo=True,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _generic_tidy(
|
|
94
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite, group, wait=True
|
|
95
|
+
) -> MsgGenerator:
|
|
96
|
+
LOGGER.info("Tidying up Zebra")
|
|
97
|
+
yield from tidy_up_zebra_after_gridscan(
|
|
98
|
+
fgs_composite.zebra, fgs_composite.sample_shutter, group=group, wait=wait
|
|
99
|
+
)
|
|
100
|
+
LOGGER.info("Tidying up Zocalo")
|
|
101
|
+
# make sure we don't consume any other results
|
|
102
|
+
yield from bps.unstage(fgs_composite.zocalo, group=group, wait=wait)
|
|
103
|
+
|
|
104
|
+
# Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
|
|
105
|
+
LOGGER.info("Turning off Eiger dev/shm streaming")
|
|
106
|
+
yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _panda_tidy(fgs_composite: HyperionFlyScanXRayCentreComposite):
|
|
110
|
+
group = "panda_flyscan_tidy"
|
|
111
|
+
LOGGER.info("Disabling panda blocks")
|
|
112
|
+
yield from disarm_panda_for_gridscan(fgs_composite.panda, group)
|
|
113
|
+
yield from _generic_tidy(fgs_composite, group, False)
|
|
114
|
+
yield from bps.wait(group, timeout=10)
|
|
115
|
+
yield from bps.unstage(fgs_composite.panda)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _zebra_triggering_setup(
|
|
119
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
120
|
+
parameters: HyperionSpecifiedThreeDGridScan,
|
|
121
|
+
) -> MsgGenerator:
|
|
122
|
+
yield from setup_zebra_for_gridscan(
|
|
123
|
+
fgs_composite.zebra, fgs_composite.sample_shutter, wait=True
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _panda_triggering_setup(
|
|
128
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
129
|
+
parameters: HyperionSpecifiedThreeDGridScan,
|
|
130
|
+
) -> MsgGenerator:
|
|
131
|
+
LOGGER.info("Setting up Panda for flyscan")
|
|
132
|
+
|
|
133
|
+
run_up_distance_mm = yield from bps.rd(
|
|
134
|
+
fgs_composite.panda_fast_grid_scan.run_up_distance_mm
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Set the time between x steps pv
|
|
138
|
+
DEADTIME_S = 1e-6 # according to https://www.dectris.com/en/detectors/x-ray-detectors/eiger2/eiger2-for-synchrotrons/eiger2-x/
|
|
139
|
+
|
|
140
|
+
time_between_x_steps_ms = (DEADTIME_S + parameters.exposure_time_s) * 1e3
|
|
141
|
+
|
|
142
|
+
smargon_speed_limit_mm_per_s = yield from bps.rd(
|
|
143
|
+
fgs_composite.smargon.x.max_velocity
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
sample_velocity_mm_per_s = (
|
|
147
|
+
parameters.panda_FGS_params.x_step_size_mm * 1e3 / time_between_x_steps_ms
|
|
148
|
+
)
|
|
149
|
+
if sample_velocity_mm_per_s > smargon_speed_limit_mm_per_s:
|
|
150
|
+
raise SmargonSpeedException(
|
|
151
|
+
f"Smargon speed was calculated from x step size\
|
|
152
|
+
{parameters.panda_FGS_params.x_step_size_mm}mm and\
|
|
153
|
+
time_between_x_steps_ms {time_between_x_steps_ms} as\
|
|
154
|
+
{sample_velocity_mm_per_s}mm/s. The smargon's speed limit is\
|
|
155
|
+
{smargon_speed_limit_mm_per_s}mm/s."
|
|
156
|
+
)
|
|
157
|
+
else:
|
|
158
|
+
LOGGER.info(
|
|
159
|
+
f"Panda grid scan: Smargon speed set to {smargon_speed_limit_mm_per_s} mm/s"
|
|
160
|
+
f" and using a run-up distance of {run_up_distance_mm}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
yield from bps.mv(
|
|
164
|
+
fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
165
|
+
time_between_x_steps_ms, # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
directory_provider_root = Path(parameters.storage_directory)
|
|
169
|
+
yield from set_panda_directory(directory_provider_root)
|
|
170
|
+
|
|
171
|
+
yield from setup_panda_for_flyscan(
|
|
172
|
+
fgs_composite.panda,
|
|
173
|
+
parameters.panda_FGS_params,
|
|
174
|
+
fgs_composite.smargon,
|
|
175
|
+
parameters.exposure_time_s,
|
|
176
|
+
time_between_x_steps_ms,
|
|
177
|
+
sample_velocity_mm_per_s,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
LOGGER.info("Setting up Zebra for panda flyscan")
|
|
181
|
+
yield from setup_zebra_for_panda_flyscan(
|
|
182
|
+
fgs_composite.zebra, fgs_composite.sample_shutter, wait=True
|
|
183
|
+
)
|
|
@@ -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,8 +51,11 @@ 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")
|
|
58
|
+
oav_config_file = oav_params.oav_config_json
|
|
53
59
|
|
|
54
60
|
@set_run_key_decorator(CONST.PLAN.LOAD_CENTRE_COLLECT)
|
|
55
61
|
@run_decorator(
|
|
@@ -64,7 +70,9 @@ def load_centre_collect_full(
|
|
|
64
70
|
def plan_with_callback_subs():
|
|
65
71
|
flyscan_event_handler = XRayCentreEventHandler()
|
|
66
72
|
yield from subs_wrapper(
|
|
67
|
-
robot_load_then_xray_centre(
|
|
73
|
+
robot_load_then_xray_centre(
|
|
74
|
+
composite, parameters.robot_load_then_centre, oav_config_file
|
|
75
|
+
),
|
|
68
76
|
flyscan_event_handler,
|
|
69
77
|
)
|
|
70
78
|
|
|
@@ -83,32 +91,59 @@ def load_centre_collect_full(
|
|
|
83
91
|
else:
|
|
84
92
|
# If the xray centring hasn't found a result but has not thrown an error it
|
|
85
93
|
# means that we do not need to recentre and can collect where we are
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
initial_x_mm = yield from bps.rd(composite.smargon.x.user_readback)
|
|
95
|
+
initial_y_mm = yield from bps.rd(composite.smargon.y.user_readback)
|
|
96
|
+
initial_z_mm = yield from bps.rd(composite.smargon.z.user_readback)
|
|
89
97
|
|
|
90
|
-
locations_to_collect_um = [
|
|
98
|
+
locations_to_collect_um = [
|
|
99
|
+
np.array([initial_x_mm, initial_y_mm, initial_z_mm]) * 1000
|
|
100
|
+
]
|
|
91
101
|
|
|
92
102
|
multi_rotation = parameters.multi_rotation_scan
|
|
93
103
|
rotation_template = multi_rotation.rotation_scans.copy()
|
|
94
104
|
|
|
95
105
|
multi_rotation.rotation_scans.clear()
|
|
96
106
|
|
|
107
|
+
is_alternating = parameters.features.alternate_rotation_direction
|
|
108
|
+
|
|
109
|
+
generator = rotation_scan_generator(is_alternating)
|
|
110
|
+
next(generator)
|
|
97
111
|
for location in locations_to_collect_um:
|
|
98
112
|
for rot in rotation_template:
|
|
99
|
-
combination =
|
|
100
|
-
(
|
|
101
|
-
combination.x_start_um,
|
|
102
|
-
combination.y_start_um,
|
|
103
|
-
combination.z_start_um,
|
|
104
|
-
) = location
|
|
113
|
+
combination = generator.send((rot, location))
|
|
105
114
|
multi_rotation.rotation_scans.append(combination)
|
|
106
|
-
multi_rotation =
|
|
115
|
+
multi_rotation = RotationScan.model_validate(multi_rotation)
|
|
107
116
|
|
|
108
117
|
assert (
|
|
109
118
|
multi_rotation.demand_energy_ev
|
|
110
119
|
== parameters.robot_load_then_centre.demand_energy_ev
|
|
111
120
|
), "Setting a different energy for gridscan and rotation is not supported"
|
|
112
|
-
yield from
|
|
121
|
+
yield from rotation_scan_internal(composite, multi_rotation, oav_params)
|
|
113
122
|
|
|
114
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
|