mx-bluesky 1.5.11__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/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/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 +87 -13
- 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 +147 -152
- mx_bluesky/beamlines/i24/serial/dcid.py +4 -5
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_extruder_collect_py3v2.py +5 -2
- 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 +7 -4
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_chip_manager_py3v1.py +35 -32
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +5 -5
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +113 -306
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +8 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +1 -1
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +1 -1
- mx_bluesky/beamlines/i24/serial/web_gui_plans/oav_plans.py +64 -0
- mx_bluesky/{hyperion/device_setup_plans/smargon.py → common/device_setup_plans/gonio.py} +9 -6
- 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 +2 -0
- mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py +5 -2
- mx_bluesky/common/experiment_plans/oav_snapshot_plan.py +0 -1
- mx_bluesky/{hyperion → common}/experiment_plans/pin_tip_centring_plan.py +20 -21
- mx_bluesky/common/external_interaction/callbacks/common/grid_detection_callback.py +5 -0
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +10 -12
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_mapping.py +3 -5
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +5 -5
- mx_bluesky/common/external_interaction/config_server.py +2 -2
- mx_bluesky/common/external_interaction/ispyb/data_model.py +11 -4
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +159 -2
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +76 -166
- mx_bluesky/common/external_interaction/ispyb/ispyb_utils.py +0 -14
- mx_bluesky/common/parameters/components.py +1 -0
- mx_bluesky/common/parameters/constants.py +3 -2
- mx_bluesky/common/parameters/device_composites.py +4 -2
- mx_bluesky/common/utils/exceptions.py +15 -0
- mx_bluesky/common/utils/log.py +9 -0
- mx_bluesky/common/utils/utils.py +48 -0
- mx_bluesky/hyperion/__main__.py +3 -13
- mx_bluesky/hyperion/baton_handler.py +23 -6
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +5 -6
- 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 +8 -2
- 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 +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +2 -2
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -0
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +1 -4
- mx_bluesky/hyperion/external_interaction/config_server.py +5 -5
- mx_bluesky/hyperion/parameters/constants.py +10 -3
- mx_bluesky/hyperion/parameters/device_composites.py +2 -2
- mx_bluesky/hyperion/parameters/robot_load.py +1 -9
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/METADATA +6 -5
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/RECORD +83 -69
- mx_bluesky/common/experiment_plans/inner_plans/udc_default_state.py +0 -86
- mx_bluesky/common/external_interaction/callbacks/common/logging_callback.py +0 -29
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/WHEEL +0 -0
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.5.11.dist-info → mx_bluesky-1.5.12.dist-info}/top_level.txt +0 -0
mx_bluesky/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.5.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 5,
|
|
31
|
+
__version__ = version = '1.5.12'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 5, 12)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
File without changes
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import bluesky.plan_stubs as bps
|
|
7
|
+
import bluesky.preprocessors as bpp
|
|
8
|
+
import pydantic
|
|
9
|
+
from dodal.devices.motors import XYZOmegaStage, XYZStage
|
|
10
|
+
from dodal.devices.oav.oav_detector import OAV
|
|
11
|
+
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
12
|
+
from dodal.devices.robot import BartRobot, SampleLocation
|
|
13
|
+
|
|
14
|
+
from mx_bluesky.beamlines.aithre_lasershaping.parameters.constants import CONST
|
|
15
|
+
from mx_bluesky.beamlines.aithre_lasershaping.parameters.robot_load_parameters import (
|
|
16
|
+
AithreRobotLoad,
|
|
17
|
+
)
|
|
18
|
+
from mx_bluesky.common.device_setup_plans.robot_load_unload import (
|
|
19
|
+
do_plan_while_lower_gonio_at_home,
|
|
20
|
+
)
|
|
21
|
+
from mx_bluesky.common.experiment_plans.pin_tip_centring_plan import (
|
|
22
|
+
PinTipCentringComposite,
|
|
23
|
+
pin_tip_centre_plan,
|
|
24
|
+
)
|
|
25
|
+
from mx_bluesky.common.parameters.constants import (
|
|
26
|
+
DocDescriptorNames,
|
|
27
|
+
PlanNameConstants,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
32
|
+
class RobotLoadComposite:
|
|
33
|
+
# RobotLoad fields
|
|
34
|
+
robot: BartRobot
|
|
35
|
+
lower_gonio: XYZStage
|
|
36
|
+
oav: OAV
|
|
37
|
+
gonio: XYZOmegaStage
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _move_gonio_to_home_position(
|
|
41
|
+
composite: RobotLoadComposite,
|
|
42
|
+
x_home: float = 0.0,
|
|
43
|
+
y_home: float = 0.0,
|
|
44
|
+
z_home: float = 0.0,
|
|
45
|
+
omega_home: float = 0.0,
|
|
46
|
+
group: str = "group",
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
Move Gonio to home position, default is zero
|
|
50
|
+
"""
|
|
51
|
+
yield from bps.abs_set(composite.gonio.omega, omega_home, group=group)
|
|
52
|
+
yield from bps.abs_set(composite.gonio.x, x_home, group=group)
|
|
53
|
+
yield from bps.abs_set(composite.gonio.y, y_home, group=group)
|
|
54
|
+
yield from bps.abs_set(composite.gonio.z, z_home, group=group)
|
|
55
|
+
|
|
56
|
+
yield from bps.wait(group=group)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _take_robot_snapshots(oav: OAV, directory: Path):
|
|
60
|
+
time_now = datetime.now()
|
|
61
|
+
snapshot_format = f"{time_now.strftime('%H%M%S')}_{{device}}_after_load"
|
|
62
|
+
for device in [oav.snapshot]:
|
|
63
|
+
yield from bps.abs_set(
|
|
64
|
+
device.filename, snapshot_format.format(device=device.name)
|
|
65
|
+
)
|
|
66
|
+
yield from bps.abs_set(device.directory, str(directory))
|
|
67
|
+
# Note: should be able to use `wait=True` after https://github.com/bluesky/bluesky/issues/1795
|
|
68
|
+
yield from bps.trigger(device, group="snapshots")
|
|
69
|
+
yield from bps.wait("snapshots")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _do_robot_load_and_centre(
|
|
73
|
+
composite: RobotLoadComposite,
|
|
74
|
+
sample_location: SampleLocation,
|
|
75
|
+
sample_id: int,
|
|
76
|
+
pin_tip_detection: PinTipDetection,
|
|
77
|
+
tip_offset_microns: float = 0,
|
|
78
|
+
oav_config_file: str = CONST.OAV_CENTRING_FILE,
|
|
79
|
+
):
|
|
80
|
+
yield from bps.abs_set(composite.robot.next_sample_id, sample_id, wait=True)
|
|
81
|
+
yield from bps.abs_set(
|
|
82
|
+
composite.robot,
|
|
83
|
+
sample_location,
|
|
84
|
+
group="robot_load",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
yield from _move_gonio_to_home_position(composite=composite, group="robot_load")
|
|
88
|
+
|
|
89
|
+
yield from bps.wait(group="robot_load")
|
|
90
|
+
|
|
91
|
+
pin_tip_centring_composite = PinTipCentringComposite(
|
|
92
|
+
composite.oav, composite.gonio, pin_tip_detection
|
|
93
|
+
)
|
|
94
|
+
yield from pin_tip_centre_plan(
|
|
95
|
+
pin_tip_centring_composite, tip_offset_microns, oav_config_file
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _robot_load_and_snapshots(
|
|
100
|
+
composite: RobotLoadComposite,
|
|
101
|
+
location: SampleLocation,
|
|
102
|
+
snapshot_directory: Path,
|
|
103
|
+
sample_id: int,
|
|
104
|
+
pin_tip_detection: PinTipDetection,
|
|
105
|
+
tip_offset_microns: float = 0,
|
|
106
|
+
oav_config_file: str = CONST.OAV_CENTRING_FILE,
|
|
107
|
+
):
|
|
108
|
+
yield from bps.create(name=DocDescriptorNames.ROBOT_PRE_LOAD)
|
|
109
|
+
yield from bps.read(composite.robot)
|
|
110
|
+
yield from bps.save()
|
|
111
|
+
|
|
112
|
+
robot_load_plan = _do_robot_load_and_centre(
|
|
113
|
+
composite,
|
|
114
|
+
location,
|
|
115
|
+
sample_id,
|
|
116
|
+
pin_tip_detection,
|
|
117
|
+
tip_offset_microns,
|
|
118
|
+
oav_config_file,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
gonio_finished = yield from do_plan_while_lower_gonio_at_home(
|
|
122
|
+
robot_load_plan, composite.lower_gonio
|
|
123
|
+
)
|
|
124
|
+
yield from bps.wait(group="snapshot")
|
|
125
|
+
|
|
126
|
+
yield from _take_robot_snapshots(composite.oav, snapshot_directory)
|
|
127
|
+
|
|
128
|
+
yield from bps.create(name=DocDescriptorNames.ROBOT_UPDATE)
|
|
129
|
+
yield from bps.read(composite.robot)
|
|
130
|
+
yield from bps.read(composite.oav.snapshot)
|
|
131
|
+
yield from bps.save()
|
|
132
|
+
|
|
133
|
+
yield from bps.wait(gonio_finished)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def robot_load_and_snapshots_plan(
|
|
137
|
+
composite: RobotLoadComposite,
|
|
138
|
+
params: AithreRobotLoad,
|
|
139
|
+
ptd: PinTipDetection,
|
|
140
|
+
tip_offset_microns: float = 0,
|
|
141
|
+
oav_config_file: str = CONST.OAV_CENTRING_FILE,
|
|
142
|
+
):
|
|
143
|
+
assert params.sample_puck is not None
|
|
144
|
+
assert params.sample_pin is not None
|
|
145
|
+
|
|
146
|
+
sample_location = SampleLocation(params.sample_puck, params.sample_pin)
|
|
147
|
+
|
|
148
|
+
yield from _move_gonio_to_home_position(composite)
|
|
149
|
+
|
|
150
|
+
yield from bpp.set_run_key_wrapper(
|
|
151
|
+
bpp.run_wrapper(
|
|
152
|
+
_robot_load_and_snapshots(
|
|
153
|
+
composite,
|
|
154
|
+
sample_location,
|
|
155
|
+
params.snapshot_directory,
|
|
156
|
+
params.sample_id,
|
|
157
|
+
ptd,
|
|
158
|
+
tip_offset_microns,
|
|
159
|
+
oav_config_file,
|
|
160
|
+
),
|
|
161
|
+
md={
|
|
162
|
+
"subplan_name": PlanNameConstants.ROBOT_LOAD,
|
|
163
|
+
"metadata": {"visit": params.visit, "sample_id": params.sample_id},
|
|
164
|
+
"activate_callbacks": [
|
|
165
|
+
"RobotLoadISPyBCallback",
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
),
|
|
169
|
+
PlanNameConstants.ROBOT_LOAD_AND_SNAPSHOTS,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def robot_unload_plan(
|
|
174
|
+
composite: RobotLoadComposite,
|
|
175
|
+
params: AithreRobotLoad,
|
|
176
|
+
):
|
|
177
|
+
@bpp.run_decorator(
|
|
178
|
+
md={
|
|
179
|
+
"subplan_name": PlanNameConstants.ROBOT_UNLOAD,
|
|
180
|
+
"metadata": {"visit": params.visit, "sample_id": params.sample_id},
|
|
181
|
+
"activate_callbacks": [
|
|
182
|
+
"RobotLoadISPyBCallback",
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
)
|
|
186
|
+
def do_robot_unload_and_send_to_ispyb():
|
|
187
|
+
yield from _take_robot_snapshots(composite.oav, params.snapshot_directory)
|
|
188
|
+
yield from bps.wait(group="snapshot")
|
|
189
|
+
yield from _move_gonio_to_home_position(composite)
|
|
190
|
+
|
|
191
|
+
yield from bps.abs_set(composite.robot, None, wait=True)
|
|
192
|
+
|
|
193
|
+
yield from bps.create(name=DocDescriptorNames.ROBOT_UPDATE)
|
|
194
|
+
yield from bps.read(composite.robot)
|
|
195
|
+
yield from bps.read(composite.oav.snapshot)
|
|
196
|
+
yield from bps.save()
|
|
197
|
+
|
|
198
|
+
yield from do_robot_unload_and_send_to_ispyb()
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from pydantic.dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
TEST_MODE = os.environ.get("AITHRE_TEST_MODE")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class AithreConstants:
|
|
10
|
+
BEAMLINE = "aithre"
|
|
11
|
+
OAV_CENTRING_FILE = (
|
|
12
|
+
"/dls/science/groups/i23/aithre/daq_configuration/json/OAVCentring_aithre.json"
|
|
13
|
+
)
|
|
14
|
+
LOG_FILE_NAME = "aithre.log"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
CONST = AithreConstants()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from bluesky.utils import MsgGenerator
|
|
2
|
+
from dodal.common import inject
|
|
3
|
+
from dodal.devices.aithre_lasershaping.goniometer import Goniometer
|
|
4
|
+
from dodal.devices.oav.oav_detector import OAV
|
|
5
|
+
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
6
|
+
|
|
7
|
+
from mx_bluesky.beamlines.aithre_lasershaping.parameters.constants import CONST
|
|
8
|
+
from mx_bluesky.common.experiment_plans.pin_tip_centring_plan import (
|
|
9
|
+
PinTipCentringComposite,
|
|
10
|
+
pin_tip_centre_plan,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def aithre_pin_tip_centre(
|
|
15
|
+
oav: OAV = inject("OAV"),
|
|
16
|
+
gonio: Goniometer = inject("gonio"),
|
|
17
|
+
pin_tip_detection: PinTipDetection = inject("pin_tip_detection"),
|
|
18
|
+
tip_offset_microns: float = 0,
|
|
19
|
+
oav_config_file: str = CONST.OAV_CENTRING_FILE,
|
|
20
|
+
) -> MsgGenerator:
|
|
21
|
+
"""
|
|
22
|
+
A plan that use pin_tip_centre_plan from common for aithre
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
composite = PinTipCentringComposite(oav, gonio, pin_tip_detection)
|
|
26
|
+
|
|
27
|
+
yield from pin_tip_centre_plan(
|
|
28
|
+
composite=composite,
|
|
29
|
+
tip_offset_microns=tip_offset_microns,
|
|
30
|
+
oav_config_file=oav_config_file,
|
|
31
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
from bluesky.utils import MsgGenerator
|
|
4
|
+
from dodal.common import inject
|
|
5
|
+
from dodal.devices.motors import XYZOmegaStage
|
|
6
|
+
from dodal.devices.oav.oav_detector import OAV
|
|
7
|
+
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
8
|
+
from dodal.devices.robot import BartRobot
|
|
9
|
+
|
|
10
|
+
from mx_bluesky.beamlines.aithre_lasershaping.experiment_plans.robot_load_plan import (
|
|
11
|
+
RobotLoadComposite,
|
|
12
|
+
robot_load_and_snapshots_plan,
|
|
13
|
+
robot_unload_plan,
|
|
14
|
+
)
|
|
15
|
+
from mx_bluesky.beamlines.aithre_lasershaping.parameters.constants import CONST
|
|
16
|
+
from mx_bluesky.beamlines.aithre_lasershaping.parameters.robot_load_parameters import (
|
|
17
|
+
AithreRobotLoad,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def robot_load_and_snapshot(
|
|
22
|
+
robot: BartRobot = inject("robot"),
|
|
23
|
+
gonio: XYZOmegaStage = inject("gonio"),
|
|
24
|
+
oav: OAV = inject("oav"),
|
|
25
|
+
ptd: PinTipDetection = inject("ptd"),
|
|
26
|
+
tip_offset_microns: float = 0,
|
|
27
|
+
oav_config_file: str = CONST.OAV_CENTRING_FILE,
|
|
28
|
+
sample_puck: int = 0,
|
|
29
|
+
sample_pin: int = 0,
|
|
30
|
+
sample_id: int = 0,
|
|
31
|
+
visit: str = "cm40645-5",
|
|
32
|
+
categories: str = "",
|
|
33
|
+
) -> MsgGenerator:
|
|
34
|
+
"""
|
|
35
|
+
categories: type of the sample, e.g. Germ, ProteinaseK, Screening
|
|
36
|
+
"""
|
|
37
|
+
time_now = datetime.datetime.now()
|
|
38
|
+
year_now = str(time_now.year)
|
|
39
|
+
snapshot_directory = f"/dls/i23/data/{year_now}/{visit}/{categories}"
|
|
40
|
+
composite = RobotLoadComposite(robot, gonio, oav, gonio)
|
|
41
|
+
params = AithreRobotLoad(
|
|
42
|
+
sample_id=sample_id,
|
|
43
|
+
sample_puck=sample_puck,
|
|
44
|
+
sample_pin=sample_pin,
|
|
45
|
+
snapshot_directory=snapshot_directory,
|
|
46
|
+
visit=visit,
|
|
47
|
+
beamline="BL23I",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
yield from robot_load_and_snapshots_plan(
|
|
51
|
+
composite, params, ptd, tip_offset_microns, oav_config_file
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def robot_unload(
|
|
56
|
+
robot: BartRobot = inject("robot"),
|
|
57
|
+
gonio: XYZOmegaStage = inject("gonio"),
|
|
58
|
+
oav: OAV = inject("oav"),
|
|
59
|
+
sample_puck: int = 0,
|
|
60
|
+
sample_pin: int = 0,
|
|
61
|
+
sample_id: int = 0,
|
|
62
|
+
visit: str = "cm40645-5",
|
|
63
|
+
categories: str = "",
|
|
64
|
+
) -> MsgGenerator:
|
|
65
|
+
"""
|
|
66
|
+
categories: type of the sample, e.g. Germ, ProteinaseK, Screening
|
|
67
|
+
"""
|
|
68
|
+
time_now = datetime.datetime.now()
|
|
69
|
+
year_now = str(time_now.year)
|
|
70
|
+
snapshot_directory = f"/dls/i23/data/{year_now}/{visit}/{categories}"
|
|
71
|
+
composite = RobotLoadComposite(robot, gonio, oav, gonio)
|
|
72
|
+
params = AithreRobotLoad(
|
|
73
|
+
sample_id=sample_id,
|
|
74
|
+
sample_puck=sample_puck,
|
|
75
|
+
sample_pin=sample_pin,
|
|
76
|
+
snapshot_directory=snapshot_directory,
|
|
77
|
+
visit=visit,
|
|
78
|
+
beamline="BL23I",
|
|
79
|
+
)
|
|
80
|
+
yield from robot_unload_plan(composite, params)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from mx_bluesky.beamlines.i04.experiment_plans.i04_grid_detect_then_xray_centre_plan import (
|
|
2
|
-
|
|
2
|
+
i04_default_grid_detect_and_xray_centre,
|
|
3
|
+
)
|
|
4
|
+
from mx_bluesky.beamlines.i04.oav_centering_plans.oav_imaging import (
|
|
5
|
+
take_oav_image_with_scintillator_in,
|
|
3
6
|
)
|
|
4
7
|
from mx_bluesky.beamlines.i04.thawing_plan import (
|
|
5
8
|
thaw,
|
|
@@ -10,6 +13,7 @@ from mx_bluesky.beamlines.i04.thawing_plan import (
|
|
|
10
13
|
__all__ = [
|
|
11
14
|
"thaw",
|
|
12
15
|
"thaw_and_stream_to_redis",
|
|
13
|
-
"
|
|
16
|
+
"i04_default_grid_detect_and_xray_centre",
|
|
14
17
|
"thaw_and_murko_centre",
|
|
18
|
+
"take_oav_image_with_scintillator_in",
|
|
15
19
|
]
|
|
@@ -8,6 +8,8 @@ from dodal.log import LOGGER
|
|
|
8
8
|
from event_model.documents import Event, RunStart, RunStop
|
|
9
9
|
from redis import StrictRedis
|
|
10
10
|
|
|
11
|
+
FORWARDING_COMPLETE_MESSAGE = "image_forwarding_complete"
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
class OmegaReading(TypedDict):
|
|
13
15
|
value: float
|
|
@@ -56,22 +58,28 @@ class MurkoCallback(CallbackBase):
|
|
|
56
58
|
self.previous_omegas: list[OmegaReading] = []
|
|
57
59
|
|
|
58
60
|
def start(self, doc: RunStart) -> RunStart | None:
|
|
59
|
-
self.
|
|
60
|
-
self.murko_metadata = {
|
|
61
|
-
"zoom_percentage": doc.get("zoom_percentage"),
|
|
62
|
-
"microns_per_x_pixel": doc.get("microns_per_x_pixel"),
|
|
63
|
-
"microns_per_y_pixel": doc.get("microns_per_y_pixel"),
|
|
64
|
-
"beam_centre_i": doc.get("beam_centre_i"),
|
|
65
|
-
"beam_centre_j": doc.get("beam_centre_j"),
|
|
66
|
-
"sample_id": self.sample_id,
|
|
67
|
-
}
|
|
61
|
+
self.murko_metadata: dict = {"sample_id": doc.get("sample_id")}
|
|
68
62
|
self.last_uuid = None
|
|
69
63
|
self.previous_omegas = []
|
|
70
|
-
LOGGER.info(
|
|
64
|
+
LOGGER.info(
|
|
65
|
+
f"Starting to stream metadata to murko under {self.murko_metadata['sample_id']}"
|
|
66
|
+
)
|
|
71
67
|
return doc
|
|
72
68
|
|
|
73
69
|
def event(self, doc: Event) -> Event:
|
|
74
|
-
|
|
70
|
+
data = doc["data"]
|
|
71
|
+
for prefix in ("oav", "oav_full_screen"):
|
|
72
|
+
if f"{prefix}-beam_centre_j" in data:
|
|
73
|
+
self.murko_metadata.update(
|
|
74
|
+
{
|
|
75
|
+
"microns_per_x_pixel": data[f"{prefix}-microns_per_pixel_x"],
|
|
76
|
+
"microns_per_y_pixel": data[f"{prefix}-microns_per_pixel_y"],
|
|
77
|
+
"beam_centre_i": data[f"{prefix}-beam_centre_i"],
|
|
78
|
+
"beam_centre_j": data[f"{prefix}-beam_centre_j"],
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
if (latest_omega := data.get("smargon-omega")) is not None:
|
|
75
83
|
if len(self.previous_omegas) <= 2 and self.last_uuid:
|
|
76
84
|
# For the first few images there's not enough data to extrapolate so we
|
|
77
85
|
# match them one to one
|
|
@@ -106,5 +114,12 @@ class MurkoCallback(CallbackBase):
|
|
|
106
114
|
self.redis_client.publish("murko", json.dumps(metadata))
|
|
107
115
|
|
|
108
116
|
def stop(self, doc: RunStop) -> RunStop | None:
|
|
109
|
-
LOGGER.info(f"Finished streaming {self.sample_id} to murko")
|
|
117
|
+
LOGGER.info(f"Finished streaming {self.murko_metadata['sample_id']} to murko")
|
|
118
|
+
LOGGER.info(
|
|
119
|
+
f"Publishing forwarding complete message: {FORWARDING_COMPLETE_MESSAGE}"
|
|
120
|
+
)
|
|
121
|
+
self.redis_client.publish(
|
|
122
|
+
"murko",
|
|
123
|
+
json.dumps(FORWARDING_COMPLETE_MESSAGE),
|
|
124
|
+
)
|
|
110
125
|
return doc
|
|
@@ -17,6 +17,7 @@ from dodal.devices.fast_grid_scan import (
|
|
|
17
17
|
set_fast_grid_scan_params,
|
|
18
18
|
)
|
|
19
19
|
from dodal.devices.flux import Flux
|
|
20
|
+
from dodal.devices.i04.beamsize import Beamsize
|
|
20
21
|
from dodal.devices.i04.transfocator import Transfocator
|
|
21
22
|
from dodal.devices.mx_phase1.beamstop import Beamstop
|
|
22
23
|
from dodal.devices.oav.oav_detector import OAV
|
|
@@ -25,7 +26,7 @@ from dodal.devices.robot import BartRobot
|
|
|
25
26
|
from dodal.devices.s4_slit_gaps import S4SlitGaps
|
|
26
27
|
from dodal.devices.smargon import Smargon
|
|
27
28
|
from dodal.devices.synchrotron import Synchrotron
|
|
28
|
-
from dodal.devices.undulator import
|
|
29
|
+
from dodal.devices.undulator import UndulatorInKeV
|
|
29
30
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
30
31
|
from dodal.devices.zebra.zebra import Zebra
|
|
31
32
|
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
@@ -33,7 +34,11 @@ from dodal.devices.zocalo import ZocaloResults
|
|
|
33
34
|
from dodal.plans.preprocessors.verify_undulator_gap import (
|
|
34
35
|
verify_undulator_gap_before_run_decorator,
|
|
35
36
|
)
|
|
37
|
+
from pydantic import BaseModel
|
|
36
38
|
|
|
39
|
+
from mx_bluesky.beamlines.i04.external_interaction.config_server import (
|
|
40
|
+
get_i04_config_client,
|
|
41
|
+
)
|
|
37
42
|
from mx_bluesky.common.device_setup_plans.setup_zebra_and_shutter import (
|
|
38
43
|
setup_zebra_for_gridscan,
|
|
39
44
|
tidy_up_zebra_after_gridscan,
|
|
@@ -58,6 +63,7 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback
|
|
|
58
63
|
from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
|
|
59
64
|
GridscanNexusFileCallback,
|
|
60
65
|
)
|
|
66
|
+
from mx_bluesky.common.parameters.components import PARAMETER_VERSION
|
|
61
67
|
from mx_bluesky.common.parameters.constants import (
|
|
62
68
|
EnvironmentConstants,
|
|
63
69
|
OavConstants,
|
|
@@ -67,13 +73,28 @@ from mx_bluesky.common.parameters.constants import (
|
|
|
67
73
|
from mx_bluesky.common.parameters.device_composites import (
|
|
68
74
|
GridDetectThenXRayCentreComposite,
|
|
69
75
|
)
|
|
70
|
-
from mx_bluesky.common.parameters.gridscan import
|
|
76
|
+
from mx_bluesky.common.parameters.gridscan import (
|
|
77
|
+
GridCommon,
|
|
78
|
+
SpecifiedThreeDGridScan,
|
|
79
|
+
)
|
|
71
80
|
from mx_bluesky.common.preprocessors.preprocessors import (
|
|
72
81
|
transmission_and_xbpm_feedback_for_collection_decorator,
|
|
73
82
|
)
|
|
83
|
+
from mx_bluesky.common.utils.exceptions import CrystalNotFoundError
|
|
74
84
|
from mx_bluesky.common.utils.log import LOGGER
|
|
85
|
+
from mx_bluesky.common.utils.utils import (
|
|
86
|
+
fix_transmission_and_exposure_time_for_current_wavelength,
|
|
87
|
+
)
|
|
75
88
|
|
|
76
|
-
|
|
89
|
+
DEFAULT_XRC_BEAMSIZE_MICRONS = 20
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class I04AutoXrcParams(BaseModel):
|
|
93
|
+
sample_id: int
|
|
94
|
+
file_name: str
|
|
95
|
+
visit: str
|
|
96
|
+
detector_distance_mm: float
|
|
97
|
+
storage_directory: str
|
|
77
98
|
|
|
78
99
|
|
|
79
100
|
def _change_beamsize(
|
|
@@ -91,19 +112,20 @@ def _change_beamsize(
|
|
|
91
112
|
|
|
92
113
|
|
|
93
114
|
# See https://github.com/DiamondLightSource/blueapi/issues/506 for using device composites
|
|
94
|
-
def
|
|
95
|
-
parameters:
|
|
115
|
+
def i04_default_grid_detect_and_xray_centre(
|
|
116
|
+
parameters: I04AutoXrcParams,
|
|
96
117
|
aperture_scatterguard: ApertureScatterguard = inject("aperture_scatterguard"),
|
|
97
118
|
attenuator: BinaryFilterAttenuator = inject("attenuator"),
|
|
98
119
|
backlight: Backlight = inject("backlight"),
|
|
99
120
|
beamstop: Beamstop = inject("beamstop"),
|
|
121
|
+
beamsize: Beamsize = inject("beamsize"),
|
|
100
122
|
dcm: DoubleCrystalMonochromator = inject("dcm"),
|
|
101
123
|
zebra_fast_grid_scan: ZebraFastGridScanThreeD = inject("zebra_fast_grid_scan"),
|
|
102
124
|
flux: Flux = inject("flux"),
|
|
103
125
|
oav: OAV = inject("oav"),
|
|
104
126
|
pin_tip_detection: PinTipDetection = inject("pin_tip_detection"),
|
|
105
127
|
s4_slit_gaps: S4SlitGaps = inject("s4_slit_gaps"),
|
|
106
|
-
undulator:
|
|
128
|
+
undulator: UndulatorInKeV = inject("undulator"),
|
|
107
129
|
xbpm_feedback: XBPMFeedback = inject("xbpm_feedback"),
|
|
108
130
|
zebra: Zebra = inject("zebra"),
|
|
109
131
|
robot: BartRobot = inject("robot"),
|
|
@@ -124,7 +146,6 @@ def i04_grid_detect_then_xray_centre(
|
|
|
124
146
|
- Changes the aperture to match the beam size to the crystal size
|
|
125
147
|
- Moves the sample to the crystal centre of mass
|
|
126
148
|
|
|
127
|
-
|
|
128
149
|
i04's implementation of this plan is very similar to Hyperion. However, since i04
|
|
129
150
|
isn't running in a continuous Bluesky UDC loop, we take additional steps in beamline
|
|
130
151
|
tidy-up.
|
|
@@ -139,6 +160,7 @@ def i04_grid_detect_then_xray_centre(
|
|
|
139
160
|
attenuator,
|
|
140
161
|
backlight,
|
|
141
162
|
beamstop,
|
|
163
|
+
beamsize,
|
|
142
164
|
dcm,
|
|
143
165
|
detector_motion,
|
|
144
166
|
zebra_fast_grid_scan,
|
|
@@ -152,9 +174,18 @@ def i04_grid_detect_then_xray_centre(
|
|
|
152
174
|
robot,
|
|
153
175
|
sample_shutter,
|
|
154
176
|
)
|
|
155
|
-
initial_beamsize = yield from bps.rd(transfocator.
|
|
177
|
+
initial_beamsize = yield from bps.rd(transfocator.current_vertical_size_rbv)
|
|
178
|
+
|
|
179
|
+
initial_x = yield from bps.rd(smargon.x.user_readback)
|
|
180
|
+
initial_y = yield from bps.rd(smargon.y.user_readback)
|
|
181
|
+
initial_z = yield from bps.rd(smargon.z.user_readback)
|
|
182
|
+
|
|
183
|
+
_current_wavelength_a = yield from bps.rd(composite.dcm.wavelength_in_a)
|
|
184
|
+
grid_common_params = _get_grid_common_params(_current_wavelength_a, parameters)
|
|
156
185
|
|
|
157
186
|
def tidy_beamline():
|
|
187
|
+
yield from bps.mv(transfocator, initial_beamsize)
|
|
188
|
+
|
|
158
189
|
if not udc:
|
|
159
190
|
yield from get_ready_for_oav_and_close_shutter(
|
|
160
191
|
composite.smargon,
|
|
@@ -162,7 +193,6 @@ def i04_grid_detect_then_xray_centre(
|
|
|
162
193
|
composite.aperture_scatterguard,
|
|
163
194
|
composite.detector_motion,
|
|
164
195
|
)
|
|
165
|
-
yield from bps.mv(transfocator, initial_beamsize)
|
|
166
196
|
|
|
167
197
|
@bpp.finalize_decorator(tidy_beamline)
|
|
168
198
|
def _inner_grid_detect_then_xrc():
|
|
@@ -174,20 +204,30 @@ def i04_grid_detect_then_xray_centre(
|
|
|
174
204
|
@bpp.subs_decorator(callbacks)
|
|
175
205
|
@verify_undulator_gap_before_run_decorator(composite)
|
|
176
206
|
@transmission_and_xbpm_feedback_for_collection_decorator(
|
|
177
|
-
composite,
|
|
207
|
+
composite,
|
|
208
|
+
grid_common_params.transmission_frac,
|
|
209
|
+
PlanNameConstants.GRIDSCAN_OUTER,
|
|
178
210
|
)
|
|
179
211
|
def grid_detect_then_xray_centre_with_callbacks():
|
|
180
212
|
yield from grid_detect_then_xray_centre(
|
|
181
213
|
composite=composite,
|
|
182
|
-
parameters=
|
|
214
|
+
parameters=grid_common_params,
|
|
183
215
|
xrc_params_type=SpecifiedThreeDGridScan,
|
|
184
216
|
construct_beamline_specific=construct_i04_specific_features,
|
|
185
217
|
oav_config=oav_config,
|
|
186
218
|
)
|
|
187
219
|
|
|
188
|
-
|
|
220
|
+
try:
|
|
221
|
+
yield from grid_detect_then_xray_centre_with_callbacks()
|
|
222
|
+
except CrystalNotFoundError:
|
|
223
|
+
yield from bps.mv(
|
|
224
|
+
smargon.x, initial_x, smargon.y, initial_y, smargon.z, initial_z
|
|
225
|
+
)
|
|
226
|
+
raise
|
|
189
227
|
|
|
190
|
-
yield from _change_beamsize(
|
|
228
|
+
yield from _change_beamsize(
|
|
229
|
+
transfocator, DEFAULT_XRC_BEAMSIZE_MICRONS, grid_common_params
|
|
230
|
+
)
|
|
191
231
|
yield from _inner_grid_detect_then_xrc()
|
|
192
232
|
|
|
193
233
|
|
|
@@ -278,3 +318,37 @@ def construct_i04_specific_features(
|
|
|
278
318
|
signals_to_read_during_collection,
|
|
279
319
|
get_xrc_results_from_zocalo=True,
|
|
280
320
|
)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _get_grid_common_params(
|
|
324
|
+
_current_wavelength_a: float, parameters: I04AutoXrcParams
|
|
325
|
+
) -> GridCommon:
|
|
326
|
+
"""Calculate scaled transmission and exposure by comparing current beamline energy to default energy"""
|
|
327
|
+
_assumed_wavelength_a = (
|
|
328
|
+
get_i04_config_client().get_feature_flags().ASSUMED_WAVELENGTH_IN_A
|
|
329
|
+
)
|
|
330
|
+
_unscaled_transmission = (
|
|
331
|
+
get_i04_config_client().get_feature_flags().XRC_UNSCALED_TRANSMISSION_FRAC
|
|
332
|
+
)
|
|
333
|
+
_unscaled_exposure_time_s = (
|
|
334
|
+
get_i04_config_client().get_feature_flags().XRC_UNSCALED_EXPOSURE_TIME_S
|
|
335
|
+
)
|
|
336
|
+
transmission_frac, exposure_time_s = (
|
|
337
|
+
fix_transmission_and_exposure_time_for_current_wavelength(
|
|
338
|
+
_current_wavelength_a,
|
|
339
|
+
_assumed_wavelength_a,
|
|
340
|
+
_unscaled_transmission,
|
|
341
|
+
_unscaled_exposure_time_s,
|
|
342
|
+
)
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
return GridCommon(
|
|
346
|
+
sample_id=parameters.sample_id,
|
|
347
|
+
file_name=parameters.file_name,
|
|
348
|
+
visit=parameters.visit,
|
|
349
|
+
detector_distance_mm=parameters.detector_distance_mm,
|
|
350
|
+
storage_directory=parameters.storage_directory,
|
|
351
|
+
transmission_frac=transmission_frac,
|
|
352
|
+
exposure_time_s=exposure_time_s,
|
|
353
|
+
parameter_model_version=PARAMETER_VERSION,
|
|
354
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from functools import cache
|
|
2
|
+
|
|
3
|
+
from mx_bluesky.beamlines.i04.parameters.constants import (
|
|
4
|
+
I04FeatureSettings,
|
|
5
|
+
I04FeatureSettingsSources,
|
|
6
|
+
)
|
|
7
|
+
from mx_bluesky.common.external_interaction.config_server import MXConfigClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@cache
|
|
11
|
+
def get_i04_config_client() -> MXConfigClient[I04FeatureSettings]:
|
|
12
|
+
return MXConfigClient(
|
|
13
|
+
feature_sources=I04FeatureSettingsSources,
|
|
14
|
+
feature_dc=I04FeatureSettings,
|
|
15
|
+
)
|
|
File without changes
|