mx-bluesky 1.4.5__py3-none-any.whl → 1.4.6__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 +9 -4
- mx_bluesky/beamlines/i04/redis_to_murko_forwarder.py +14 -3
- mx_bluesky/beamlines/i04/thawing_plan.py +9 -13
- mx_bluesky/beamlines/i24/serial/__init__.py +14 -0
- mx_bluesky/beamlines/i24/serial/dcid.py +3 -1
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +1 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +6 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +11 -11
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +1 -1
- mx_bluesky/beamlines/i24/serial/log.py +0 -1
- mx_bluesky/beamlines/i24/serial/parameters/constants.py +1 -1
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +1 -1
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +1 -1
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +2 -2
- mx_bluesky/beamlines/i24/serial/web_gui_plans/__init__.py +0 -0
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +109 -0
- mx_bluesky/beamlines/i24/serial/write_nexus.py +2 -2
- mx_bluesky/common/external_interaction/callbacks/common/plan_reactive_callback.py +2 -2
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +2 -2
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_mapping.py +1 -1
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +6 -2
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +7 -0
- mx_bluesky/common/parameters/constants.py +1 -1
- mx_bluesky/common/parameters/gridscan.py +36 -1
- mx_bluesky/common/plans/do_fgs.py +4 -6
- mx_bluesky/common/plans/read_hardware.py +78 -0
- mx_bluesky/common/utils/context.py +68 -0
- mx_bluesky/{hyperion/experiment_plans/common → common}/xrc_result.py +16 -0
- mx_bluesky/hyperion/__main__.py +4 -0
- mx_bluesky/hyperion/device_setup_plans/setup_oav.py +5 -5
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +2 -2
- mx_bluesky/hyperion/device_setup_plans/smargon.py +6 -6
- mx_bluesky/hyperion/device_setup_plans/utils.py +2 -2
- mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +4 -4
- mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +2 -6
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +33 -87
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +6 -6
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +3 -5
- mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +11 -11
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +4 -4
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +1 -1
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +2 -4
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +10 -10
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +10 -10
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +2 -4
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +7 -9
- mx_bluesky/hyperion/external_interaction/agamemnon.py +104 -0
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +14 -9
- mx_bluesky/hyperion/external_interaction/config_server.py +6 -6
- mx_bluesky/hyperion/parameters/device_composites.py +49 -0
- mx_bluesky/hyperion/parameters/gridscan.py +1 -1
- mx_bluesky/hyperion/utils/__init__.py +1 -0
- mx_bluesky/hyperion/utils/context.py +0 -65
- mx_bluesky/hyperion/utils/validation.py +3 -3
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/METADATA +4 -3
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/RECORD +61 -56
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/WHEEL +1 -1
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/entry_points.txt +1 -0
- mx_bluesky/common/device_setup_plans/read_hardware_for_setup.py +0 -14
- mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +0 -54
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/LICENSE +0 -0
- {mx_bluesky-1.4.5.dist-info → mx_bluesky-1.4.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import bluesky.plan_stubs as bps
|
|
4
|
+
from bluesky.protocols import Readable
|
|
5
|
+
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
6
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
7
|
+
from dodal.devices.dcm import DCM
|
|
8
|
+
from dodal.devices.eiger import EigerDetector
|
|
9
|
+
from dodal.devices.flux import Flux
|
|
10
|
+
from dodal.devices.s4_slit_gaps import S4SlitGaps
|
|
11
|
+
from dodal.devices.smargon import Smargon
|
|
12
|
+
from dodal.devices.synchrotron import Synchrotron
|
|
13
|
+
from dodal.devices.undulator import Undulator
|
|
14
|
+
|
|
15
|
+
from mx_bluesky.common.parameters.constants import (
|
|
16
|
+
DocDescriptorNames,
|
|
17
|
+
)
|
|
18
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def read_hardware_plan(
|
|
22
|
+
signals: list[Readable],
|
|
23
|
+
event_name: str,
|
|
24
|
+
):
|
|
25
|
+
LOGGER.info(f"Reading status of beamline for event, {event_name}")
|
|
26
|
+
yield from bps.create(name=event_name)
|
|
27
|
+
for signal in signals:
|
|
28
|
+
yield from bps.read(signal)
|
|
29
|
+
yield from bps.save()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def read_hardware_for_zocalo(detector: EigerDetector):
|
|
33
|
+
""" "
|
|
34
|
+
If the RunEngine is subscribed to the ZocaloCallback, this plan will also trigger zocalo.
|
|
35
|
+
"""
|
|
36
|
+
yield from read_hardware_plan(
|
|
37
|
+
[detector.odin.file_writer.id], # type: ignore
|
|
38
|
+
DocDescriptorNames.ZOCALO_HW_READ,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def standard_read_hardware_pre_collection(
|
|
43
|
+
undulator: Undulator,
|
|
44
|
+
synchrotron: Synchrotron,
|
|
45
|
+
s4_slit_gaps: S4SlitGaps,
|
|
46
|
+
dcm: DCM,
|
|
47
|
+
smargon: Smargon,
|
|
48
|
+
):
|
|
49
|
+
LOGGER.info("Reading status of beamline for callbacks, pre collection.")
|
|
50
|
+
signals_to_read_pre_flyscan = [
|
|
51
|
+
undulator.current_gap,
|
|
52
|
+
synchrotron.synchrotron_mode,
|
|
53
|
+
s4_slit_gaps,
|
|
54
|
+
smargon,
|
|
55
|
+
dcm.energy_in_kev,
|
|
56
|
+
]
|
|
57
|
+
yield from read_hardware_plan(
|
|
58
|
+
signals_to_read_pre_flyscan, DocDescriptorNames.HARDWARE_READ_PRE
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def standard_read_hardware_during_collection(
|
|
63
|
+
aperture_scatterguard: ApertureScatterguard,
|
|
64
|
+
attenuator: BinaryFilterAttenuator,
|
|
65
|
+
flux: Flux,
|
|
66
|
+
dcm: DCM,
|
|
67
|
+
detector: EigerDetector,
|
|
68
|
+
):
|
|
69
|
+
signals_to_read_during_collection = [
|
|
70
|
+
aperture_scatterguard,
|
|
71
|
+
attenuator.actual_transmission,
|
|
72
|
+
flux.flux_reading,
|
|
73
|
+
dcm.energy_in_kev,
|
|
74
|
+
detector.bit_depth,
|
|
75
|
+
]
|
|
76
|
+
yield from read_hardware_plan(
|
|
77
|
+
signals_to_read_during_collection, DocDescriptorNames.HARDWARE_READ_DURING
|
|
78
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
from typing import Any, ClassVar, Protocol, TypeVar, get_type_hints
|
|
3
|
+
|
|
4
|
+
from blueapi.core import BlueskyContext
|
|
5
|
+
from blueapi.core.bluesky_types import Device
|
|
6
|
+
|
|
7
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T", bound=Device)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class _IsDataclass(Protocol):
|
|
13
|
+
"""Protocol followed by any dataclass"""
|
|
14
|
+
|
|
15
|
+
__dataclass_fields__: ClassVar[dict]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
DT = TypeVar("DT", bound=_IsDataclass)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def find_device_in_context(
|
|
22
|
+
context: BlueskyContext,
|
|
23
|
+
name: str,
|
|
24
|
+
# Typing in here is wrong (see https://github.com/microsoft/pyright/issues/7228#issuecomment-1934500232)
|
|
25
|
+
# but this whole thing will go away when we do https://github.com/DiamondLightSource/hyperion/issues/868
|
|
26
|
+
expected_type: type[T] = Device, # type: ignore
|
|
27
|
+
) -> T:
|
|
28
|
+
LOGGER.debug(f"Looking for device {name} of type {expected_type} in context")
|
|
29
|
+
|
|
30
|
+
device = context.find_device(name)
|
|
31
|
+
if device is None:
|
|
32
|
+
raise ValueError(
|
|
33
|
+
f"Cannot find device named '{name}' in bluesky context {context.devices}."
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if not isinstance(device, expected_type):
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f"Found device named '{name}' and expected it to be a '{expected_type}' but it was a '{device.__class__.__name__}'"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
LOGGER.debug(f"Found matching device {device}")
|
|
42
|
+
return device
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def device_composite_from_context(context: BlueskyContext, dc: type[DT]) -> DT:
|
|
46
|
+
"""
|
|
47
|
+
Initializes all of the devices referenced in a given dataclass from a provided
|
|
48
|
+
context, checking that the types of devices returned by the context are compatible
|
|
49
|
+
with the type annotations of the dataclass.
|
|
50
|
+
|
|
51
|
+
Note that if the context was not created with `wait_for_connection=True` devices may
|
|
52
|
+
still be unconnected.
|
|
53
|
+
"""
|
|
54
|
+
LOGGER.debug(
|
|
55
|
+
f"Attempting to initialize devices referenced in dataclass {dc} from blueapi context"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
devices: dict[str, Any] = {}
|
|
59
|
+
dc_type_hints: dict[str, Any] = get_type_hints(dc)
|
|
60
|
+
|
|
61
|
+
for field in dataclasses.fields(dc):
|
|
62
|
+
device = find_device_in_context(
|
|
63
|
+
context, field.name, expected_type=dc_type_hints.get(field.name, Device)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
devices[field.name] = device
|
|
67
|
+
|
|
68
|
+
return dc(**devices)
|
|
@@ -5,6 +5,8 @@ from collections.abc import Callable, Sequence
|
|
|
5
5
|
from functools import partial
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
|
+
from bluesky.callbacks import CallbackBase
|
|
9
|
+
from event_model import RunStart
|
|
8
10
|
|
|
9
11
|
from mx_bluesky.common.parameters.components import (
|
|
10
12
|
MultiXtalSelection,
|
|
@@ -12,6 +14,20 @@ from mx_bluesky.common.parameters.components import (
|
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
|
|
17
|
+
class XRayCentreEventHandler(CallbackBase):
|
|
18
|
+
def __init__(self):
|
|
19
|
+
super().__init__()
|
|
20
|
+
self.xray_centre_results: Sequence[XRayCentreResult] | None = None
|
|
21
|
+
|
|
22
|
+
def start(self, doc: RunStart) -> RunStart | None:
|
|
23
|
+
if "xray_centre_results" in doc:
|
|
24
|
+
self.xray_centre_results = [
|
|
25
|
+
XRayCentreResult(**result_dict)
|
|
26
|
+
for result_dict in doc["xray_centre_results"] # type: ignore
|
|
27
|
+
]
|
|
28
|
+
return doc
|
|
29
|
+
|
|
30
|
+
|
|
15
31
|
@dataclasses.dataclass
|
|
16
32
|
class XRayCentreResult:
|
|
17
33
|
"""
|
mx_bluesky/hyperion/__main__.py
CHANGED
|
@@ -38,6 +38,9 @@ from mx_bluesky.hyperion.experiment_plans.experiment_registry import (
|
|
|
38
38
|
PLAN_REGISTRY,
|
|
39
39
|
PlanNotFound,
|
|
40
40
|
)
|
|
41
|
+
from mx_bluesky.hyperion.external_interaction.agamemnon import (
|
|
42
|
+
update_params_from_agamemnon,
|
|
43
|
+
)
|
|
41
44
|
from mx_bluesky.hyperion.parameters.cli import parse_cli_args
|
|
42
45
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
43
46
|
from mx_bluesky.hyperion.utils.context import setup_context
|
|
@@ -208,6 +211,7 @@ def compose_start_args(context: BlueskyContext, plan_name: str, action: Actions)
|
|
|
208
211
|
)
|
|
209
212
|
try:
|
|
210
213
|
parameters = experiment_internal_param_type(**json.loads(request.data))
|
|
214
|
+
parameters = update_params_from_agamemnon(parameters)
|
|
211
215
|
if parameters.model_extra:
|
|
212
216
|
raise ValueError(f"Extra fields not allowed {parameters.model_extra}")
|
|
213
217
|
except Exception as e:
|
|
@@ -55,14 +55,14 @@ def setup_pin_tip_detection_params(
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
def setup_general_oav_params(oav: OAV, parameters: OAVParameters):
|
|
58
|
-
yield from set_using_group(oav.cam.color_mode, ColorMode.RGB1)
|
|
59
|
-
yield from set_using_group(oav.cam.acquire_period, parameters.acquire_period)
|
|
60
|
-
yield from set_using_group(oav.cam.acquire_time, parameters.exposure)
|
|
61
|
-
yield from set_using_group(oav.cam.gain, parameters.gain)
|
|
58
|
+
yield from set_using_group(oav.cam.color_mode, ColorMode.RGB1)
|
|
59
|
+
yield from set_using_group(oav.cam.acquire_period, parameters.acquire_period)
|
|
60
|
+
yield from set_using_group(oav.cam.acquire_time, parameters.exposure)
|
|
61
|
+
yield from set_using_group(oav.cam.gain, parameters.gain)
|
|
62
62
|
|
|
63
63
|
zoom_level_str = f"{float(parameters.zoom)}x"
|
|
64
64
|
yield from bps.abs_set(
|
|
65
|
-
oav.zoom_controller,
|
|
65
|
+
oav.zoom_controller,
|
|
66
66
|
zoom_level_str,
|
|
67
67
|
wait=True,
|
|
68
68
|
)
|
|
@@ -47,7 +47,7 @@ def bluesky_retry(func: Callable):
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def arm_zebra(zebra: Zebra):
|
|
50
|
-
yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True)
|
|
50
|
+
yield from bps.abs_set(zebra.pc.arm, ArmDemand.ARM, wait=True)
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def tidy_up_zebra_after_rotation_scan(
|
|
@@ -56,7 +56,7 @@ def tidy_up_zebra_after_rotation_scan(
|
|
|
56
56
|
group="tidy_up_zebra_after_rotation",
|
|
57
57
|
wait=True,
|
|
58
58
|
):
|
|
59
|
-
yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, group=group)
|
|
59
|
+
yield from bps.abs_set(zebra.pc.arm, ArmDemand.DISARM, group=group)
|
|
60
60
|
yield from bps.abs_set(
|
|
61
61
|
zebra_shutter.control_mode, ZebraShutterControl.MANUAL, group=group
|
|
62
62
|
)
|
|
@@ -16,10 +16,10 @@ def move_smargon_warn_on_out_of_range(
|
|
|
16
16
|
"Pin tip centring failed - pin too long/short/bent and out of range"
|
|
17
17
|
)
|
|
18
18
|
yield from bps.mv(
|
|
19
|
-
smargon.x,
|
|
20
|
-
position[0],
|
|
21
|
-
smargon.y,
|
|
22
|
-
position[1],
|
|
23
|
-
smargon.z,
|
|
24
|
-
position[2],
|
|
19
|
+
smargon.x,
|
|
20
|
+
position[0],
|
|
21
|
+
smargon.y,
|
|
22
|
+
position[1],
|
|
23
|
+
smargon.z,
|
|
24
|
+
position[2],
|
|
25
25
|
)
|
|
@@ -44,7 +44,7 @@ def start_preparing_data_collection_then_do_plan(
|
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
def wrapped_plan():
|
|
47
|
-
yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore #
|
|
47
|
+
yield from bps.abs_set(eiger.do_arm, 1, group=group) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
48
48
|
if detector_distance_mm:
|
|
49
49
|
yield from set_detector_z_position(
|
|
50
50
|
detector_motion, detector_distance_mm, group
|
|
@@ -55,5 +55,5 @@ def start_preparing_data_collection_then_do_plan(
|
|
|
55
55
|
yield from check_beamstop(beamstop)
|
|
56
56
|
yield from bpp.contingency_wrapper(
|
|
57
57
|
wrapped_plan(),
|
|
58
|
-
except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore #
|
|
58
|
+
except_plan=lambda e: (yield from bps.stop(eiger)), # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
59
59
|
)
|
|
@@ -25,14 +25,14 @@ def _check_and_pause_feedback(
|
|
|
25
25
|
turning XBPM feedback off.
|
|
26
26
|
|
|
27
27
|
"""
|
|
28
|
-
yield from bps.mv(attenuator, 1.0)
|
|
28
|
+
yield from bps.mv(attenuator, 1.0)
|
|
29
29
|
LOGGER.info("Waiting for XBPM feedback to be stable")
|
|
30
30
|
yield from bps.trigger(xbpm_feedback, wait=True)
|
|
31
31
|
LOGGER.info(
|
|
32
32
|
f"XPBM feedback in position, pausing and setting transmission to {desired_transmission_fraction}"
|
|
33
33
|
)
|
|
34
|
-
yield from bps.mv(xbpm_feedback.pause_feedback, Pause.PAUSE)
|
|
35
|
-
yield from bps.mv(attenuator, desired_transmission_fraction)
|
|
34
|
+
yield from bps.mv(xbpm_feedback.pause_feedback, Pause.PAUSE)
|
|
35
|
+
yield from bps.mv(attenuator, desired_transmission_fraction)
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def _unpause_xbpm_feedback_and_set_transmission_to_1(
|
|
@@ -46,7 +46,7 @@ def _unpause_xbpm_feedback_and_set_transmission_to_1(
|
|
|
46
46
|
the beam in position
|
|
47
47
|
attenuator (BinaryFilterAttenuator): The attenuator used to set transmission
|
|
48
48
|
"""
|
|
49
|
-
yield from bps.mv(xbpm_feedback.pause_feedback, Pause.RUN, attenuator, 1.0)
|
|
49
|
+
yield from bps.mv(xbpm_feedback.pause_feedback, Pause.RUN, attenuator, 1.0)
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def transmission_and_xbpm_feedback_for_collection_wrapper(
|
|
@@ -6,8 +6,8 @@ from dodal.devices.smargon import Smargon, StubPosition
|
|
|
6
6
|
|
|
7
7
|
from mx_bluesky.common.utils.log import LOGGER
|
|
8
8
|
from mx_bluesky.common.utils.tracing import TRACER
|
|
9
|
+
from mx_bluesky.common.xrc_result import XRayCentreResult
|
|
9
10
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_x_y_z
|
|
10
|
-
from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult
|
|
11
11
|
from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
|
|
12
12
|
|
|
13
13
|
|
|
@@ -43,11 +43,7 @@ def change_aperture_then_move_to_xtal(
|
|
|
43
43
|
# https://github.com/DiamondLightSource/mx-bluesky/issues/552
|
|
44
44
|
if parameters and parameters.FGS_params.set_stub_offsets:
|
|
45
45
|
LOGGER.info("Recentring smargon co-ordinate system to this point.")
|
|
46
|
-
yield from bps.mv(
|
|
47
|
-
# See: https://github.com/bluesky/bluesky/issues/1809
|
|
48
|
-
smargon.stub_offsets, # type: ignore
|
|
49
|
-
StubPosition.CURRENT_AS_CENTER, # type: ignore
|
|
50
|
-
)
|
|
46
|
+
yield from bps.mv(smargon.stub_offsets, StubPosition.CURRENT_AS_CENTER)
|
|
51
47
|
|
|
52
48
|
|
|
53
49
|
def set_aperture_for_bbox_mm(
|
|
@@ -9,59 +9,39 @@ from typing import Protocol
|
|
|
9
9
|
import bluesky.plan_stubs as bps
|
|
10
10
|
import bluesky.preprocessors as bpp
|
|
11
11
|
import numpy as np
|
|
12
|
-
import pydantic
|
|
13
12
|
from blueapi.core import BlueskyContext
|
|
14
|
-
from bluesky.callbacks import CallbackBase
|
|
15
13
|
from bluesky.utils import MsgGenerator
|
|
16
|
-
from dodal.devices.aperturescatterguard import (
|
|
17
|
-
ApertureScatterguard,
|
|
18
|
-
)
|
|
19
|
-
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
20
|
-
from dodal.devices.backlight import Backlight
|
|
21
|
-
from dodal.devices.dcm import DCM
|
|
22
|
-
from dodal.devices.eiger import EigerDetector
|
|
23
14
|
from dodal.devices.fast_grid_scan import (
|
|
24
15
|
FastGridScanCommon,
|
|
25
|
-
PandAFastGridScan,
|
|
26
|
-
ZebraFastGridScan,
|
|
27
16
|
)
|
|
28
17
|
from dodal.devices.fast_grid_scan import (
|
|
29
18
|
set_fast_grid_scan_params as set_flyscan_params,
|
|
30
19
|
)
|
|
31
|
-
from dodal.devices.flux import Flux
|
|
32
|
-
from dodal.devices.robot import BartRobot
|
|
33
|
-
from dodal.devices.s4_slit_gaps import S4SlitGaps
|
|
34
|
-
from dodal.devices.smargon import Smargon
|
|
35
|
-
from dodal.devices.synchrotron import Synchrotron
|
|
36
|
-
from dodal.devices.undulator import Undulator
|
|
37
|
-
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
38
20
|
from dodal.devices.zebra.zebra import Zebra
|
|
39
|
-
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
40
21
|
from dodal.devices.zocalo.zocalo_results import (
|
|
41
22
|
ZOCALO_READING_PLAN_NAME,
|
|
42
23
|
ZOCALO_STAGE_GROUP,
|
|
43
24
|
XrcResult,
|
|
44
|
-
ZocaloResults,
|
|
45
25
|
get_full_processing_results,
|
|
46
26
|
)
|
|
47
|
-
from event_model import RunStart
|
|
48
|
-
from ophyd_async.fastcs.panda import HDFPanda
|
|
49
27
|
|
|
50
28
|
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
51
29
|
ispyb_activation_wrapper,
|
|
52
30
|
)
|
|
53
31
|
from mx_bluesky.common.parameters.constants import HardwareConstants
|
|
54
32
|
from mx_bluesky.common.plans.do_fgs import kickoff_and_complete_gridscan
|
|
33
|
+
from mx_bluesky.common.plans.read_hardware import (
|
|
34
|
+
standard_read_hardware_during_collection,
|
|
35
|
+
standard_read_hardware_pre_collection,
|
|
36
|
+
)
|
|
37
|
+
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
55
38
|
from mx_bluesky.common.utils.exceptions import (
|
|
56
39
|
CrystalNotFoundException,
|
|
57
40
|
SampleException,
|
|
58
41
|
)
|
|
59
42
|
from mx_bluesky.common.utils.log import LOGGER
|
|
60
43
|
from mx_bluesky.common.utils.tracing import TRACER
|
|
61
|
-
from mx_bluesky.
|
|
62
|
-
read_hardware_during_collection,
|
|
63
|
-
read_hardware_pre_collection,
|
|
64
|
-
)
|
|
44
|
+
from mx_bluesky.common.xrc_result import XRayCentreEventHandler, XRayCentreResult
|
|
65
45
|
from mx_bluesky.hyperion.device_setup_plans.setup_panda import (
|
|
66
46
|
disarm_panda_for_gridscan,
|
|
67
47
|
set_panda_directory,
|
|
@@ -78,10 +58,11 @@ from mx_bluesky.hyperion.device_setup_plans.xbpm_feedback import (
|
|
|
78
58
|
from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import (
|
|
79
59
|
change_aperture_then_move_to_xtal,
|
|
80
60
|
)
|
|
81
|
-
from mx_bluesky.hyperion.experiment_plans.common.xrc_result import XRayCentreResult
|
|
82
61
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
62
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
63
|
+
HyperionFlyScanXRayCentreComposite,
|
|
64
|
+
)
|
|
83
65
|
from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
|
|
84
|
-
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
85
66
|
|
|
86
67
|
ZOCALO_MIN_TOTAL_COUNT_THRESHOLD = 3
|
|
87
68
|
|
|
@@ -90,56 +71,21 @@ class SmargonSpeedException(Exception):
|
|
|
90
71
|
pass
|
|
91
72
|
|
|
92
73
|
|
|
93
|
-
|
|
94
|
-
class FlyScanXRayCentreComposite:
|
|
95
|
-
"""All devices which are directly or indirectly required by this plan"""
|
|
96
|
-
|
|
97
|
-
aperture_scatterguard: ApertureScatterguard
|
|
98
|
-
attenuator: BinaryFilterAttenuator
|
|
99
|
-
backlight: Backlight
|
|
100
|
-
dcm: DCM
|
|
101
|
-
eiger: EigerDetector
|
|
102
|
-
zebra_fast_grid_scan: ZebraFastGridScan
|
|
103
|
-
flux: Flux
|
|
104
|
-
s4_slit_gaps: S4SlitGaps
|
|
105
|
-
smargon: Smargon
|
|
106
|
-
undulator: Undulator
|
|
107
|
-
synchrotron: Synchrotron
|
|
108
|
-
xbpm_feedback: XBPMFeedback
|
|
109
|
-
zebra: Zebra
|
|
110
|
-
zocalo: ZocaloResults
|
|
111
|
-
panda: HDFPanda
|
|
112
|
-
panda_fast_grid_scan: PandAFastGridScan
|
|
113
|
-
robot: BartRobot
|
|
114
|
-
sample_shutter: ZebraShutter
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class XRayCentreEventHandler(CallbackBase):
|
|
118
|
-
def __init__(self):
|
|
119
|
-
super().__init__()
|
|
120
|
-
self.xray_centre_results: Sequence[XRayCentreResult] | None = None
|
|
121
|
-
|
|
122
|
-
def start(self, doc: RunStart) -> RunStart | None:
|
|
123
|
-
if CONST.PLAN.FLYSCAN_RESULTS in doc:
|
|
124
|
-
self.xray_centre_results = [
|
|
125
|
-
XRayCentreResult(**result_dict)
|
|
126
|
-
for result_dict in doc[CONST.PLAN.FLYSCAN_RESULTS] # type: ignore
|
|
127
|
-
]
|
|
128
|
-
return doc
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def create_devices(context: BlueskyContext) -> FlyScanXRayCentreComposite:
|
|
74
|
+
def create_devices(context: BlueskyContext) -> HyperionFlyScanXRayCentreComposite:
|
|
132
75
|
"""Creates the devices required for the plan and connect to them"""
|
|
133
|
-
return device_composite_from_context(context,
|
|
76
|
+
return device_composite_from_context(context, HyperionFlyScanXRayCentreComposite)
|
|
134
77
|
|
|
135
78
|
|
|
136
79
|
def flyscan_xray_centre_no_move(
|
|
137
|
-
composite:
|
|
80
|
+
composite: HyperionFlyScanXRayCentreComposite,
|
|
81
|
+
parameters: HyperionSpecifiedThreeDGridScan,
|
|
138
82
|
) -> MsgGenerator:
|
|
139
83
|
"""Perform a flyscan and determine the centres of interest"""
|
|
140
|
-
|
|
84
|
+
|
|
141
85
|
composite.eiger.set_detector_parameters(parameters.detector_params)
|
|
142
86
|
composite.zocalo.zocalo_environment = CONST.ZOCALO_ENV
|
|
87
|
+
|
|
88
|
+
parameters.features.update_self_from_server()
|
|
143
89
|
composite.zocalo.use_cpu_and_gpu = parameters.features.compare_cpu_and_gpu_zocalo
|
|
144
90
|
composite.zocalo.use_gpu = parameters.features.use_gpu_results
|
|
145
91
|
|
|
@@ -164,7 +110,7 @@ def flyscan_xray_centre_no_move(
|
|
|
164
110
|
parameters.transmission_frac,
|
|
165
111
|
)
|
|
166
112
|
def run_gridscan_and_fetch_and_tidy(
|
|
167
|
-
fgs_composite:
|
|
113
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
168
114
|
params: HyperionSpecifiedThreeDGridScan,
|
|
169
115
|
feature_controlled: _FeatureControlled,
|
|
170
116
|
) -> MsgGenerator:
|
|
@@ -178,7 +124,7 @@ def flyscan_xray_centre_no_move(
|
|
|
178
124
|
|
|
179
125
|
|
|
180
126
|
def flyscan_xray_centre(
|
|
181
|
-
composite:
|
|
127
|
+
composite: HyperionFlyScanXRayCentreComposite,
|
|
182
128
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
183
129
|
) -> MsgGenerator:
|
|
184
130
|
"""Create the plan to run the grid scan based on provided parameters.
|
|
@@ -217,7 +163,7 @@ def flyscan_xray_centre(
|
|
|
217
163
|
@bpp.set_run_key_decorator(CONST.PLAN.GRIDSCAN_AND_MOVE)
|
|
218
164
|
@bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_AND_MOVE})
|
|
219
165
|
def run_gridscan_and_fetch_results(
|
|
220
|
-
fgs_composite:
|
|
166
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
221
167
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
222
168
|
feature_controlled: _FeatureControlled,
|
|
223
169
|
) -> MsgGenerator:
|
|
@@ -265,7 +211,7 @@ def run_gridscan_and_fetch_results(
|
|
|
265
211
|
finally:
|
|
266
212
|
# Turn off dev/shm streaming to avoid filling disk, see https://github.com/DiamondLightSource/hyperion/issues/1395
|
|
267
213
|
LOGGER.info("Turning off Eiger dev/shm streaming")
|
|
268
|
-
yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore #
|
|
214
|
+
yield from bps.abs_set(fgs_composite.eiger.odin.fan.dev_shm_enable, 0) # type: ignore # Fix types in ophyd-async (https://github.com/DiamondLightSource/mx-bluesky/issues/855)
|
|
269
215
|
|
|
270
216
|
# Wait on everything before returning to GDA (particularly apertures), can be removed
|
|
271
217
|
# when we do not return to GDA here
|
|
@@ -314,7 +260,7 @@ def _fire_xray_centre_result_event(results: Sequence[XRayCentreResult]):
|
|
|
314
260
|
@bpp.set_run_key_decorator(CONST.PLAN.GRIDSCAN_MAIN)
|
|
315
261
|
@bpp.run_decorator(md={"subplan_name": CONST.PLAN.GRIDSCAN_MAIN})
|
|
316
262
|
def run_gridscan(
|
|
317
|
-
fgs_composite:
|
|
263
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
318
264
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
319
265
|
feature_controlled: _FeatureControlled,
|
|
320
266
|
md={ # noqa
|
|
@@ -329,7 +275,7 @@ def run_gridscan(
|
|
|
329
275
|
# we should generate an event reading the values which need to be included in the
|
|
330
276
|
# ispyb deposition
|
|
331
277
|
with TRACER.start_span("ispyb_hardware_readings"):
|
|
332
|
-
yield from
|
|
278
|
+
yield from standard_read_hardware_pre_collection(
|
|
333
279
|
fgs_composite.undulator,
|
|
334
280
|
fgs_composite.synchrotron,
|
|
335
281
|
fgs_composite.s4_slit_gaps,
|
|
@@ -338,7 +284,7 @@ def run_gridscan(
|
|
|
338
284
|
)
|
|
339
285
|
|
|
340
286
|
read_during_collection = partial(
|
|
341
|
-
|
|
287
|
+
standard_read_hardware_during_collection,
|
|
342
288
|
fgs_composite.aperture_scatterguard,
|
|
343
289
|
fgs_composite.attenuator,
|
|
344
290
|
fgs_composite.flux,
|
|
@@ -354,7 +300,7 @@ def run_gridscan(
|
|
|
354
300
|
|
|
355
301
|
LOGGER.info("Waiting for arming to finish")
|
|
356
302
|
yield from bps.wait(CONST.WAIT.GRID_READY_FOR_DC)
|
|
357
|
-
yield from bps.stage(fgs_composite.eiger)
|
|
303
|
+
yield from bps.stage(fgs_composite.eiger)
|
|
358
304
|
|
|
359
305
|
yield from kickoff_and_complete_gridscan(
|
|
360
306
|
feature_controlled.fgs_motors,
|
|
@@ -394,18 +340,18 @@ class _FeatureControlled:
|
|
|
394
340
|
class _ExtraSetup(Protocol):
|
|
395
341
|
def __call__(
|
|
396
342
|
self,
|
|
397
|
-
fgs_composite:
|
|
343
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
398
344
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
399
345
|
) -> MsgGenerator: ...
|
|
400
346
|
|
|
401
347
|
setup_trigger: _ExtraSetup
|
|
402
|
-
tidy_plan: Callable[[
|
|
348
|
+
tidy_plan: Callable[[HyperionFlyScanXRayCentreComposite], MsgGenerator]
|
|
403
349
|
set_flyscan_params: Callable[[], MsgGenerator]
|
|
404
350
|
fgs_motors: FastGridScanCommon
|
|
405
351
|
|
|
406
352
|
|
|
407
353
|
def _get_feature_controlled(
|
|
408
|
-
fgs_composite:
|
|
354
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
409
355
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
410
356
|
):
|
|
411
357
|
if parameters.features.use_panda_for_gridscan:
|
|
@@ -433,7 +379,7 @@ def _get_feature_controlled(
|
|
|
433
379
|
|
|
434
380
|
|
|
435
381
|
def _generic_tidy(
|
|
436
|
-
fgs_composite:
|
|
382
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite, group, wait=True
|
|
437
383
|
) -> MsgGenerator:
|
|
438
384
|
LOGGER.info("Tidying up Zebra")
|
|
439
385
|
yield from tidy_up_zebra_after_gridscan(
|
|
@@ -444,7 +390,7 @@ def _generic_tidy(
|
|
|
444
390
|
yield from bps.unstage(fgs_composite.zocalo, group=group, wait=wait)
|
|
445
391
|
|
|
446
392
|
|
|
447
|
-
def _panda_tidy(fgs_composite:
|
|
393
|
+
def _panda_tidy(fgs_composite: HyperionFlyScanXRayCentreComposite):
|
|
448
394
|
group = "panda_flyscan_tidy"
|
|
449
395
|
LOGGER.info("Disabling panda blocks")
|
|
450
396
|
yield from disarm_panda_for_gridscan(fgs_composite.panda, group)
|
|
@@ -454,7 +400,7 @@ def _panda_tidy(fgs_composite: FlyScanXRayCentreComposite):
|
|
|
454
400
|
|
|
455
401
|
|
|
456
402
|
def _zebra_triggering_setup(
|
|
457
|
-
fgs_composite:
|
|
403
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
458
404
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
459
405
|
):
|
|
460
406
|
yield from setup_zebra_for_gridscan(
|
|
@@ -463,7 +409,7 @@ def _zebra_triggering_setup(
|
|
|
463
409
|
|
|
464
410
|
|
|
465
411
|
def _panda_triggering_setup(
|
|
466
|
-
fgs_composite:
|
|
412
|
+
fgs_composite: HyperionFlyScanXRayCentreComposite,
|
|
467
413
|
parameters: HyperionSpecifiedThreeDGridScan,
|
|
468
414
|
):
|
|
469
415
|
LOGGER.info("Setting up Panda for flyscan")
|
|
@@ -498,8 +444,8 @@ def _panda_triggering_setup(
|
|
|
498
444
|
)
|
|
499
445
|
|
|
500
446
|
yield from bps.mv(
|
|
501
|
-
fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms,
|
|
502
|
-
time_between_x_steps_ms,
|
|
447
|
+
fgs_composite.panda_fast_grid_scan.time_between_x_steps_ms,
|
|
448
|
+
time_between_x_steps_ms,
|
|
503
449
|
)
|
|
504
450
|
|
|
505
451
|
directory_provider_root = Path(parameters.storage_directory)
|
|
@@ -39,7 +39,9 @@ from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback
|
|
|
39
39
|
ispyb_activation_wrapper,
|
|
40
40
|
)
|
|
41
41
|
from mx_bluesky.common.parameters.constants import OavConstants
|
|
42
|
+
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
42
43
|
from mx_bluesky.common.utils.log import LOGGER
|
|
44
|
+
from mx_bluesky.common.xrc_result import XRayCentreEventHandler
|
|
43
45
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
|
|
44
46
|
move_aperture_if_required,
|
|
45
47
|
)
|
|
@@ -50,10 +52,6 @@ from mx_bluesky.hyperion.experiment_plans.change_aperture_then_move_plan import
|
|
|
50
52
|
change_aperture_then_move_to_xtal,
|
|
51
53
|
)
|
|
52
54
|
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
53
|
-
FlyScanXRayCentreComposite as FlyScanXRayCentreComposite,
|
|
54
|
-
)
|
|
55
|
-
from mx_bluesky.hyperion.experiment_plans.flyscan_xray_centre_plan import (
|
|
56
|
-
XRayCentreEventHandler,
|
|
57
55
|
flyscan_xray_centre_no_move,
|
|
58
56
|
)
|
|
59
57
|
from mx_bluesky.hyperion.experiment_plans.oav_grid_detection_plan import (
|
|
@@ -61,11 +59,13 @@ from mx_bluesky.hyperion.experiment_plans.oav_grid_detection_plan import (
|
|
|
61
59
|
grid_detection_plan,
|
|
62
60
|
)
|
|
63
61
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
62
|
+
from mx_bluesky.hyperion.parameters.device_composites import (
|
|
63
|
+
HyperionFlyScanXRayCentreComposite,
|
|
64
|
+
)
|
|
64
65
|
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
65
66
|
GridScanWithEdgeDetect,
|
|
66
67
|
HyperionSpecifiedThreeDGridScan,
|
|
67
68
|
)
|
|
68
|
-
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
@@ -167,7 +167,7 @@ def detect_grid_and_do_gridscan(
|
|
|
167
167
|
)
|
|
168
168
|
|
|
169
169
|
yield from flyscan_xray_centre_no_move(
|
|
170
|
-
|
|
170
|
+
HyperionFlyScanXRayCentreComposite(
|
|
171
171
|
aperture_scatterguard=composite.aperture_scatterguard,
|
|
172
172
|
attenuator=composite.attenuator,
|
|
173
173
|
backlight=composite.backlight,
|
|
@@ -8,11 +8,10 @@ from bluesky.preprocessors import run_decorator, set_run_key_decorator, subs_wra
|
|
|
8
8
|
from bluesky.utils import MsgGenerator
|
|
9
9
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
10
10
|
|
|
11
|
-
import mx_bluesky.
|
|
11
|
+
import mx_bluesky.common.xrc_result as flyscan_result
|
|
12
|
+
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
12
13
|
from mx_bluesky.common.utils.log import LOGGER
|
|
13
|
-
from mx_bluesky.
|
|
14
|
-
XRayCentreEventHandler,
|
|
15
|
-
)
|
|
14
|
+
from mx_bluesky.common.xrc_result import XRayCentreEventHandler
|
|
16
15
|
from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
|
|
17
16
|
RobotLoadThenCentreComposite,
|
|
18
17
|
robot_load_then_xray_centre,
|
|
@@ -24,7 +23,6 @@ from mx_bluesky.hyperion.experiment_plans.rotation_scan_plan import (
|
|
|
24
23
|
)
|
|
25
24
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
26
25
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
27
|
-
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|