mx-bluesky 1.4.9__py3-none-any.whl → 1.5.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/i24/serial/__init__.py +4 -2
- mx_bluesky/beamlines/i24/serial/blueapi_config.yaml +4 -0
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +8 -8
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +36 -4
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +6 -5
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +2 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +5 -5
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +79 -10
- mx_bluesky/common/device_setup_plans/manipulate_sample.py +4 -1
- mx_bluesky/common/device_setup_plans/robot_load_unload.py +123 -0
- mx_bluesky/common/device_setup_plans/utils.py +49 -0
- mx_bluesky/common/{plans → experiment_plans}/common_flyscan_xray_centre_plan.py +12 -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 -136
- 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 +5 -2
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +26 -24
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +0 -1
- mx_bluesky/common/external_interaction/nexus/write_nexus.py +2 -2
- mx_bluesky/common/parameters/components.py +8 -3
- mx_bluesky/common/parameters/constants.py +4 -3
- mx_bluesky/common/parameters/device_composites.py +65 -0
- mx_bluesky/common/utils/__init__.py +0 -0
- mx_bluesky/common/xrc_result.py +25 -2
- mx_bluesky/hyperion/device_setup_plans/utils.py +0 -48
- mx_bluesky/hyperion/experiment_plans/__init__.py +3 -3
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +3 -3
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +46 -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 +26 -8
- 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 +21 -75
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +10 -8
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +20 -15
- mx_bluesky/hyperion/external_interaction/agamemnon.py +4 -4
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/{robot_load → robot_actions}/ispyb_callback.py +28 -19
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/snapshot_callback.py +3 -0
- mx_bluesky/hyperion/external_interaction/config_server.py +0 -11
- mx_bluesky/hyperion/parameters/constants.py +1 -6
- mx_bluesky/hyperion/parameters/device_composites.py +5 -27
- mx_bluesky/hyperion/parameters/gridscan.py +2 -6
- mx_bluesky/hyperion/parameters/load_centre_collect.py +15 -0
- mx_bluesky/hyperion/parameters/rotation.py +7 -3
- {mx_bluesky-1.4.9.dist-info → mx_bluesky-1.5.1.dist-info}/METADATA +5 -4
- {mx_bluesky-1.4.9.dist-info → mx_bluesky-1.5.1.dist-info}/RECORD +56 -52
- mx_bluesky/hyperion/utils/validation.py +0 -196
- /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.9.dist-info → mx_bluesky-1.5.1.dist-info}/WHEEL +0 -0
- {mx_bluesky-1.4.9.dist-info → mx_bluesky-1.5.1.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.9.dist-info → mx_bluesky-1.5.1.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.4.9.dist-info → mx_bluesky-1.5.1.dist-info}/top_level.txt +0 -0
mx_bluesky/_version.py
CHANGED
|
@@ -2,7 +2,8 @@ from mx_bluesky.beamlines.i24.serial.web_gui_plans.general_plans import (
|
|
|
2
2
|
gui_gonio_move_on_click,
|
|
3
3
|
gui_move_backlight,
|
|
4
4
|
gui_move_detector,
|
|
5
|
-
|
|
5
|
+
gui_run_chip_collection,
|
|
6
|
+
gui_set_zoom_level,
|
|
6
7
|
gui_sleep,
|
|
7
8
|
gui_stage_move_on_click,
|
|
8
9
|
)
|
|
@@ -57,6 +58,7 @@ __all__ = [
|
|
|
57
58
|
"gui_gonio_move_on_click",
|
|
58
59
|
"gui_sleep",
|
|
59
60
|
"gui_move_detector",
|
|
60
|
-
"
|
|
61
|
+
"gui_run_chip_collection",
|
|
61
62
|
"gui_move_backlight",
|
|
63
|
+
"gui_set_zoom_level",
|
|
62
64
|
]
|
|
@@ -23,8 +23,8 @@ from dodal.devices.i24.beamstop import Beamstop
|
|
|
23
23
|
from dodal.devices.i24.dcm import DCM
|
|
24
24
|
from dodal.devices.i24.dual_backlight import DualBacklight
|
|
25
25
|
from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
|
|
26
|
-
from dodal.devices.i24.i24_detector_motion import DetectorMotion
|
|
27
26
|
from dodal.devices.i24.pilatus_metadata import PilatusMetadata
|
|
27
|
+
from dodal.devices.motors import YZStage
|
|
28
28
|
from dodal.devices.zebra.zebra import Zebra
|
|
29
29
|
|
|
30
30
|
from mx_bluesky.beamlines.i24.serial.dcid import (
|
|
@@ -70,7 +70,7 @@ def flush_print(text):
|
|
|
70
70
|
|
|
71
71
|
@log_on_entry
|
|
72
72
|
def initialise_extruder(
|
|
73
|
-
detector_stage:
|
|
73
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
74
74
|
) -> MsgGenerator:
|
|
75
75
|
SSX_LOGGER.info("Initialise Parameters for extruder data collection on I24.")
|
|
76
76
|
|
|
@@ -98,7 +98,7 @@ def initialise_extruder(
|
|
|
98
98
|
def laser_check(
|
|
99
99
|
mode: str,
|
|
100
100
|
zebra: Zebra = inject("zebra"),
|
|
101
|
-
detector_stage:
|
|
101
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
102
102
|
) -> MsgGenerator:
|
|
103
103
|
"""Plan to open the shutter and check the laser beam from the viewer by pressing \
|
|
104
104
|
'Laser On' and 'Laser Off' buttons on the edm.
|
|
@@ -138,7 +138,7 @@ def laser_check(
|
|
|
138
138
|
|
|
139
139
|
@log_on_entry
|
|
140
140
|
def enter_hutch(
|
|
141
|
-
detector_stage:
|
|
141
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
142
142
|
) -> MsgGenerator:
|
|
143
143
|
"""Move the detector stage before entering hutch."""
|
|
144
144
|
yield from bps.mv(detector_stage.z, SAFE_DET_Z)
|
|
@@ -146,12 +146,12 @@ def enter_hutch(
|
|
|
146
146
|
|
|
147
147
|
|
|
148
148
|
@log_on_entry
|
|
149
|
-
def read_parameters(detector_stage:
|
|
149
|
+
def read_parameters(detector_stage: YZStage, attenuator: ReadOnlyAttenuator):
|
|
150
150
|
""" Read the parameters from user input and create the parameter model for an \
|
|
151
151
|
extruder collection.
|
|
152
152
|
|
|
153
153
|
Args:
|
|
154
|
-
detector_stage (
|
|
154
|
+
detector_stage (YZStage): The detector stage device.
|
|
155
155
|
attenuator (ReadOnlyAttenuator): A read-only attenuator device to get the \
|
|
156
156
|
transmission value.
|
|
157
157
|
|
|
@@ -208,7 +208,7 @@ def main_extruder_plan(
|
|
|
208
208
|
aperture: Aperture,
|
|
209
209
|
backlight: DualBacklight,
|
|
210
210
|
beamstop: Beamstop,
|
|
211
|
-
detector_stage:
|
|
211
|
+
detector_stage: YZStage,
|
|
212
212
|
shutter: HutchShutter,
|
|
213
213
|
dcm: DCM,
|
|
214
214
|
mirrors: FocusMirrorsMode,
|
|
@@ -500,7 +500,7 @@ def run_extruder_plan(
|
|
|
500
500
|
aperture: Aperture = inject("aperture"),
|
|
501
501
|
backlight: DualBacklight = inject("backlight"),
|
|
502
502
|
beamstop: Beamstop = inject("beamstop"),
|
|
503
|
-
detector_stage:
|
|
503
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
504
504
|
shutter: HutchShutter = inject("shutter"),
|
|
505
505
|
dcm: DCM = inject("dcm"),
|
|
506
506
|
mirrors: FocusMirrorsMode = inject("focus_mirrors"),
|
|
@@ -18,9 +18,9 @@ from dodal.devices.i24.beamstop import Beamstop
|
|
|
18
18
|
from dodal.devices.i24.dcm import DCM
|
|
19
19
|
from dodal.devices.i24.dual_backlight import DualBacklight
|
|
20
20
|
from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
|
|
21
|
-
from dodal.devices.i24.i24_detector_motion import DetectorMotion
|
|
22
21
|
from dodal.devices.i24.pilatus_metadata import PilatusMetadata
|
|
23
22
|
from dodal.devices.i24.pmac import PMAC
|
|
23
|
+
from dodal.devices.motors import YZStage
|
|
24
24
|
from dodal.devices.zebra.zebra import Zebra
|
|
25
25
|
|
|
26
26
|
from mx_bluesky.beamlines.i24.serial.dcid import (
|
|
@@ -269,7 +269,7 @@ def start_i24(
|
|
|
269
269
|
aperture: Aperture,
|
|
270
270
|
backlight: DualBacklight,
|
|
271
271
|
beamstop: Beamstop,
|
|
272
|
-
detector_stage:
|
|
272
|
+
detector_stage: YZStage,
|
|
273
273
|
shutter: HutchShutter,
|
|
274
274
|
parameters: FixedTargetParameters,
|
|
275
275
|
dcm: DCM,
|
|
@@ -504,7 +504,7 @@ def main_fixed_target_plan(
|
|
|
504
504
|
aperture: Aperture,
|
|
505
505
|
backlight: DualBacklight,
|
|
506
506
|
beamstop: Beamstop,
|
|
507
|
-
detector_stage:
|
|
507
|
+
detector_stage: YZStage,
|
|
508
508
|
shutter: HutchShutter,
|
|
509
509
|
dcm: DCM,
|
|
510
510
|
mirrors: FocusMirrorsMode,
|
|
@@ -655,7 +655,7 @@ def run_fixed_target_plan(
|
|
|
655
655
|
aperture: Aperture = inject("aperture"),
|
|
656
656
|
backlight: DualBacklight = inject("backlight"),
|
|
657
657
|
beamstop: Beamstop = inject("beamstop"),
|
|
658
|
-
detector_stage:
|
|
658
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
659
659
|
shutter: HutchShutter = inject("shutter"),
|
|
660
660
|
dcm: DCM = inject("dcm"),
|
|
661
661
|
mirrors: FocusMirrorsMode = inject("focus_mirrors"),
|
|
@@ -684,6 +684,38 @@ def run_fixed_target_plan(
|
|
|
684
684
|
# DCID instance - do not create yet
|
|
685
685
|
dcid = DCID(emit_errors=False, expt_params=parameters)
|
|
686
686
|
|
|
687
|
+
yield from run_plan_in_wrapper(
|
|
688
|
+
zebra,
|
|
689
|
+
pmac,
|
|
690
|
+
aperture,
|
|
691
|
+
backlight,
|
|
692
|
+
beamstop,
|
|
693
|
+
detector_stage,
|
|
694
|
+
shutter,
|
|
695
|
+
dcm,
|
|
696
|
+
mirrors,
|
|
697
|
+
beam_center_device,
|
|
698
|
+
parameters,
|
|
699
|
+
dcid,
|
|
700
|
+
pilatus_metadata,
|
|
701
|
+
)
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def run_plan_in_wrapper(
|
|
705
|
+
zebra: Zebra,
|
|
706
|
+
pmac: PMAC,
|
|
707
|
+
aperture: Aperture,
|
|
708
|
+
backlight: DualBacklight,
|
|
709
|
+
beamstop: Beamstop,
|
|
710
|
+
detector_stage: YZStage,
|
|
711
|
+
shutter: HutchShutter,
|
|
712
|
+
dcm: DCM,
|
|
713
|
+
mirrors: FocusMirrorsMode,
|
|
714
|
+
beam_center_device: DetectorBeamCenter,
|
|
715
|
+
parameters: FixedTargetParameters,
|
|
716
|
+
dcid: DCID,
|
|
717
|
+
pilatus_metadata: PilatusMetadata,
|
|
718
|
+
) -> MsgGenerator:
|
|
687
719
|
yield from bpp.contingency_wrapper(
|
|
688
720
|
main_fixed_target_plan(
|
|
689
721
|
zebra,
|
|
@@ -16,8 +16,8 @@ from dodal.common import inject
|
|
|
16
16
|
from dodal.devices.attenuator.attenuator import ReadOnlyAttenuator
|
|
17
17
|
from dodal.devices.i24.beamstop import Beamstop, BeamstopPositions
|
|
18
18
|
from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
|
|
19
|
-
from dodal.devices.i24.i24_detector_motion import DetectorMotion
|
|
20
19
|
from dodal.devices.i24.pmac import PMAC, EncReset, LaserSettings
|
|
20
|
+
from dodal.devices.motors import YZStage
|
|
21
21
|
|
|
22
22
|
from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
|
|
23
23
|
ChipType,
|
|
@@ -121,14 +121,14 @@ def _is_checker_pattern() -> bool:
|
|
|
121
121
|
|
|
122
122
|
@log_on_entry
|
|
123
123
|
def read_parameters(
|
|
124
|
-
detector_stage:
|
|
124
|
+
detector_stage: YZStage,
|
|
125
125
|
attenuator: ReadOnlyAttenuator,
|
|
126
126
|
) -> MsgGenerator:
|
|
127
127
|
""" Read the parameters from user input and create the parameter model for a fixed \
|
|
128
128
|
target collection.
|
|
129
129
|
|
|
130
130
|
Args:
|
|
131
|
-
detector_stage (
|
|
131
|
+
detector_stage (YZStage): The detector stage device.
|
|
132
132
|
attenuator (ReadOnlyAttenuator): A read-only attenuator device to get the \
|
|
133
133
|
transmission value.
|
|
134
134
|
|
|
@@ -256,6 +256,7 @@ def upload_chip_map_to_geobrick(pmac: PMAC, chip_map: list[int]) -> MsgGenerator
|
|
|
256
256
|
"""
|
|
257
257
|
SSX_LOGGER.info("Uploading Parameters for Oxford Chip to the GeoBrick")
|
|
258
258
|
SSX_LOGGER.info(f"Chipid {ChipType.Oxford}, width {OXFORD_CHIP_WIDTH}")
|
|
259
|
+
SSX_LOGGER.warning(f"MAP TO UPLOAD: {chip_map}")
|
|
259
260
|
for block in range(1, 65):
|
|
260
261
|
value = 1 if block in chip_map else 0
|
|
261
262
|
pvar = PVAR_TEMPLATE % block
|
|
@@ -264,7 +265,7 @@ def upload_chip_map_to_geobrick(pmac: PMAC, chip_map: list[int]) -> MsgGenerator
|
|
|
264
265
|
yield from bps.abs_set(pmac.pmac_string, pvar_str, wait=True)
|
|
265
266
|
# Wait for PMAC to be done processing PVAR string
|
|
266
267
|
yield from bps.sleep(0.02)
|
|
267
|
-
SSX_LOGGER.
|
|
268
|
+
SSX_LOGGER.info("Upload parameters done.")
|
|
268
269
|
|
|
269
270
|
|
|
270
271
|
@log_on_entry
|
|
@@ -565,7 +566,7 @@ def moveto_preset(
|
|
|
565
566
|
pmac: PMAC = inject("pmac"),
|
|
566
567
|
beamstop: Beamstop = inject("beamstop"),
|
|
567
568
|
backlight: DualBacklight = inject("backlight"),
|
|
568
|
-
det_stage:
|
|
569
|
+
det_stage: YZStage = inject("detector_motion"),
|
|
569
570
|
) -> MsgGenerator:
|
|
570
571
|
# Non Chip Specific Move
|
|
571
572
|
if place == "zero":
|
|
@@ -7,7 +7,7 @@ from dodal.devices.i24.beam_center import DetectorBeamCenter
|
|
|
7
7
|
from dodal.devices.i24.beamstop import Beamstop, BeamstopPositions
|
|
8
8
|
from dodal.devices.i24.dcm import DCM
|
|
9
9
|
from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
|
|
10
|
-
from dodal.devices.
|
|
10
|
+
from dodal.devices.motors import YZStage
|
|
11
11
|
from dodal.devices.util.lookup_tables import (
|
|
12
12
|
linear_interpolation_lut,
|
|
13
13
|
parse_lookup_table,
|
|
@@ -69,7 +69,7 @@ def setup_beamline_for_collection_plan(
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
def move_detector_stage_to_position_plan(
|
|
72
|
-
detector_stage:
|
|
72
|
+
detector_stage: YZStage,
|
|
73
73
|
detector_distance: float,
|
|
74
74
|
):
|
|
75
75
|
SSX_LOGGER.debug("Setup beamline: moving detector stage.")
|
|
@@ -8,7 +8,7 @@ from enum import IntEnum
|
|
|
8
8
|
import bluesky.plan_stubs as bps
|
|
9
9
|
from bluesky.utils import Msg, MsgGenerator
|
|
10
10
|
from dodal.common import inject
|
|
11
|
-
from dodal.devices.
|
|
11
|
+
from dodal.devices.motors import YZStage
|
|
12
12
|
|
|
13
13
|
from mx_bluesky.beamlines.i24.serial.log import SSX_LOGGER
|
|
14
14
|
from mx_bluesky.beamlines.i24.serial.parameters import SSXType
|
|
@@ -38,9 +38,9 @@ class UnknownDetectorType(Exception):
|
|
|
38
38
|
pass
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def get_detector_type(detector_stage:
|
|
41
|
+
def get_detector_type(detector_stage: YZStage) -> Generator[Msg, None, Detector]:
|
|
42
42
|
det_y = yield from bps.rd(detector_stage.y)
|
|
43
|
-
#
|
|
43
|
+
# YZStage should also be used for this.
|
|
44
44
|
# This should be part of https://github.com/DiamondLightSource/mx_bluesky/issues/51
|
|
45
45
|
if float(det_y) < Eiger.det_y_threshold:
|
|
46
46
|
SSX_LOGGER.info("Eiger detector in use.")
|
|
@@ -53,7 +53,7 @@ def get_detector_type(detector_stage: DetectorMotion) -> Generator[Msg, None, De
|
|
|
53
53
|
raise UnknownDetectorType("Detector not found.")
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def _move_detector_stage(detector_stage:
|
|
56
|
+
def _move_detector_stage(detector_stage: YZStage, target: float) -> MsgGenerator:
|
|
57
57
|
SSX_LOGGER.info(f"Moving detector stage to target position: {target}.")
|
|
58
58
|
yield from bps.mv(detector_stage.y, target)
|
|
59
59
|
|
|
@@ -82,7 +82,7 @@ def _get_requested_detector(det_type_pv: str) -> str:
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
def setup_detector_stage(
|
|
85
|
-
expt_type: SSXType, detector_stage:
|
|
85
|
+
expt_type: SSXType, detector_stage: YZStage = inject("detector_motion")
|
|
86
86
|
) -> MsgGenerator:
|
|
87
87
|
# Grab the correct PV depending on experiment
|
|
88
88
|
# Its value is set with MUX on edm screen
|
|
@@ -3,19 +3,34 @@ from typing import Literal
|
|
|
3
3
|
|
|
4
4
|
import bluesky.plan_stubs as bps
|
|
5
5
|
import bluesky.preprocessors as bpp
|
|
6
|
-
from
|
|
6
|
+
from bluesky.utils import MsgGenerator
|
|
7
7
|
from dodal.beamlines import i24
|
|
8
8
|
from dodal.common import inject
|
|
9
|
+
from dodal.devices.hutch_shutter import HutchShutter
|
|
10
|
+
from dodal.devices.i24.aperture import Aperture
|
|
11
|
+
from dodal.devices.i24.beam_center import DetectorBeamCenter
|
|
12
|
+
from dodal.devices.i24.beamstop import Beamstop
|
|
13
|
+
from dodal.devices.i24.dcm import DCM
|
|
9
14
|
from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
|
|
10
|
-
from dodal.devices.i24.
|
|
15
|
+
from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
|
|
16
|
+
from dodal.devices.i24.pilatus_metadata import PilatusMetadata
|
|
11
17
|
from dodal.devices.i24.pmac import PMAC
|
|
12
|
-
from dodal.devices.
|
|
18
|
+
from dodal.devices.motors import YZStage
|
|
19
|
+
from dodal.devices.oav.oav_detector import OAVBeamCentreFile
|
|
20
|
+
from dodal.devices.zebra.zebra import Zebra
|
|
13
21
|
|
|
22
|
+
from mx_bluesky.beamlines.i24.serial.dcid import DCID
|
|
14
23
|
from mx_bluesky.beamlines.i24.serial.fixed_target.ft_utils import (
|
|
15
24
|
ChipType,
|
|
16
25
|
MappingType,
|
|
17
26
|
PumpProbeSetting,
|
|
18
27
|
)
|
|
28
|
+
from mx_bluesky.beamlines.i24.serial.fixed_target.i24ssx_Chip_Collect_py3v1 import (
|
|
29
|
+
run_plan_in_wrapper,
|
|
30
|
+
)
|
|
31
|
+
from mx_bluesky.beamlines.i24.serial.fixed_target.i24ssx_Chip_Manager_py3v1 import (
|
|
32
|
+
upload_chip_map_to_geobrick,
|
|
33
|
+
)
|
|
19
34
|
from mx_bluesky.beamlines.i24.serial.fixed_target.i24ssx_moveonclick import (
|
|
20
35
|
_move_on_mouse_click_plan,
|
|
21
36
|
)
|
|
@@ -24,6 +39,7 @@ from mx_bluesky.beamlines.i24.serial.log import (
|
|
|
24
39
|
_read_visit_directory_from_file,
|
|
25
40
|
)
|
|
26
41
|
from mx_bluesky.beamlines.i24.serial.parameters import (
|
|
42
|
+
DetectorName,
|
|
27
43
|
FixedTargetParameters,
|
|
28
44
|
get_chip_format,
|
|
29
45
|
)
|
|
@@ -46,9 +62,19 @@ def gui_move_backlight(
|
|
|
46
62
|
SSX_LOGGER.debug(f"Backlight moved to {bl_pos.value}")
|
|
47
63
|
|
|
48
64
|
|
|
65
|
+
@bpp.run_decorator()
|
|
66
|
+
def gui_set_zoom_level(
|
|
67
|
+
position: str, oav: OAVBeamCentreFile = inject("oav")
|
|
68
|
+
) -> MsgGenerator:
|
|
69
|
+
yield from bps.abs_set(oav.zoom_controller, position, wait=True)
|
|
70
|
+
SSX_LOGGER.debug(f"Setting zoom level to {position}")
|
|
71
|
+
|
|
72
|
+
|
|
49
73
|
@bpp.run_decorator()
|
|
50
74
|
def gui_stage_move_on_click(
|
|
51
|
-
position_px: tuple[int, int],
|
|
75
|
+
position_px: tuple[int, int],
|
|
76
|
+
oav: OAVBeamCentreFile = inject("oav"),
|
|
77
|
+
pmac: PMAC = inject("pmac"),
|
|
52
78
|
) -> MsgGenerator:
|
|
53
79
|
yield from _move_on_mouse_click_plan(oav, pmac, position_px)
|
|
54
80
|
|
|
@@ -78,7 +104,7 @@ def gui_sleep(sec: int) -> MsgGenerator:
|
|
|
78
104
|
@bpp.run_decorator()
|
|
79
105
|
def gui_move_detector(
|
|
80
106
|
det: Literal["eiger", "pilatus"],
|
|
81
|
-
detector_stage:
|
|
107
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
82
108
|
) -> MsgGenerator:
|
|
83
109
|
det_y_target = Eiger.det_y_target if det == "eiger" else Pilatus.det_y_target
|
|
84
110
|
yield from _move_detector_stage(detector_stage, det_y_target)
|
|
@@ -88,7 +114,7 @@ def gui_move_detector(
|
|
|
88
114
|
|
|
89
115
|
|
|
90
116
|
@bpp.run_decorator()
|
|
91
|
-
def
|
|
117
|
+
def gui_run_chip_collection(
|
|
92
118
|
sub_dir: str,
|
|
93
119
|
chip_name: str,
|
|
94
120
|
exp_time: float,
|
|
@@ -103,6 +129,18 @@ def gui_set_parameters(
|
|
|
103
129
|
laser_dwell: float,
|
|
104
130
|
laser_delay: float,
|
|
105
131
|
pre_pump: float,
|
|
132
|
+
pmac: PMAC = inject("pmac"),
|
|
133
|
+
zebra: Zebra = inject("zebra"),
|
|
134
|
+
aperture: Aperture = inject("aperture"),
|
|
135
|
+
backlight: DualBacklight = inject("backlight"),
|
|
136
|
+
beamstop: Beamstop = inject("beamstop"),
|
|
137
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
138
|
+
shutter: HutchShutter = inject("shutter"),
|
|
139
|
+
dcm: DCM = inject("dcm"),
|
|
140
|
+
mirrors: FocusMirrorsMode = inject("focus_mirrors"),
|
|
141
|
+
beam_center_pilatus: DetectorBeamCenter = inject("pilatus_bc"),
|
|
142
|
+
beam_center_eiger: DetectorBeamCenter = inject("eiger_bc"),
|
|
143
|
+
pilatus_metadata: PilatusMetadata = inject("pilatus_meta"),
|
|
106
144
|
) -> MsgGenerator:
|
|
107
145
|
"""Set the parameter model for the data collection.
|
|
108
146
|
|
|
@@ -132,7 +170,6 @@ def gui_set_parameters(
|
|
|
132
170
|
"""
|
|
133
171
|
# NOTE still a work in progress, adding to it as the ui grows
|
|
134
172
|
# See progression of https://github.com/DiamondLightSource/mx-daq-ui/issues/3
|
|
135
|
-
detector_stage = i24.detector_motion()
|
|
136
173
|
det_type = yield from get_detector_type(detector_stage)
|
|
137
174
|
_format = chip_format if ChipType[chip_type] is ChipType.Custom else None
|
|
138
175
|
chip_params = get_chip_format(ChipType[chip_type], _format)
|
|
@@ -164,6 +201,38 @@ def gui_set_parameters(
|
|
|
164
201
|
"checker_pattern": checker_pattern,
|
|
165
202
|
"pre_pump_exposure_s": pre_pump,
|
|
166
203
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
204
|
+
|
|
205
|
+
parameters = FixedTargetParameters(**params)
|
|
206
|
+
|
|
207
|
+
# Create collection directory
|
|
208
|
+
parameters.collection_directory.mkdir(parents=True, exist_ok=True)
|
|
209
|
+
|
|
210
|
+
if parameters.chip_map:
|
|
211
|
+
yield from upload_chip_map_to_geobrick(pmac, parameters.chip_map)
|
|
212
|
+
|
|
213
|
+
beam_center_device = (
|
|
214
|
+
beam_center_eiger
|
|
215
|
+
if parameters.detector_name is DetectorName.EIGER
|
|
216
|
+
else beam_center_pilatus
|
|
217
|
+
)
|
|
218
|
+
SSX_LOGGER.info("Beam center device ready")
|
|
219
|
+
|
|
220
|
+
# DCID instance - do not create yet
|
|
221
|
+
dcid = DCID(emit_errors=False, expt_params=parameters) # noqa
|
|
222
|
+
SSX_LOGGER.info("DCID created")
|
|
223
|
+
|
|
224
|
+
yield from run_plan_in_wrapper(
|
|
225
|
+
zebra,
|
|
226
|
+
pmac,
|
|
227
|
+
aperture,
|
|
228
|
+
backlight,
|
|
229
|
+
beamstop,
|
|
230
|
+
detector_stage,
|
|
231
|
+
shutter,
|
|
232
|
+
dcm,
|
|
233
|
+
mirrors,
|
|
234
|
+
beam_center_device,
|
|
235
|
+
parameters,
|
|
236
|
+
dcid,
|
|
237
|
+
pilatus_metadata,
|
|
238
|
+
)
|
|
@@ -10,6 +10,7 @@ from dodal.devices.detector.detector_motion import DetectorMotion
|
|
|
10
10
|
from dodal.devices.smargon import CombinedMove, Smargon
|
|
11
11
|
|
|
12
12
|
from mx_bluesky.common.utils.log import LOGGER
|
|
13
|
+
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
13
14
|
|
|
14
15
|
LOWER_DETECTOR_SHUTTER_AFTER_SCAN = True
|
|
15
16
|
|
|
@@ -21,6 +22,8 @@ def setup_sample_environment(
|
|
|
21
22
|
group="setup_senv",
|
|
22
23
|
):
|
|
23
24
|
"""Move the aperture into required position, move out the backlight."""
|
|
25
|
+
yield from bps.abs_set(backlight, BacklightPosition.OUT, group=group)
|
|
26
|
+
|
|
24
27
|
aperture_value = (
|
|
25
28
|
None
|
|
26
29
|
if not aperture_position_gda_name
|
|
@@ -29,7 +32,6 @@ def setup_sample_environment(
|
|
|
29
32
|
yield from move_aperture_if_required(
|
|
30
33
|
aperture_scatterguard, aperture_value, group=group
|
|
31
34
|
)
|
|
32
|
-
yield from bps.abs_set(backlight, BacklightPosition.OUT, group=group)
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
def move_aperture_if_required(
|
|
@@ -46,6 +48,7 @@ def move_aperture_if_required(
|
|
|
46
48
|
|
|
47
49
|
else:
|
|
48
50
|
LOGGER.info(f"Setting aperture position to {aperture_value}")
|
|
51
|
+
yield from bps.wait(CONST.WAIT.PREPARE_APERTURE)
|
|
49
52
|
yield from bps.abs_set(
|
|
50
53
|
aperture_scatterguard.selected_aperture,
|
|
51
54
|
aperture_value,
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import bluesky.plan_stubs as bps
|
|
4
|
+
import bluesky.preprocessors as bpp
|
|
5
|
+
from bluesky.utils import MsgGenerator
|
|
6
|
+
from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
|
|
7
|
+
from dodal.devices.motors import XYZStage
|
|
8
|
+
from dodal.devices.robot import BartRobot
|
|
9
|
+
from dodal.devices.smargon import CombinedMove, Smargon, StubPosition
|
|
10
|
+
from dodal.plan_stubs.motor_utils import MoveTooLarge, home_and_reset_wrapper
|
|
11
|
+
|
|
12
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
13
|
+
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def wait_for_smargon_not_disabled(smargon: Smargon, timeout=60):
|
|
17
|
+
"""Waits for the smargon disabled flag to go low. The robot hardware is responsible
|
|
18
|
+
for setting this to low when it is safe to move. It does this through a physical
|
|
19
|
+
connection between the robot and the smargon.
|
|
20
|
+
"""
|
|
21
|
+
LOGGER.info("Waiting for smargon enabled")
|
|
22
|
+
SLEEP_PER_CHECK = 0.1
|
|
23
|
+
times_to_check = int(timeout / SLEEP_PER_CHECK)
|
|
24
|
+
for _ in range(times_to_check):
|
|
25
|
+
smargon_disabled = yield from bps.rd(smargon.disabled)
|
|
26
|
+
if not smargon_disabled:
|
|
27
|
+
LOGGER.info("Smargon now enabled")
|
|
28
|
+
return
|
|
29
|
+
yield from bps.sleep(SLEEP_PER_CHECK)
|
|
30
|
+
raise TimeoutError(
|
|
31
|
+
"Timed out waiting for smargon to become enabled after robot load"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _raise_exception_if_moved_out_of_cryojet(exception):
|
|
36
|
+
yield from bps.null()
|
|
37
|
+
if isinstance(exception, MoveTooLarge):
|
|
38
|
+
raise Exception(
|
|
39
|
+
f"Moving {exception.axis} back to {exception.position} after \
|
|
40
|
+
robot load would move it out of the cryojet. The max safe \
|
|
41
|
+
distance is {exception.maximum_move}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def do_plan_while_lower_gonio_at_home(plan: MsgGenerator, lower_gonio: XYZStage):
|
|
46
|
+
"""Moves the lower gonio to home then performs the provided plan and moves it back.
|
|
47
|
+
|
|
48
|
+
The lower gonio must be in the correct position for the robot load and we
|
|
49
|
+
want to put it back afterwards. Note we don't need to wait for the move as the robot
|
|
50
|
+
is interlocked to the lower gonio and the move is quicker than the robot takes to
|
|
51
|
+
get to the load position.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
plan (MsgGenerator): The plan to run while the lower gonio is at home.
|
|
55
|
+
lower_gonio (XYZStage): The lower gonio to home.
|
|
56
|
+
"""
|
|
57
|
+
yield from bpp.contingency_wrapper(
|
|
58
|
+
home_and_reset_wrapper(
|
|
59
|
+
plan,
|
|
60
|
+
lower_gonio,
|
|
61
|
+
BartRobot.LOAD_TOLERANCE_MM,
|
|
62
|
+
CONST.HARDWARE.CRYOJET_MARGIN_MM,
|
|
63
|
+
"lower_gonio",
|
|
64
|
+
wait_for_all=False,
|
|
65
|
+
),
|
|
66
|
+
except_plan=_raise_exception_if_moved_out_of_cryojet,
|
|
67
|
+
)
|
|
68
|
+
return "reset-lower_gonio"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def prepare_for_robot_load(
|
|
72
|
+
aperture_scatterguard: ApertureScatterguard, smargon: Smargon
|
|
73
|
+
):
|
|
74
|
+
yield from bps.abs_set(
|
|
75
|
+
aperture_scatterguard.selected_aperture,
|
|
76
|
+
ApertureValue.OUT_OF_BEAM,
|
|
77
|
+
group="prepare_robot_load",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
yield from bps.mv(smargon.stub_offsets, StubPosition.RESET_TO_ROBOT_LOAD)
|
|
81
|
+
|
|
82
|
+
yield from bps.mv(smargon, CombinedMove(x=0, y=0, z=0, chi=0, phi=0, omega=0))
|
|
83
|
+
|
|
84
|
+
yield from bps.wait("prepare_robot_load")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def robot_unload(
|
|
88
|
+
robot: BartRobot,
|
|
89
|
+
smargon: Smargon,
|
|
90
|
+
aperture_scatterguard: ApertureScatterguard,
|
|
91
|
+
lower_gonio: XYZStage,
|
|
92
|
+
visit: str,
|
|
93
|
+
):
|
|
94
|
+
"""Unloads the currently mounted pin into the location that it was loaded from. The
|
|
95
|
+
loaded location is stored on the robot and so need not be provided.
|
|
96
|
+
"""
|
|
97
|
+
yield from prepare_for_robot_load(aperture_scatterguard, smargon)
|
|
98
|
+
sample_id = yield from bps.rd(robot.sample_id)
|
|
99
|
+
|
|
100
|
+
@bpp.run_decorator(
|
|
101
|
+
md={
|
|
102
|
+
"subplan_name": CONST.PLAN.ROBOT_UNLOAD,
|
|
103
|
+
"metadata": {"visit": visit, "sample_id": sample_id},
|
|
104
|
+
"activate_callbacks": [
|
|
105
|
+
"RobotLoadISPyBCallback",
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
)
|
|
109
|
+
def do_robot_unload_and_send_to_ispyb():
|
|
110
|
+
yield from bps.create(name=CONST.DESCRIPTORS.ROBOT_UPDATE)
|
|
111
|
+
yield from bps.read(robot)
|
|
112
|
+
yield from bps.save()
|
|
113
|
+
|
|
114
|
+
def _unload():
|
|
115
|
+
yield from bps.trigger(robot.unload, wait=True)
|
|
116
|
+
yield from wait_for_smargon_not_disabled(smargon)
|
|
117
|
+
|
|
118
|
+
gonio_finished = yield from do_plan_while_lower_gonio_at_home(
|
|
119
|
+
_unload(), lower_gonio
|
|
120
|
+
)
|
|
121
|
+
yield from bps.wait(gonio_finished)
|
|
122
|
+
|
|
123
|
+
yield from do_robot_unload_and_send_to_ispyb()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from collections.abc import Generator
|
|
2
|
+
|
|
3
|
+
from bluesky import plan_stubs as bps
|
|
4
|
+
from bluesky import preprocessors as bpp
|
|
5
|
+
from bluesky.utils import Msg
|
|
6
|
+
from dodal.devices.detector.detector_motion import DetectorMotion, ShutterState
|
|
7
|
+
from dodal.devices.eiger import EigerDetector
|
|
8
|
+
from dodal.devices.mx_phase1.beamstop import Beamstop, BeamstopPositions
|
|
9
|
+
|
|
10
|
+
from mx_bluesky.common.device_setup_plans.position_detector import (
|
|
11
|
+
set_detector_z_position,
|
|
12
|
+
set_shutter,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def start_preparing_data_collection_then_do_plan(
|
|
17
|
+
beamstop: Beamstop,
|
|
18
|
+
eiger: EigerDetector,
|
|
19
|
+
detector_motion: DetectorMotion,
|
|
20
|
+
detector_distance_mm: float | None,
|
|
21
|
+
plan_to_run: Generator[Msg, None, None],
|
|
22
|
+
group="ready_for_data_collection",
|
|
23
|
+
) -> Generator[Msg, None, None]:
|
|
24
|
+
"""Starts preparing for the next data collection and then runs the
|
|
25
|
+
given plan.
|
|
26
|
+
|
|
27
|
+
Preparation consists of:
|
|
28
|
+
* Arming the Eiger
|
|
29
|
+
* Moving the detector to the specified position
|
|
30
|
+
* Opening the detect shutter
|
|
31
|
+
If the plan fails it will disarm the eiger.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def wrapped_plan():
|
|
35
|
+
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)
|
|
36
|
+
yield from bps.abs_set(
|
|
37
|
+
beamstop.selected_pos, BeamstopPositions.DATA_COLLECTION, group=group
|
|
38
|
+
)
|
|
39
|
+
if detector_distance_mm:
|
|
40
|
+
yield from set_detector_z_position(
|
|
41
|
+
detector_motion, detector_distance_mm, group
|
|
42
|
+
)
|
|
43
|
+
yield from set_shutter(detector_motion, ShutterState.OPEN, group)
|
|
44
|
+
yield from plan_to_run
|
|
45
|
+
|
|
46
|
+
yield from bpp.contingency_wrapper(
|
|
47
|
+
wrapped_plan(),
|
|
48
|
+
except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
49
|
+
)
|