mx-bluesky 1.5.10__py3-none-any.whl → 1.5.12__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/experiment_plans/__init__.py +0 -0
- mx_bluesky/beamlines/aithre_lasershaping/experiment_plans/robot_load_plan.py +198 -0
- mx_bluesky/beamlines/aithre_lasershaping/goniometer_controls.py +2 -2
- mx_bluesky/beamlines/aithre_lasershaping/parameters/__init__.py +0 -0
- mx_bluesky/beamlines/aithre_lasershaping/parameters/constants.py +17 -0
- mx_bluesky/beamlines/aithre_lasershaping/parameters/robot_load_parameters.py +13 -0
- mx_bluesky/beamlines/aithre_lasershaping/pin_tip_centring.py +31 -0
- mx_bluesky/beamlines/aithre_lasershaping/robot_load.py +80 -0
- mx_bluesky/beamlines/i02_1/parameters/gridscan.py +1 -1
- mx_bluesky/beamlines/i04/__init__.py +6 -2
- mx_bluesky/beamlines/i04/callbacks/murko_callback.py +27 -12
- mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py +94 -20
- mx_bluesky/beamlines/i04/external_interaction/__init__.py +0 -0
- mx_bluesky/beamlines/i04/external_interaction/config_server.py +15 -0
- mx_bluesky/beamlines/i04/oav_centering_plans/__init__.py +0 -0
- mx_bluesky/beamlines/i04/oav_centering_plans/oav_imaging.py +115 -0
- mx_bluesky/beamlines/i04/parameters/__init__.py +0 -0
- mx_bluesky/beamlines/i04/parameters/constants.py +21 -0
- mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +24 -1
- mx_bluesky/beamlines/i04/thawing_plan.py +149 -154
- mx_bluesky/beamlines/i24/jungfrau_commissioning/experiment_plans/do_darks.py +55 -10
- mx_bluesky/beamlines/i24/jungfrau_commissioning/plan_stubs/do_external_acquisition.py +1 -1
- mx_bluesky/beamlines/i24/jungfrau_commissioning/plan_stubs/plan_utils.py +1 -1
- mx_bluesky/beamlines/i24/serial/__init__.py +7 -5
- mx_bluesky/beamlines/i24/serial/dcid.py +6 -7
- mx_bluesky/beamlines/i24/serial/extruder/{i24ssx_Extruder_Collect_py3v2.py → i24ssx_extruder_collect_py3v2.py} +70 -37
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/CustomChip_py3v1.edl +11 -11
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DetStage.edl +3 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +142 -142
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +135 -135
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/PMAC_Command.edl +8 -8
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +13 -13
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_Collect_py3v1.py → i24ssx_chip_collect_py3v1.py} +12 -9
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_Manager_py3v1.py → i24ssx_chip_manager_py3v1.py} +81 -78
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_StartUp_py3v1.py → i24ssx_chip_startup_py3v1.py} +3 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +33 -33
- mx_bluesky/beamlines/i24/serial/log.py +11 -11
- mx_bluesky/beamlines/i24/serial/parameters/fixed_target/cs/cs_maker.json +3 -3
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +5 -5
- mx_bluesky/beamlines/i24/serial/setup_beamline/ca.py +0 -12
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +122 -334
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv_abstract.py +5 -5
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +30 -251
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +3 -3
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +4 -4
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +103 -16
- mx_bluesky/beamlines/i24/serial/web_gui_plans/oav_plans.py +64 -0
- mx_bluesky/beamlines/i24/serial/write_nexus.py +4 -4
- mx_bluesky/common/device_setup_plans/gonio.py +28 -0
- mx_bluesky/common/device_setup_plans/manipulate_sample.py +8 -1
- mx_bluesky/common/device_setup_plans/robot_load_unload.py +1 -1
- mx_bluesky/common/device_setup_plans/setup_oav.py +8 -0
- mx_bluesky/common/device_setup_plans/setup_zebra_and_shutter.py +0 -5
- mx_bluesky/common/device_setup_plans/xbpm_feedback.py +8 -1
- mx_bluesky/common/experiment_plans/beamstop_check.py +229 -0
- mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py +8 -6
- mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py +2 -2
- mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py +1 -1
- mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py +7 -4
- mx_bluesky/common/experiment_plans/inner_plans/write_sample_status.py +2 -2
- mx_bluesky/common/experiment_plans/oav_snapshot_plan.py +1 -2
- mx_bluesky/{hyperion → common}/experiment_plans/pin_tip_centring_plan.py +23 -24
- mx_bluesky/common/external_interaction/callbacks/common/grid_detection_callback.py +5 -0
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +13 -15
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_mapping.py +3 -5
- mx_bluesky/common/external_interaction/callbacks/common/plan_reactive_callback.py +1 -1
- mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py +2 -2
- mx_bluesky/common/external_interaction/callbacks/sample_handling/sample_handling_callback.py +3 -3
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +12 -10
- mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py +2 -2
- mx_bluesky/common/external_interaction/config_server.py +4 -4
- mx_bluesky/common/external_interaction/ispyb/data_model.py +11 -4
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +163 -4
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +76 -167
- mx_bluesky/common/external_interaction/ispyb/ispyb_utils.py +0 -14
- mx_bluesky/common/external_interaction/nexus/nexus_utils.py +2 -2
- mx_bluesky/common/external_interaction/nexus/write_nexus.py +3 -3
- mx_bluesky/common/parameters/components.py +1 -0
- mx_bluesky/common/parameters/constants.py +4 -3
- mx_bluesky/common/parameters/device_composites.py +4 -2
- mx_bluesky/common/parameters/gridscan.py +2 -2
- mx_bluesky/common/utils/exceptions.py +24 -7
- mx_bluesky/common/utils/log.py +13 -4
- mx_bluesky/common/utils/tracing.py +5 -5
- mx_bluesky/common/utils/utils.py +56 -8
- mx_bluesky/hyperion/__main__.py +6 -16
- mx_bluesky/hyperion/baton_handler.py +38 -14
- mx_bluesky/hyperion/device_setup_plans/utils.py +1 -1
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +1 -1
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +15 -13
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +9 -9
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +7 -8
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +3 -10
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +4 -2
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +10 -4
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/udc_default_state.py +160 -0
- mx_bluesky/hyperion/external_interaction/agamemnon.py +3 -3
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +2 -2
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +3 -3
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -0
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +3 -6
- mx_bluesky/hyperion/external_interaction/config_server.py +5 -5
- mx_bluesky/hyperion/parameters/constants.py +11 -4
- mx_bluesky/hyperion/parameters/device_composites.py +2 -2
- mx_bluesky/hyperion/parameters/gridscan.py +4 -4
- mx_bluesky/hyperion/parameters/robot_load.py +1 -9
- mx_bluesky/hyperion/plan_runner.py +6 -6
- mx_bluesky/hyperion/runner.py +10 -8
- mx_bluesky/jupyter_example.ipynb +3 -3
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/METADATA +9 -7
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/RECORD +118 -104
- mx_bluesky/common/experiment_plans/inner_plans/udc_default_state.py +0 -65
- mx_bluesky/common/external_interaction/callbacks/common/logging_callback.py +0 -29
- mx_bluesky/hyperion/device_setup_plans/smargon.py +0 -25
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/WHEEL +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.12.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from functools import partial
|
|
3
|
-
|
|
4
1
|
import bluesky.plan_stubs as bps
|
|
5
2
|
import bluesky.preprocessors as bpp
|
|
6
|
-
from bluesky.preprocessors import run_decorator, subs_decorator
|
|
3
|
+
from bluesky.preprocessors import contingency_decorator, run_decorator, subs_decorator
|
|
7
4
|
from bluesky.utils import MsgGenerator
|
|
8
5
|
from dodal.common import inject
|
|
9
6
|
from dodal.devices.i04.constants import RedisConstants
|
|
10
7
|
from dodal.devices.i04.murko_results import MurkoResultsDevice
|
|
11
|
-
from dodal.devices.oav.oav_detector import OAV
|
|
12
8
|
from dodal.devices.oav.oav_to_redis_forwarder import OAVToRedisForwarder, Source
|
|
13
9
|
from dodal.devices.robot import BartRobot
|
|
14
10
|
from dodal.devices.smargon import Smargon
|
|
15
11
|
from dodal.devices.thawer import OnOff, Thawer
|
|
12
|
+
from dodal.log import LOGGER
|
|
16
13
|
|
|
17
14
|
from mx_bluesky.beamlines.i04.callbacks.murko_callback import MurkoCallback
|
|
18
15
|
|
|
@@ -29,53 +26,26 @@ def thaw(
|
|
|
29
26
|
|
|
30
27
|
Args:
|
|
31
28
|
time_to_thaw (float): Time to thaw for, in seconds.
|
|
32
|
-
rotation (float
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
defaults are always correct.
|
|
29
|
+
rotation (float): How much to rotate by whilst thawing, in degrees.
|
|
30
|
+
thawer (Thawer): The thawing device.
|
|
31
|
+
smargon (Smargon): The smargon used to rotate.
|
|
36
32
|
"""
|
|
37
|
-
yield from
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def thaw_and_stream_to_redis(
|
|
41
|
-
time_to_thaw: float,
|
|
42
|
-
rotation: float = 360,
|
|
43
|
-
robot: BartRobot = inject("robot"),
|
|
44
|
-
thawer: Thawer = inject("thawer"),
|
|
45
|
-
smargon: Smargon = inject("smargon"),
|
|
46
|
-
oav: OAV = inject("oav_full_screen"),
|
|
47
|
-
oav_to_redis_forwarder: OAVToRedisForwarder = inject("oav_to_redis_forwarder"),
|
|
48
|
-
) -> MsgGenerator:
|
|
49
|
-
"""Turns on the thawer and rotates the sample by {rotation} degrees to thaw it, then
|
|
50
|
-
rotates {rotation} degrees back and turns the thawer off. The speed of the goniometer
|
|
51
|
-
is set such that the process takes whole process will take {time_to_thaw} time.
|
|
33
|
+
initial_velocity = yield from bps.rd(smargon.omega.velocity)
|
|
34
|
+
new_velocity = abs(rotation / time_to_thaw) * 2.0
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
36
|
+
def do_thaw():
|
|
37
|
+
yield from bps.abs_set(smargon.omega.velocity, new_velocity, wait=True)
|
|
38
|
+
yield from bps.abs_set(thawer, OnOff.ON, wait=True)
|
|
39
|
+
yield from bps.rel_set(smargon.omega, rotation, wait=True)
|
|
40
|
+
yield from bps.rel_set(smargon.omega, -rotation, wait=True)
|
|
56
41
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Defaults to 360.
|
|
61
|
-
... devices: These are the specific ophyd-devices used for the plan, the
|
|
62
|
-
defaults are always correct
|
|
63
|
-
"""
|
|
42
|
+
def cleanup():
|
|
43
|
+
yield from bps.abs_set(smargon.omega.velocity, initial_velocity, wait=True)
|
|
44
|
+
yield from bps.abs_set(thawer, OnOff.OFF, wait=True)
|
|
64
45
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
yield from bps.kickoff(oav_to_redis_forwarder, wait=True)
|
|
69
|
-
|
|
70
|
-
yield from _thaw_and_stream_to_redis(
|
|
71
|
-
time_to_thaw,
|
|
72
|
-
rotation,
|
|
73
|
-
robot,
|
|
74
|
-
thawer,
|
|
75
|
-
smargon,
|
|
76
|
-
oav,
|
|
77
|
-
oav_to_redis_forwarder,
|
|
78
|
-
switch_forwarder_to_ROI,
|
|
46
|
+
yield from bpp.contingency_wrapper(
|
|
47
|
+
do_thaw(),
|
|
48
|
+
final_plan=cleanup,
|
|
79
49
|
)
|
|
80
50
|
|
|
81
51
|
|
|
@@ -85,14 +55,13 @@ def thaw_and_murko_centre(
|
|
|
85
55
|
robot: BartRobot = inject("robot"),
|
|
86
56
|
thawer: Thawer = inject("thawer"),
|
|
87
57
|
smargon: Smargon = inject("smargon"),
|
|
88
|
-
oav: OAV = inject("oav_full_screen"),
|
|
89
58
|
murko_results: MurkoResultsDevice = inject("murko_results"),
|
|
90
59
|
oav_to_redis_forwarder: OAVToRedisForwarder = inject("oav_to_redis_forwarder"),
|
|
91
60
|
) -> MsgGenerator:
|
|
92
61
|
"""Thaws the sample and centres it using murko by:
|
|
93
62
|
1. Turns on the thawer
|
|
94
63
|
2. Rotates the sample by {rotation} degrees, whilst this is happening images from
|
|
95
|
-
the
|
|
64
|
+
the full screen OAV are being fed to murko
|
|
96
65
|
3. After the rotation has completed moves to the average centre returned by murko
|
|
97
66
|
from these images
|
|
98
67
|
4. Rotate {rotation} degrees back to the start, whilst this is happening images
|
|
@@ -109,147 +78,173 @@ def thaw_and_murko_centre(
|
|
|
109
78
|
... devices: These are the specific ophyd-devices used for the plan, the
|
|
110
79
|
defaults are always correct
|
|
111
80
|
"""
|
|
81
|
+
murko_results_group = "get_results"
|
|
112
82
|
|
|
113
|
-
|
|
83
|
+
sample_id = yield from bps.rd(robot.sample_id)
|
|
84
|
+
sample_id = int(sample_id)
|
|
114
85
|
|
|
115
|
-
|
|
116
|
-
yield from bps.complete(oav_to_redis_forwarder, wait=True)
|
|
86
|
+
oav_fs = oav_to_redis_forwarder.sources[Source.FULL_SCREEN].oav_ref()
|
|
117
87
|
|
|
118
|
-
|
|
88
|
+
initial_zoom_level = yield from bps.rd(oav_fs.zoom_controller.level)
|
|
89
|
+
initial_velocity = yield from bps.rd(smargon.omega.velocity)
|
|
90
|
+
new_velocity = abs(rotation / time_to_thaw) * 2.0
|
|
91
|
+
murko_callback = MurkoCallback(
|
|
92
|
+
RedisConstants.REDIS_HOST,
|
|
93
|
+
RedisConstants.REDIS_PASSWORD,
|
|
94
|
+
RedisConstants.MURKO_REDIS_DB,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def cleanup():
|
|
98
|
+
yield from bps.mv(oav_fs.zoom_controller.level, initial_zoom_level)
|
|
99
|
+
yield from bps.abs_set(smargon.omega.velocity, initial_velocity, wait=True)
|
|
100
|
+
yield from bps.abs_set(thawer, OnOff.OFF, wait=True)
|
|
101
|
+
|
|
102
|
+
def centre_from_murko():
|
|
103
|
+
yield from bps.wait(murko_results_group)
|
|
119
104
|
|
|
120
|
-
yield from bps.wait(MURKO_RESULTS_GROUP)
|
|
121
105
|
x_predict = yield from bps.rd(murko_results.x_mm)
|
|
122
106
|
y_predict = yield from bps.rd(murko_results.y_mm)
|
|
123
107
|
z_predict = yield from bps.rd(murko_results.z_mm)
|
|
124
108
|
|
|
109
|
+
LOGGER.info(f"Got results: {x_predict, y_predict, z_predict}")
|
|
110
|
+
|
|
125
111
|
yield from bps.rel_set(smargon.x, x_predict)
|
|
126
112
|
yield from bps.rel_set(smargon.y, y_predict)
|
|
127
113
|
yield from bps.rel_set(smargon.z, z_predict)
|
|
128
114
|
|
|
129
|
-
|
|
115
|
+
@subs_decorator(murko_callback)
|
|
116
|
+
@contingency_decorator(final_plan=cleanup)
|
|
117
|
+
def do_thaw_and_murko_centre():
|
|
118
|
+
yield from bps.mv(
|
|
119
|
+
murko_results.sample_id,
|
|
120
|
+
str(sample_id),
|
|
121
|
+
oav_to_redis_forwarder.sample_id,
|
|
122
|
+
sample_id,
|
|
123
|
+
oav_fs.zoom_controller.level,
|
|
124
|
+
"1.0x",
|
|
125
|
+
)
|
|
126
|
+
yield from bps.abs_set(smargon.omega.velocity, new_velocity, wait=True)
|
|
127
|
+
yield from bps.abs_set(thawer, OnOff.ON, wait=True)
|
|
128
|
+
|
|
129
|
+
def rotate_in_one_direction_then_murko_centre(
|
|
130
|
+
rotation: float, oav_mode: Source
|
|
131
|
+
):
|
|
132
|
+
@run_decorator(md={"sample_id": sample_id})
|
|
133
|
+
def rotate_in_one_direction_and_start_murko_and_stream_to_redis():
|
|
134
|
+
yield from bps.stage(murko_results, wait=True)
|
|
135
|
+
yield from bps.trigger(murko_results, group=murko_results_group)
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
yield from _rotate_in_one_direction_and_stream_to_redis(
|
|
138
|
+
smargon, oav_to_redis_forwarder, oav_mode, rotation
|
|
139
|
+
)
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
yield from bps.trigger(murko_results, group=MURKO_RESULTS_GROUP)
|
|
141
|
+
yield from rotate_in_one_direction_and_start_murko_and_stream_to_redis()
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
oav,
|
|
145
|
-
oav_to_redis_forwarder,
|
|
146
|
-
centre_then_switch_forwarder_to_ROI,
|
|
147
|
-
),
|
|
148
|
-
final_plan=partial(bps.unstage, murko_results, wait=True),
|
|
149
|
-
)
|
|
143
|
+
yield from centre_from_murko()
|
|
144
|
+
yield from bps.unstage(murko_results, wait=True)
|
|
145
|
+
|
|
146
|
+
yield from rotate_in_one_direction_then_murko_centre(
|
|
147
|
+
rotation, Source.FULL_SCREEN
|
|
148
|
+
)
|
|
149
|
+
yield from rotate_in_one_direction_then_murko_centre(-rotation, Source.ROI)
|
|
150
150
|
|
|
151
|
+
yield from do_thaw_and_murko_centre()
|
|
151
152
|
|
|
152
|
-
|
|
153
|
+
|
|
154
|
+
def thaw_and_stream_to_redis(
|
|
153
155
|
time_to_thaw: float,
|
|
154
|
-
rotation: float,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
rotation: float = 360,
|
|
157
|
+
robot: BartRobot = inject("robot"),
|
|
158
|
+
thawer: Thawer = inject("thawer"),
|
|
159
|
+
smargon: Smargon = inject("smargon"),
|
|
160
|
+
oav_to_redis_forwarder: OAVToRedisForwarder = inject("oav_to_redis_forwarder"),
|
|
158
161
|
) -> MsgGenerator:
|
|
159
162
|
"""Turns on the thawer and rotates the sample by {rotation} degrees to thaw it, then
|
|
160
163
|
rotates {rotation} degrees back and turns the thawer off. The speed of the goniometer
|
|
161
164
|
is set such that the process takes whole process will take {time_to_thaw} time.
|
|
162
165
|
|
|
166
|
+
At the same time streams OAV images to redis for later processing (e.g. by murko).
|
|
167
|
+
On the first rotation the images from the large ROI are streamed, on the second the
|
|
168
|
+
smaller ROI is used.
|
|
169
|
+
|
|
163
170
|
Args:
|
|
164
171
|
time_to_thaw (float): Time to thaw for, in seconds.
|
|
165
|
-
rotation (float): How much to rotate by whilst thawing, in degrees.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
of the smargon. Defaults to no plan.
|
|
172
|
+
rotation (float, optional): How much to rotate by whilst thawing, in degrees.
|
|
173
|
+
Defaults to 360.
|
|
174
|
+
... devices: These are the specific ophyd-devices used for the plan, the
|
|
175
|
+
defaults are always correct
|
|
170
176
|
"""
|
|
171
|
-
inital_velocity = yield from bps.rd(smargon.omega.velocity)
|
|
172
|
-
new_velocity = abs(rotation / time_to_thaw) * 2.0
|
|
173
|
-
|
|
174
|
-
def do_thaw():
|
|
175
|
-
yield from bps.abs_set(smargon.omega.velocity, new_velocity, wait=True)
|
|
176
|
-
yield from bps.abs_set(thawer.control, OnOff.ON, wait=True)
|
|
177
|
-
yield from bps.rel_set(smargon.omega, rotation, wait=True)
|
|
178
|
-
if plan_between_rotations:
|
|
179
|
-
yield from plan_between_rotations()
|
|
180
|
-
yield from bps.rel_set(smargon.omega, -rotation, wait=True)
|
|
181
|
-
|
|
182
|
-
def cleanup():
|
|
183
|
-
yield from bps.abs_set(smargon.omega.velocity, inital_velocity, wait=True)
|
|
184
|
-
yield from bps.abs_set(thawer.control, OnOff.OFF, wait=True)
|
|
185
|
-
|
|
186
|
-
# Always cleanup even if there is a failure
|
|
187
|
-
yield from bpp.contingency_wrapper(
|
|
188
|
-
do_thaw(),
|
|
189
|
-
final_plan=cleanup,
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def _thaw_and_stream_to_redis(
|
|
194
|
-
time_to_thaw: float,
|
|
195
|
-
rotation: float,
|
|
196
|
-
robot: BartRobot,
|
|
197
|
-
thawer: Thawer,
|
|
198
|
-
smargon: Smargon,
|
|
199
|
-
oav: OAV,
|
|
200
|
-
oav_to_redis_forwarder: OAVToRedisForwarder,
|
|
201
|
-
plan_between_rotations: Callable[[], MsgGenerator],
|
|
202
|
-
) -> MsgGenerator:
|
|
203
|
-
zoom_percentage = yield from bps.rd(oav.zoom_controller.percentage)
|
|
204
177
|
sample_id = yield from bps.rd(robot.sample_id)
|
|
205
|
-
|
|
206
178
|
sample_id = int(sample_id)
|
|
207
|
-
zoom_level_before_thawing = yield from bps.rd(oav.zoom_controller.level)
|
|
208
179
|
|
|
209
|
-
|
|
180
|
+
oav_fs = oav_to_redis_forwarder.sources[Source.FULL_SCREEN].oav_ref()
|
|
210
181
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
beam_centre_j = yield from bps.rd(oav.beam_centre_j)
|
|
182
|
+
initial_zoom_level = yield from bps.rd(oav_fs.zoom_controller.level)
|
|
183
|
+
initial_velocity = yield from bps.rd(smargon.omega.velocity)
|
|
184
|
+
new_velocity = abs(rotation / time_to_thaw) * 2.0
|
|
215
185
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
RedisConstants.MURKO_REDIS_DB,
|
|
221
|
-
)
|
|
222
|
-
)
|
|
223
|
-
@run_decorator(
|
|
224
|
-
md={
|
|
225
|
-
"microns_per_x_pixel": microns_per_pixel_x,
|
|
226
|
-
"microns_per_y_pixel": microns_per_pixel_y,
|
|
227
|
-
"beam_centre_i": beam_centre_i,
|
|
228
|
-
"beam_centre_j": beam_centre_j,
|
|
229
|
-
"zoom_percentage": zoom_percentage,
|
|
230
|
-
"sample_id": sample_id,
|
|
231
|
-
}
|
|
186
|
+
murko_callback = MurkoCallback(
|
|
187
|
+
RedisConstants.REDIS_HOST,
|
|
188
|
+
RedisConstants.REDIS_PASSWORD,
|
|
189
|
+
RedisConstants.MURKO_REDIS_DB,
|
|
232
190
|
)
|
|
233
|
-
|
|
191
|
+
|
|
192
|
+
def cleanup():
|
|
193
|
+
yield from bps.mv(oav_fs.zoom_controller.level, initial_zoom_level)
|
|
194
|
+
yield from bps.abs_set(smargon.omega.velocity, initial_velocity, wait=True)
|
|
195
|
+
yield from bps.abs_set(thawer, OnOff.OFF, wait=True)
|
|
196
|
+
|
|
197
|
+
@subs_decorator(murko_callback)
|
|
198
|
+
@contingency_decorator(final_plan=cleanup)
|
|
199
|
+
def do_thaw_and_stream_to_redis():
|
|
234
200
|
yield from bps.mv(
|
|
235
201
|
oav_to_redis_forwarder.sample_id,
|
|
236
202
|
sample_id,
|
|
237
|
-
|
|
238
|
-
|
|
203
|
+
oav_fs.zoom_controller.level,
|
|
204
|
+
"1.0x",
|
|
239
205
|
)
|
|
240
|
-
|
|
241
|
-
yield from bps.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
206
|
+
yield from bps.abs_set(smargon.omega.velocity, new_velocity, wait=True)
|
|
207
|
+
yield from bps.abs_set(thawer, OnOff.ON, wait=True)
|
|
208
|
+
|
|
209
|
+
@run_decorator(md={"sample_id": sample_id})
|
|
210
|
+
def rotate_in_one_direction_and_stream_to_redis(
|
|
211
|
+
rotation: float, oav_mode: Source
|
|
212
|
+
):
|
|
213
|
+
yield from _rotate_in_one_direction_and_stream_to_redis(
|
|
214
|
+
smargon, oav_to_redis_forwarder, oav_mode, rotation
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
yield from rotate_in_one_direction_and_stream_to_redis(
|
|
218
|
+
rotation, Source.FULL_SCREEN
|
|
246
219
|
)
|
|
247
|
-
yield from
|
|
220
|
+
yield from rotate_in_one_direction_and_stream_to_redis(-rotation, Source.ROI)
|
|
248
221
|
|
|
249
|
-
|
|
250
|
-
yield from bps.mv(oav.zoom_controller.level, zoom_level_before_thawing)
|
|
222
|
+
yield from do_thaw_and_stream_to_redis()
|
|
251
223
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
224
|
+
|
|
225
|
+
def _rotate_in_one_direction_and_stream_to_redis(
|
|
226
|
+
smargon: Smargon,
|
|
227
|
+
oav_to_redis_forwarder: OAVToRedisForwarder,
|
|
228
|
+
oav_mode: Source,
|
|
229
|
+
rotation: float,
|
|
230
|
+
):
|
|
231
|
+
def get_metadata_from_current_oav():
|
|
232
|
+
current_source_idx = yield from bps.rd(oav_to_redis_forwarder.selected_source)
|
|
233
|
+
oav = oav_to_redis_forwarder.sources[current_source_idx].oav_ref()
|
|
234
|
+
yield from bps.create()
|
|
235
|
+
oav_info = yield from bps.read(oav)
|
|
236
|
+
LOGGER.info(f"Got oav information: {oav_info}")
|
|
237
|
+
yield from bps.save()
|
|
238
|
+
|
|
239
|
+
yield from bps.mv(
|
|
240
|
+
oav_to_redis_forwarder.selected_source,
|
|
241
|
+
oav_mode.value,
|
|
255
242
|
)
|
|
243
|
+
|
|
244
|
+
yield from get_metadata_from_current_oav()
|
|
245
|
+
yield from bps.monitor(smargon.omega.user_readback, name="smargon")
|
|
246
|
+
yield from bps.monitor(oav_to_redis_forwarder.uuid, name="oav")
|
|
247
|
+
|
|
248
|
+
yield from bps.kickoff(oav_to_redis_forwarder, wait=True)
|
|
249
|
+
yield from bps.rel_set(smargon.omega, rotation, wait=True)
|
|
250
|
+
yield from bps.complete(oav_to_redis_forwarder, wait=True)
|
|
@@ -3,10 +3,10 @@ from bluesky import plan_stubs as bps
|
|
|
3
3
|
from bluesky.utils import MsgGenerator
|
|
4
4
|
from dodal.common import inject
|
|
5
5
|
from dodal.devices.i24.commissioning_jungfrau import CommissioningJungfrau
|
|
6
|
-
from ophyd_async.core import WatchableAsyncStatus
|
|
7
6
|
from ophyd_async.fastcs.jungfrau import (
|
|
8
7
|
AcquisitionType,
|
|
9
8
|
GainMode,
|
|
9
|
+
create_jungfrau_internal_triggering_info,
|
|
10
10
|
create_jungfrau_pedestal_triggering_info,
|
|
11
11
|
)
|
|
12
12
|
from pydantic import PositiveInt
|
|
@@ -18,6 +18,7 @@ from mx_bluesky.beamlines.i24.jungfrau_commissioning.plan_stubs.plan_utils impor
|
|
|
18
18
|
from mx_bluesky.common.utils.log import LOGGER
|
|
19
19
|
|
|
20
20
|
PEDESTAL_DARKS_RUN = "PEDESTAL DARKS RUN"
|
|
21
|
+
STANDARD_DARKS_RUN = "STANDARD DARKS RUN"
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def do_pedestal_darks(
|
|
@@ -26,7 +27,7 @@ def do_pedestal_darks(
|
|
|
26
27
|
pedestal_loops: PositiveInt = 200,
|
|
27
28
|
jungfrau: CommissioningJungfrau = inject("jungfrau"),
|
|
28
29
|
path_of_output_file: str | None = None,
|
|
29
|
-
) -> MsgGenerator
|
|
30
|
+
) -> MsgGenerator:
|
|
30
31
|
"""Acquire darks in pedestal mode, using dynamic gain mode. This calibrates the offsets
|
|
31
32
|
for the jungfrau, and must be performed before acquiring real data in dynamic gain mode.
|
|
32
33
|
|
|
@@ -38,6 +39,9 @@ def do_pedestal_darks(
|
|
|
38
39
|
4. Do the first three steps a second time, except use ForceSwitchG2 instead of ForceSwitchG1
|
|
39
40
|
during step 2.
|
|
40
41
|
|
|
42
|
+
A pedestal scan should be acquired when detector configuration and environmental conditions change, but due to small
|
|
43
|
+
in instabilities in beamline conditions, it is recommended to run a pedestal scan on roughly an hourly basis.
|
|
44
|
+
|
|
41
45
|
Args:
|
|
42
46
|
exp_time_s: Length of detector exposure for each frame.
|
|
43
47
|
pedestal_frames: Number of frames acquired per pedestal loop.
|
|
@@ -66,13 +70,54 @@ def do_pedestal_darks(
|
|
|
66
70
|
jungfrau.drv.gain_mode,
|
|
67
71
|
GainMode.DYNAMIC,
|
|
68
72
|
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
yield from fly_jungfrau(
|
|
74
|
+
jungfrau,
|
|
75
|
+
trigger_info,
|
|
76
|
+
wait=True,
|
|
77
|
+
log_on_percentage_prefix="Jungfrau pedestal dynamic gain mode darks triggers received",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
yield from _do_decorated_plan()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def do_non_pedestal_darks(
|
|
84
|
+
gain_mode: GainMode,
|
|
85
|
+
exp_time_s: float = 0.001,
|
|
86
|
+
total_triggers: PositiveInt = 1000,
|
|
87
|
+
jungfrau: CommissioningJungfrau = inject("jungfrau"),
|
|
88
|
+
path_of_output_file: str | None = None,
|
|
89
|
+
) -> MsgGenerator:
|
|
90
|
+
"""Internally take a set of images at a given gain mode.
|
|
91
|
+
|
|
92
|
+
Non-pedestal darks are useful for detector panel cross-checks and for calculating masks.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
gain_mode: Which gain mode to put the Jungfrau into before starting the acquisition.
|
|
96
|
+
exp_time_s: Length of detector exposure for each trigger.
|
|
97
|
+
total_triggers: Total triggers for the dark scan.
|
|
98
|
+
jungfrau: Jungfrau device
|
|
99
|
+
path_of_output_file: Absolute path of the detector file output, including file name. If None, then use the PathProvider
|
|
100
|
+
set during Jungfrau device instantiation
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
@bpp.set_run_key_decorator(STANDARD_DARKS_RUN)
|
|
104
|
+
@bpp.run_decorator(md={"subplan_name": STANDARD_DARKS_RUN})
|
|
105
|
+
@bpp.stage_decorator([jungfrau])
|
|
106
|
+
def _do_decorated_plan():
|
|
107
|
+
if path_of_output_file:
|
|
108
|
+
override_file_path(jungfrau, path_of_output_file)
|
|
109
|
+
|
|
110
|
+
trigger_info = create_jungfrau_internal_triggering_info(
|
|
111
|
+
total_triggers, exp_time_s
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
yield from bps.mv(jungfrau.drv.gain_mode, gain_mode)
|
|
115
|
+
|
|
116
|
+
yield from fly_jungfrau(
|
|
117
|
+
jungfrau,
|
|
118
|
+
trigger_info,
|
|
119
|
+
wait=True,
|
|
120
|
+
log_on_percentage_prefix=f"Jungfrau {gain_mode} gain mode darks triggers received",
|
|
76
121
|
)
|
|
77
122
|
|
|
78
|
-
|
|
123
|
+
yield from _do_decorated_plan()
|
|
@@ -30,7 +30,7 @@ def do_external_acquisition(
|
|
|
30
30
|
|
|
31
31
|
Args:
|
|
32
32
|
exp_time_s: Length of detector exposure for each frame.
|
|
33
|
-
total_triggers: Number of external triggers
|
|
33
|
+
total_triggers: Number of external triggers received before acquisition is marked as complete.
|
|
34
34
|
jungfrau: Jungfrau device
|
|
35
35
|
output_file_name: Absolute path of the detector file output, including file name. If None, then use the PathProvider
|
|
36
36
|
set during jungfrau device instantiation
|
|
@@ -21,7 +21,7 @@ def fly_jungfrau(
|
|
|
21
21
|
jungfrau: CommissioningJungfrau,
|
|
22
22
|
trigger_info: TriggerInfo,
|
|
23
23
|
wait: bool = False,
|
|
24
|
-
log_on_percentage_prefix="Jungfrau data collection triggers
|
|
24
|
+
log_on_percentage_prefix="Jungfrau data collection triggers received",
|
|
25
25
|
) -> MsgGenerator[WatchableAsyncStatus]:
|
|
26
26
|
"""Stage, prepare, and kickoff Jungfrau with a configured TriggerInfo. Optionally wait
|
|
27
27
|
for completion.
|
|
@@ -3,19 +3,20 @@ from mx_bluesky.beamlines.i24.serial.web_gui_plans.general_plans import (
|
|
|
3
3
|
gui_move_backlight,
|
|
4
4
|
gui_move_detector,
|
|
5
5
|
gui_run_chip_collection,
|
|
6
|
+
gui_run_extruder_collection,
|
|
7
|
+
gui_set_fiducial_0,
|
|
6
8
|
gui_set_zoom_level,
|
|
7
|
-
gui_sleep,
|
|
8
9
|
gui_stage_move_on_click,
|
|
9
10
|
)
|
|
10
11
|
|
|
11
|
-
from .extruder.
|
|
12
|
+
from .extruder.i24ssx_extruder_collect_py3v2 import (
|
|
12
13
|
enter_hutch,
|
|
13
14
|
initialise_extruder,
|
|
14
15
|
laser_check,
|
|
15
16
|
run_extruder_plan,
|
|
16
17
|
)
|
|
17
|
-
from .fixed_target.
|
|
18
|
-
from .fixed_target.
|
|
18
|
+
from .fixed_target.i24ssx_chip_collect_py3v1 import run_fixed_target_plan
|
|
19
|
+
from .fixed_target.i24ssx_chip_manager_py3v1 import (
|
|
19
20
|
block_check,
|
|
20
21
|
cs_maker,
|
|
21
22
|
cs_reset,
|
|
@@ -56,9 +57,10 @@ __all__ = [
|
|
|
56
57
|
# GUI plans
|
|
57
58
|
"gui_stage_move_on_click",
|
|
58
59
|
"gui_gonio_move_on_click",
|
|
59
|
-
"gui_sleep",
|
|
60
60
|
"gui_move_detector",
|
|
61
61
|
"gui_run_chip_collection",
|
|
62
62
|
"gui_move_backlight",
|
|
63
63
|
"gui_set_zoom_level",
|
|
64
|
+
"gui_set_fiducial_0",
|
|
65
|
+
"gui_run_extruder_collection",
|
|
64
66
|
]
|
|
@@ -95,7 +95,7 @@ class DCID:
|
|
|
95
95
|
|
|
96
96
|
Attributes:
|
|
97
97
|
error:
|
|
98
|
-
If an error has
|
|
98
|
+
If an error has occurred. This will be set, even if emit_errors = True
|
|
99
99
|
"""
|
|
100
100
|
|
|
101
101
|
def __init__(
|
|
@@ -112,6 +112,8 @@ class DCID:
|
|
|
112
112
|
match expt_params.detector_name:
|
|
113
113
|
case "eiger":
|
|
114
114
|
self.detector = Eiger()
|
|
115
|
+
case _:
|
|
116
|
+
raise ValueError("Unknown detector:", expt_params.detector_name)
|
|
115
117
|
|
|
116
118
|
self.server = server or DEFAULT_ISPYB_SERVER
|
|
117
119
|
self.emit_errors = emit_errors
|
|
@@ -144,7 +146,7 @@ class DCID:
|
|
|
144
146
|
try:
|
|
145
147
|
if not start_time:
|
|
146
148
|
start_time = datetime.datetime.now().astimezone()
|
|
147
|
-
|
|
149
|
+
else:
|
|
148
150
|
start_time = start_time.astimezone()
|
|
149
151
|
|
|
150
152
|
resolution = get_resolution(
|
|
@@ -156,10 +158,7 @@ class DCID:
|
|
|
156
158
|
transmission = self.parameters.transmission * 100
|
|
157
159
|
xbeam, ybeam = beam_settings.beam_center_in_mm
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
startImageNumber = 1
|
|
161
|
-
else:
|
|
162
|
-
raise ValueError("Unknown detector:", self.detector)
|
|
161
|
+
start_image_number = 1
|
|
163
162
|
|
|
164
163
|
events = [
|
|
165
164
|
{
|
|
@@ -201,7 +200,7 @@ class DCID:
|
|
|
201
200
|
"imageDirectory": image_dir,
|
|
202
201
|
"numberOfImages": num_images,
|
|
203
202
|
"resolution": resolution,
|
|
204
|
-
"startImageNumber":
|
|
203
|
+
"startImageNumber": start_image_number,
|
|
205
204
|
"startTime": start_time.isoformat(),
|
|
206
205
|
"transmission": transmission,
|
|
207
206
|
"visit": self.parameters.visit.name,
|