mx-bluesky 1.5.0__py3-none-any.whl → 1.5.2__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/i04/__init__.py +4 -1
- mx_bluesky/beamlines/i04/callbacks/murko_callback.py +56 -1
- mx_bluesky/beamlines/i04/experiment_plans/__init__.py +0 -0
- mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py +259 -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 +8 -6
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +4 -4
- 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 +3 -3
- mx_bluesky/common/device_setup_plans/robot_load_unload.py +123 -0
- mx_bluesky/common/experiment_plans/change_aperture_then_move_plan.py +5 -1
- mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py +27 -3
- mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py +1 -0
- mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py +3 -1
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +26 -24
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +11 -7
- mx_bluesky/common/external_interaction/nexus/write_nexus.py +2 -2
- mx_bluesky/common/parameters/__init__.py +0 -0
- mx_bluesky/common/parameters/components.py +7 -2
- mx_bluesky/common/parameters/constants.py +5 -3
- mx_bluesky/common/parameters/device_composites.py +1 -1
- mx_bluesky/common/parameters/gridscan.py +1 -0
- mx_bluesky/common/xrc_result.py +25 -2
- mx_bluesky/hyperion/__main__.py +1 -1
- mx_bluesky/hyperion/baton_handler.py +36 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +4 -93
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +19 -31
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +26 -8
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +21 -75
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +14 -9
- 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 +2 -7
- 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/hyperion/utils/context.py +19 -5
- mx_bluesky/phase1_zebra/__init__.py +1 -0
- mx_bluesky/phase1_zebra/device_setup_plans/__init__.py +0 -0
- mx_bluesky/phase1_zebra/device_setup_plans/setup_zebra.py +112 -0
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/METADATA +5 -4
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/RECORD +55 -49
- mx_bluesky/hyperion/utils/validation.py +0 -196
- /mx_bluesky/common/experiment_plans/{read_hardware.py → inner_plans/read_hardware.py} +0 -0
- /mx_bluesky/common/experiment_plans/{write_sample_status.py → inner_plans/write_sample_status.py} +0 -0
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/WHEEL +0 -0
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.5.0.dist-info → mx_bluesky-1.5.2.dist-info}/top_level.txt +0 -0
mx_bluesky/_version.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from mx_bluesky.beamlines.i04.experiment_plans import (
|
|
2
|
+
i04_grid_detect_then_xray_centre_plan,
|
|
3
|
+
)
|
|
1
4
|
from mx_bluesky.beamlines.i04.thawing_plan import thaw, thaw_and_stream_to_redis
|
|
2
5
|
|
|
3
|
-
__all__ = ["thaw", "thaw_and_stream_to_redis"]
|
|
6
|
+
__all__ = ["thaw", "thaw_and_stream_to_redis", "i04_grid_detect_then_xray_centre_plan"]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
import json
|
|
3
3
|
from datetime import timedelta
|
|
4
|
+
from typing import TypedDict
|
|
4
5
|
|
|
5
6
|
from bluesky.callbacks import CallbackBase
|
|
6
7
|
from dodal.log import LOGGER
|
|
@@ -8,7 +9,43 @@ from event_model.documents import Event, RunStart, RunStop
|
|
|
8
9
|
from redis import StrictRedis
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
class OmegaReading(TypedDict):
|
|
13
|
+
value: float
|
|
14
|
+
timestamp: float
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def extrapolate_omega(
|
|
18
|
+
latest_omega: OmegaReading, previous_omega: OmegaReading, image_timestamp: float
|
|
19
|
+
) -> float:
|
|
20
|
+
"""Extrapolate an image omega from previous omegas.
|
|
21
|
+
|
|
22
|
+
There are a number of assumptions in this calculation:
|
|
23
|
+
* The speed of the smargon is fixed
|
|
24
|
+
* The timestamps from the two different devices are synchronised and match the data
|
|
25
|
+
exactly
|
|
26
|
+
|
|
27
|
+
These are accepted to be reasonable based on larger errors likely coming from murko
|
|
28
|
+
itself and that the results ultimately will be averaged out.
|
|
29
|
+
"""
|
|
30
|
+
omega_per_sec = (latest_omega["value"] - previous_omega["value"]) / (
|
|
31
|
+
latest_omega["timestamp"] - previous_omega["timestamp"]
|
|
32
|
+
)
|
|
33
|
+
time_elapsed = image_timestamp - latest_omega["timestamp"]
|
|
34
|
+
return latest_omega["value"] + time_elapsed * omega_per_sec
|
|
35
|
+
|
|
36
|
+
|
|
11
37
|
class MurkoCallback(CallbackBase):
|
|
38
|
+
"""A callback that triggers murko processing of images.
|
|
39
|
+
|
|
40
|
+
It combines metadata readings from e.g the goniometer rotation with the uuid's given
|
|
41
|
+
to us by an `OAVToRedisForwarder` (which describe the location of images in redis).
|
|
42
|
+
And writes these as a package to redis. A separate service then forwards this to murko.
|
|
43
|
+
|
|
44
|
+
The metadata and image data arrive independently, it is expected that the image data
|
|
45
|
+
is arriving at a faster rate than gonio metadata and so the value of omega for when
|
|
46
|
+
the image arrives is extrapolated based on previous omega readings.
|
|
47
|
+
"""
|
|
48
|
+
|
|
12
49
|
DATA_EXPIRY_DAYS = 7
|
|
13
50
|
|
|
14
51
|
def __init__(self, redis_host: str, redis_password: str, redis_db: int = 0):
|
|
@@ -16,6 +53,7 @@ class MurkoCallback(CallbackBase):
|
|
|
16
53
|
host=redis_host, password=redis_password, db=redis_db
|
|
17
54
|
)
|
|
18
55
|
self.last_uuid = None
|
|
56
|
+
self.previous_omegas: list[OmegaReading] = []
|
|
19
57
|
|
|
20
58
|
def start(self, doc: RunStart) -> RunStart | None:
|
|
21
59
|
self.sample_id = doc.get("sample_id")
|
|
@@ -28,14 +66,31 @@ class MurkoCallback(CallbackBase):
|
|
|
28
66
|
"sample_id": self.sample_id,
|
|
29
67
|
}
|
|
30
68
|
self.last_uuid = None
|
|
69
|
+
self.previous_omegas = []
|
|
31
70
|
LOGGER.info(f"Starting to stream metadata to murko under {self.sample_id}")
|
|
32
71
|
return doc
|
|
33
72
|
|
|
34
73
|
def event(self, doc: Event) -> Event:
|
|
35
74
|
if latest_omega := doc["data"].get("smargon-omega"):
|
|
36
|
-
if self.
|
|
75
|
+
if len(self.previous_omegas) <= 2 and self.last_uuid:
|
|
76
|
+
# For the first few images there's not enough data to extrapolate so we
|
|
77
|
+
# match them one to one
|
|
37
78
|
self.call_murko(self.last_uuid, latest_omega)
|
|
79
|
+
self.previous_omegas.append(
|
|
80
|
+
OmegaReading(
|
|
81
|
+
value=latest_omega,
|
|
82
|
+
timestamp=doc["timestamps"]["smargon-omega"],
|
|
83
|
+
)
|
|
84
|
+
)
|
|
38
85
|
elif (uuid := doc["data"].get("oav_to_redis_forwarder-uuid")) is not None:
|
|
86
|
+
if len(self.previous_omegas) >= 2:
|
|
87
|
+
omega = extrapolate_omega(
|
|
88
|
+
self.previous_omegas[-1],
|
|
89
|
+
self.previous_omegas[-2],
|
|
90
|
+
doc["timestamps"]["oav_to_redis_forwarder-uuid"],
|
|
91
|
+
)
|
|
92
|
+
LOGGER.info(f"Using extrapolated omega of {omega}")
|
|
93
|
+
self.call_murko(uuid, omega)
|
|
39
94
|
self.last_uuid = uuid
|
|
40
95
|
return doc
|
|
41
96
|
|
|
File without changes
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from functools import partial
|
|
4
|
+
|
|
5
|
+
import bluesky.plan_stubs as bps
|
|
6
|
+
import bluesky.preprocessors as bpp
|
|
7
|
+
from blueapi.core import BlueskyContext
|
|
8
|
+
from bluesky.utils import MsgGenerator
|
|
9
|
+
from dodal.common import inject
|
|
10
|
+
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
11
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
12
|
+
from dodal.devices.backlight import Backlight
|
|
13
|
+
from dodal.devices.common_dcm import BaseDCM
|
|
14
|
+
from dodal.devices.detector.detector_motion import DetectorMotion
|
|
15
|
+
from dodal.devices.eiger import EigerDetector
|
|
16
|
+
from dodal.devices.fast_grid_scan import (
|
|
17
|
+
ZebraFastGridScan,
|
|
18
|
+
set_fast_grid_scan_params,
|
|
19
|
+
)
|
|
20
|
+
from dodal.devices.flux import Flux
|
|
21
|
+
from dodal.devices.mx_phase1.beamstop import Beamstop
|
|
22
|
+
from dodal.devices.oav.oav_detector import OAV
|
|
23
|
+
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
24
|
+
from dodal.devices.robot import BartRobot
|
|
25
|
+
from dodal.devices.s4_slit_gaps import S4SlitGaps
|
|
26
|
+
from dodal.devices.smargon import Smargon
|
|
27
|
+
from dodal.devices.synchrotron import Synchrotron
|
|
28
|
+
from dodal.devices.undulator import Undulator
|
|
29
|
+
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
30
|
+
from dodal.devices.zebra.zebra import Zebra
|
|
31
|
+
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
32
|
+
from dodal.devices.zocalo import ZocaloResults
|
|
33
|
+
from dodal.plans.preprocessors.verify_undulator_gap import (
|
|
34
|
+
verify_undulator_gap_before_run_decorator,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
from mx_bluesky.common.experiment_plans.common_flyscan_xray_centre_plan import (
|
|
38
|
+
BeamlineSpecificFGSFeatures,
|
|
39
|
+
construct_beamline_specific_FGS_features,
|
|
40
|
+
)
|
|
41
|
+
from mx_bluesky.common.experiment_plans.common_grid_detect_then_xray_centre_plan import (
|
|
42
|
+
grid_detect_then_xray_centre,
|
|
43
|
+
)
|
|
44
|
+
from mx_bluesky.common.experiment_plans.oav_snapshot_plan import (
|
|
45
|
+
setup_beamline_for_OAV,
|
|
46
|
+
)
|
|
47
|
+
from mx_bluesky.common.external_interaction.callbacks.common.zocalo_callback import (
|
|
48
|
+
ZocaloCallback,
|
|
49
|
+
)
|
|
50
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
51
|
+
GridscanISPyBCallback,
|
|
52
|
+
)
|
|
53
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
|
|
54
|
+
GridscanNexusFileCallback,
|
|
55
|
+
)
|
|
56
|
+
from mx_bluesky.common.parameters.constants import (
|
|
57
|
+
EnvironmentConstants,
|
|
58
|
+
OavConstants,
|
|
59
|
+
PlanGroupCheckpointConstants,
|
|
60
|
+
PlanNameConstants,
|
|
61
|
+
)
|
|
62
|
+
from mx_bluesky.common.parameters.device_composites import (
|
|
63
|
+
GridDetectThenXRayCentreComposite,
|
|
64
|
+
)
|
|
65
|
+
from mx_bluesky.common.parameters.gridscan import GridCommon, SpecifiedThreeDGridScan
|
|
66
|
+
from mx_bluesky.common.preprocessors.preprocessors import (
|
|
67
|
+
transmission_and_xbpm_feedback_for_collection_decorator,
|
|
68
|
+
)
|
|
69
|
+
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
70
|
+
from mx_bluesky.phase1_zebra.device_setup_plans.setup_zebra import (
|
|
71
|
+
setup_zebra_for_gridscan,
|
|
72
|
+
tidy_up_zebra_after_gridscan,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def create_devices(
|
|
77
|
+
context: BlueskyContext,
|
|
78
|
+
) -> GridDetectThenXRayCentreComposite:
|
|
79
|
+
return device_composite_from_context(context, GridDetectThenXRayCentreComposite)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# See https://github.com/DiamondLightSource/blueapi/issues/506 for using device composites
|
|
83
|
+
def i04_grid_detect_then_xray_centre(
|
|
84
|
+
parameters: GridCommon,
|
|
85
|
+
aperture_scatterguard: ApertureScatterguard = inject("aperture_scatterguard"),
|
|
86
|
+
attenuator: BinaryFilterAttenuator = inject("attenuator"),
|
|
87
|
+
backlight: Backlight = inject("backlight"),
|
|
88
|
+
beamstop: Beamstop = inject("beamstop"),
|
|
89
|
+
dcm: BaseDCM = inject("dcm"),
|
|
90
|
+
zebra_fast_grid_scan: ZebraFastGridScan = inject("zebra_fast_grid_scan"),
|
|
91
|
+
flux: Flux = inject("flux"),
|
|
92
|
+
oav: OAV = inject("oav"),
|
|
93
|
+
pin_tip_detection: PinTipDetection = inject("pin_tip_detection"),
|
|
94
|
+
s4_slit_gaps: S4SlitGaps = inject("s4_slit_gaps"),
|
|
95
|
+
undulator: Undulator = inject("undulator"),
|
|
96
|
+
xbpm_feedback: XBPMFeedback = inject("xbpm_feedback"),
|
|
97
|
+
zebra: Zebra = inject("zebra"),
|
|
98
|
+
robot: BartRobot = inject("robot"),
|
|
99
|
+
sample_shutter: ZebraShutter = inject("sample_shutter"),
|
|
100
|
+
eiger: EigerDetector = inject("eiger"),
|
|
101
|
+
synchrotron: Synchrotron = inject("synchrotron"),
|
|
102
|
+
zocalo: ZocaloResults = inject("zocalo"),
|
|
103
|
+
smargon: Smargon = inject("smargon"),
|
|
104
|
+
detector_motion: DetectorMotion = inject("detector_motion"),
|
|
105
|
+
oav_config: str = OavConstants.OAV_CONFIG_JSON,
|
|
106
|
+
udc: bool = False,
|
|
107
|
+
) -> MsgGenerator:
|
|
108
|
+
"""
|
|
109
|
+
A composite plan which:
|
|
110
|
+
- Uses the OAV to draw a virtual grid over the sample and to take snapshots of the sample
|
|
111
|
+
- Scans through the grid to identify the crystal centre
|
|
112
|
+
- Changes the aperture to match the beam size to the crystal size
|
|
113
|
+
- Moves the sample to the crystal centre of mass
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
i04's implementation of this plan is very similar to Hyperion. However, since i04
|
|
117
|
+
isn't running in a continious Bluesky UDC loop, we take additional steps in beamline
|
|
118
|
+
tidy-up.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
composite = GridDetectThenXRayCentreComposite(
|
|
122
|
+
eiger,
|
|
123
|
+
synchrotron,
|
|
124
|
+
zocalo,
|
|
125
|
+
smargon,
|
|
126
|
+
aperture_scatterguard,
|
|
127
|
+
attenuator,
|
|
128
|
+
backlight,
|
|
129
|
+
beamstop,
|
|
130
|
+
dcm,
|
|
131
|
+
detector_motion,
|
|
132
|
+
zebra_fast_grid_scan,
|
|
133
|
+
flux,
|
|
134
|
+
oav,
|
|
135
|
+
pin_tip_detection,
|
|
136
|
+
s4_slit_gaps,
|
|
137
|
+
undulator,
|
|
138
|
+
xbpm_feedback,
|
|
139
|
+
zebra,
|
|
140
|
+
robot,
|
|
141
|
+
sample_shutter,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def tidy_beamline_if_not_udc():
|
|
145
|
+
if not udc:
|
|
146
|
+
yield from get_ready_for_oav_and_close_shutter(
|
|
147
|
+
composite.smargon,
|
|
148
|
+
composite.backlight,
|
|
149
|
+
composite.aperture_scatterguard,
|
|
150
|
+
composite.detector_motion,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
@bpp.finalize_decorator(tidy_beamline_if_not_udc)
|
|
154
|
+
def _inner_grid_detect_then_xrc():
|
|
155
|
+
# These callbacks let us talk to ISPyB and Nexgen. They aren't included in the common plan because
|
|
156
|
+
# Hyperion handles its callbacks differently to BlueAPI-managed plans, see
|
|
157
|
+
# https://github.com/DiamondLightSource/mx-bluesky/issues/1117
|
|
158
|
+
callbacks = create_gridscan_callbacks()
|
|
159
|
+
|
|
160
|
+
@bpp.subs_decorator(callbacks)
|
|
161
|
+
@verify_undulator_gap_before_run_decorator(composite)
|
|
162
|
+
@transmission_and_xbpm_feedback_for_collection_decorator(
|
|
163
|
+
composite, parameters.transmission_frac, PlanNameConstants.GRIDSCAN_OUTER
|
|
164
|
+
)
|
|
165
|
+
def grid_detect_then_xray_centre_with_callbacks():
|
|
166
|
+
yield from grid_detect_then_xray_centre(
|
|
167
|
+
composite=composite,
|
|
168
|
+
parameters=parameters,
|
|
169
|
+
xrc_params_type=SpecifiedThreeDGridScan,
|
|
170
|
+
construct_beamline_specific=construct_i04_specific_features,
|
|
171
|
+
oav_config=oav_config,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
yield from grid_detect_then_xray_centre_with_callbacks()
|
|
175
|
+
|
|
176
|
+
yield from _inner_grid_detect_then_xrc()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def get_ready_for_oav_and_close_shutter(
|
|
180
|
+
smargon: Smargon,
|
|
181
|
+
backlight: Backlight,
|
|
182
|
+
aperture_scatterguard: ApertureScatterguard,
|
|
183
|
+
detector_motion: DetectorMotion,
|
|
184
|
+
):
|
|
185
|
+
yield from bps.wait(PlanGroupCheckpointConstants.GRID_READY_FOR_DC)
|
|
186
|
+
group = "get_ready_for_oav_and_close_shutter"
|
|
187
|
+
yield from setup_beamline_for_OAV(
|
|
188
|
+
smargon, backlight, aperture_scatterguard, group=group
|
|
189
|
+
)
|
|
190
|
+
yield from bps.abs_set(
|
|
191
|
+
detector_motion.shutter,
|
|
192
|
+
0,
|
|
193
|
+
group=group,
|
|
194
|
+
)
|
|
195
|
+
yield from bps.wait(group)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def create_gridscan_callbacks() -> tuple[
|
|
199
|
+
GridscanNexusFileCallback, GridscanISPyBCallback
|
|
200
|
+
]:
|
|
201
|
+
return (
|
|
202
|
+
GridscanNexusFileCallback(param_type=SpecifiedThreeDGridScan),
|
|
203
|
+
GridscanISPyBCallback(
|
|
204
|
+
param_type=GridCommon,
|
|
205
|
+
emit=ZocaloCallback(
|
|
206
|
+
PlanNameConstants.DO_FGS, EnvironmentConstants.ZOCALO_ENV
|
|
207
|
+
),
|
|
208
|
+
),
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def construct_i04_specific_features(
|
|
213
|
+
xrc_composite: GridDetectThenXRayCentreComposite,
|
|
214
|
+
xrc_parameters: SpecifiedThreeDGridScan,
|
|
215
|
+
) -> BeamlineSpecificFGSFeatures:
|
|
216
|
+
"""
|
|
217
|
+
Get all the information needed to do the i04 XRC flyscan.
|
|
218
|
+
"""
|
|
219
|
+
signals_to_read_pre_flyscan = [
|
|
220
|
+
xrc_composite.undulator.current_gap,
|
|
221
|
+
xrc_composite.synchrotron.synchrotron_mode,
|
|
222
|
+
xrc_composite.s4_slit_gaps.xgap,
|
|
223
|
+
xrc_composite.s4_slit_gaps.ygap,
|
|
224
|
+
xrc_composite.smargon.x,
|
|
225
|
+
xrc_composite.smargon.y,
|
|
226
|
+
xrc_composite.smargon.z,
|
|
227
|
+
xrc_composite.dcm.energy_in_kev,
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
signals_to_read_during_collection = [
|
|
231
|
+
xrc_composite.aperture_scatterguard,
|
|
232
|
+
xrc_composite.attenuator.actual_transmission,
|
|
233
|
+
xrc_composite.flux.flux_reading,
|
|
234
|
+
xrc_composite.dcm.energy_in_kev,
|
|
235
|
+
xrc_composite.eiger.bit_depth,
|
|
236
|
+
]
|
|
237
|
+
|
|
238
|
+
tidy_plan = partial(
|
|
239
|
+
tidy_up_zebra_after_gridscan,
|
|
240
|
+
xrc_composite.zebra,
|
|
241
|
+
xrc_composite.sample_shutter,
|
|
242
|
+
group="flyscan_zebra_tidy",
|
|
243
|
+
wait=True,
|
|
244
|
+
)
|
|
245
|
+
set_flyscan_params_plan = partial(
|
|
246
|
+
set_fast_grid_scan_params,
|
|
247
|
+
xrc_composite.zebra_fast_grid_scan,
|
|
248
|
+
xrc_parameters.FGS_params,
|
|
249
|
+
)
|
|
250
|
+
fgs_motors = xrc_composite.zebra_fast_grid_scan
|
|
251
|
+
return construct_beamline_specific_FGS_features(
|
|
252
|
+
setup_zebra_for_gridscan,
|
|
253
|
+
tidy_plan,
|
|
254
|
+
set_flyscan_params_plan,
|
|
255
|
+
fgs_motors,
|
|
256
|
+
signals_to_read_pre_flyscan,
|
|
257
|
+
signals_to_read_during_collection,
|
|
258
|
+
get_xrc_results_from_zocalo=True,
|
|
259
|
+
)
|
|
@@ -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,
|
|
@@ -490,7 +490,9 @@ def run_aborted_plan(pmac: PMAC, dcid: DCID, exception: Exception):
|
|
|
490
490
|
either by pressing the Abort button or because of a timeout, and to reset the \
|
|
491
491
|
P variable.
|
|
492
492
|
"""
|
|
493
|
-
SSX_LOGGER.warning(
|
|
493
|
+
SSX_LOGGER.warning(
|
|
494
|
+
f"Data Collection Aborted: {''.join(format_exception(exception))}"
|
|
495
|
+
)
|
|
494
496
|
yield from bps.trigger(pmac.abort_program, wait=True)
|
|
495
497
|
|
|
496
498
|
end_time = datetime.now()
|
|
@@ -504,7 +506,7 @@ def main_fixed_target_plan(
|
|
|
504
506
|
aperture: Aperture,
|
|
505
507
|
backlight: DualBacklight,
|
|
506
508
|
beamstop: Beamstop,
|
|
507
|
-
detector_stage:
|
|
509
|
+
detector_stage: YZStage,
|
|
508
510
|
shutter: HutchShutter,
|
|
509
511
|
dcm: DCM,
|
|
510
512
|
mirrors: FocusMirrorsMode,
|
|
@@ -655,7 +657,7 @@ def run_fixed_target_plan(
|
|
|
655
657
|
aperture: Aperture = inject("aperture"),
|
|
656
658
|
backlight: DualBacklight = inject("backlight"),
|
|
657
659
|
beamstop: Beamstop = inject("beamstop"),
|
|
658
|
-
detector_stage:
|
|
660
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
659
661
|
shutter: HutchShutter = inject("shutter"),
|
|
660
662
|
dcm: DCM = inject("dcm"),
|
|
661
663
|
mirrors: FocusMirrorsMode = inject("focus_mirrors"),
|
|
@@ -707,7 +709,7 @@ def run_plan_in_wrapper(
|
|
|
707
709
|
aperture: Aperture,
|
|
708
710
|
backlight: DualBacklight,
|
|
709
711
|
beamstop: Beamstop,
|
|
710
|
-
detector_stage:
|
|
712
|
+
detector_stage: YZStage,
|
|
711
713
|
shutter: HutchShutter,
|
|
712
714
|
dcm: DCM,
|
|
713
715
|
mirrors: FocusMirrorsMode,
|
|
@@ -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
|
|
|
@@ -566,7 +566,7 @@ def moveto_preset(
|
|
|
566
566
|
pmac: PMAC = inject("pmac"),
|
|
567
567
|
beamstop: Beamstop = inject("beamstop"),
|
|
568
568
|
backlight: DualBacklight = inject("backlight"),
|
|
569
|
-
det_stage:
|
|
569
|
+
det_stage: YZStage = inject("detector_motion"),
|
|
570
570
|
) -> MsgGenerator:
|
|
571
571
|
# Non Chip Specific Move
|
|
572
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
|
|
@@ -13,9 +13,9 @@ from dodal.devices.i24.beamstop import Beamstop
|
|
|
13
13
|
from dodal.devices.i24.dcm import DCM
|
|
14
14
|
from dodal.devices.i24.dual_backlight import BacklightPositions, DualBacklight
|
|
15
15
|
from dodal.devices.i24.focus_mirrors import FocusMirrorsMode
|
|
16
|
-
from dodal.devices.i24.i24_detector_motion import DetectorMotion
|
|
17
16
|
from dodal.devices.i24.pilatus_metadata import PilatusMetadata
|
|
18
17
|
from dodal.devices.i24.pmac import PMAC
|
|
18
|
+
from dodal.devices.motors import YZStage
|
|
19
19
|
from dodal.devices.oav.oav_detector import OAVBeamCentreFile
|
|
20
20
|
from dodal.devices.zebra.zebra import Zebra
|
|
21
21
|
|
|
@@ -104,7 +104,7 @@ def gui_sleep(sec: int) -> MsgGenerator:
|
|
|
104
104
|
@bpp.run_decorator()
|
|
105
105
|
def gui_move_detector(
|
|
106
106
|
det: Literal["eiger", "pilatus"],
|
|
107
|
-
detector_stage:
|
|
107
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
108
108
|
) -> MsgGenerator:
|
|
109
109
|
det_y_target = Eiger.det_y_target if det == "eiger" else Pilatus.det_y_target
|
|
110
110
|
yield from _move_detector_stage(detector_stage, det_y_target)
|
|
@@ -134,7 +134,7 @@ def gui_run_chip_collection(
|
|
|
134
134
|
aperture: Aperture = inject("aperture"),
|
|
135
135
|
backlight: DualBacklight = inject("backlight"),
|
|
136
136
|
beamstop: Beamstop = inject("beamstop"),
|
|
137
|
-
detector_stage:
|
|
137
|
+
detector_stage: YZStage = inject("detector_motion"),
|
|
138
138
|
shutter: HutchShutter = inject("shutter"),
|
|
139
139
|
dcm: DCM = inject("dcm"),
|
|
140
140
|
mirrors: FocusMirrorsMode = inject("focus_mirrors"),
|