mx-bluesky 1.4.1a0__py3-none-any.whl → 1.4.3__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/redis_to_murko_forwarder.py +178 -0
- mx_bluesky/beamlines/i24/serial/__init__.py +0 -6
- mx_bluesky/beamlines/i24/serial/dcid.py +125 -151
- mx_bluesky/beamlines/i24/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +1 -1
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +88 -43
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +1 -1
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +2 -46
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +85 -122
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +58 -66
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +1 -19
- mx_bluesky/beamlines/i24/serial/parameters/__init__.py +11 -2
- mx_bluesky/beamlines/i24/serial/parameters/constants.py +16 -2
- mx_bluesky/beamlines/i24/serial/parameters/experiment_parameters.py +94 -19
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +19 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +2 -0
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +61 -8
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +81 -40
- mx_bluesky/beamlines/i24/serial/write_nexus.py +66 -67
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/aperture_change_callback.py +1 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/grid_detection_callback.py +19 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/ispyb_callback_base.py +40 -34
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/ispyb_mapping.py +4 -4
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/logging_callback.py +1 -1
- mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/zocalo_callback.py +14 -9
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_callback.py +46 -38
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/ispyb_mapping.py +2 -2
- mx_bluesky/{hyperion → common}/external_interaction/callbacks/xray_centre/nexus_callback.py +20 -15
- mx_bluesky/common/external_interaction/config_server.py +11 -0
- mx_bluesky/common/external_interaction/ispyb/__init__.py +0 -0
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/data_model.py +2 -0
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/exp_eye_store.py +67 -17
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_store.py +20 -18
- mx_bluesky/{hyperion → common}/external_interaction/ispyb/ispyb_utils.py +2 -2
- mx_bluesky/common/external_interaction/nexus/__init__.py +0 -0
- mx_bluesky/{hyperion → common}/external_interaction/nexus/nexus_utils.py +21 -6
- mx_bluesky/{hyperion → common}/external_interaction/nexus/write_nexus.py +5 -5
- mx_bluesky/common/external_interaction/test_config_server.py +38 -0
- mx_bluesky/common/parameters/components.py +10 -8
- mx_bluesky/common/parameters/constants.py +6 -0
- mx_bluesky/common/parameters/gridscan.py +102 -53
- mx_bluesky/common/plans/do_fgs.py +4 -4
- mx_bluesky/{hyperion → common/utils}/exceptions.py +27 -1
- mx_bluesky/common/utils/log.py +17 -7
- mx_bluesky/hyperion/__main__.py +15 -14
- mx_bluesky/hyperion/device_setup_plans/check_beamstop.py +27 -0
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +34 -37
- mx_bluesky/hyperion/device_setup_plans/manipulate_sample.py +7 -7
- mx_bluesky/hyperion/device_setup_plans/position_detector.py +1 -1
- mx_bluesky/hyperion/device_setup_plans/read_hardware_for_setup.py +3 -3
- mx_bluesky/hyperion/device_setup_plans/setup_panda.py +21 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +62 -36
- mx_bluesky/hyperion/device_setup_plans/smargon.py +3 -3
- mx_bluesky/hyperion/device_setup_plans/utils.py +4 -0
- mx_bluesky/hyperion/device_setup_plans/xbpm_feedback.py +8 -8
- mx_bluesky/hyperion/experiment_plans/change_aperture_then_move_plan.py +28 -17
- mx_bluesky/hyperion/experiment_plans/common/xrc_result.py +10 -1
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +9 -9
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +54 -58
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +22 -31
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +57 -40
- mx_bluesky/hyperion/experiment_plans/oav_grid_detection_plan.py +3 -3
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +8 -2
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +6 -14
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +12 -11
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +4 -4
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +39 -30
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +36 -18
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +33 -21
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +10 -9
- mx_bluesky/hyperion/external_interaction/callbacks/__init__.py +0 -4
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +31 -20
- mx_bluesky/hyperion/external_interaction/callbacks/common/callback_util.py +46 -30
- mx_bluesky/hyperion/external_interaction/callbacks/robot_load/ispyb_callback.py +39 -24
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +25 -24
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_mapping.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +13 -9
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/__init__.py +0 -0
- mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py +50 -0
- mx_bluesky/hyperion/external_interaction/config_server.py +15 -1
- mx_bluesky/hyperion/parameters/components.py +3 -2
- mx_bluesky/hyperion/parameters/constants.py +1 -0
- mx_bluesky/hyperion/parameters/gridscan.py +56 -89
- mx_bluesky/hyperion/parameters/load_centre_collect.py +51 -6
- mx_bluesky/hyperion/parameters/robot_load.py +40 -0
- mx_bluesky/hyperion/parameters/rotation.py +28 -3
- mx_bluesky/hyperion/utils/context.py +1 -1
- mx_bluesky/hyperion/utils/validation.py +5 -3
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/METADATA +6 -6
- mx_bluesky-1.4.3.dist-info/RECORD +155 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/WHEEL +1 -1
- mx_bluesky/common/parameters/robot_load.py +0 -16
- mx_bluesky/hyperion/external_interaction/exceptions.py +0 -13
- mx_bluesky/hyperion/log.py +0 -15
- mx_bluesky-1.4.1a0.dist-info/RECORD +0 -150
- /mx_bluesky/{hyperion/external_interaction/callbacks/xray_centre → common/external_interaction}/__init__.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/ispyb → common/external_interaction/callbacks/common}/__init__.py +0 -0
- /mx_bluesky/{hyperion → common}/external_interaction/callbacks/common/abstract_event.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/log_uid_tag_callback.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/callbacks → common/external_interaction/callbacks/common}/plan_reactive_callback.py +0 -0
- /mx_bluesky/{hyperion/external_interaction/nexus → common/external_interaction/callbacks/xray_centre}/__init__.py +0 -0
- /mx_bluesky/{hyperion → common}/utils/utils.py +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/LICENSE +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.1a0.dist-info → mx_bluesky-1.4.3.dist-info}/top_level.txt +0 -0
|
@@ -7,10 +7,24 @@ from bluesky.callbacks.zmq import Proxy, RemoteDispatcher
|
|
|
7
7
|
from dodal.log import LOGGER as dodal_logger
|
|
8
8
|
from dodal.log import set_up_all_logging_handlers
|
|
9
9
|
|
|
10
|
-
from mx_bluesky.common.
|
|
11
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.log_uid_tag_callback import (
|
|
10
|
+
from mx_bluesky.common.external_interaction.callbacks.common.log_uid_tag_callback import (
|
|
12
11
|
LogUidTaggingCallback,
|
|
13
12
|
)
|
|
13
|
+
from mx_bluesky.common.external_interaction.callbacks.common.zocalo_callback import (
|
|
14
|
+
ZocaloCallback,
|
|
15
|
+
)
|
|
16
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
17
|
+
GridscanISPyBCallback,
|
|
18
|
+
)
|
|
19
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
|
|
20
|
+
GridscanNexusFileCallback,
|
|
21
|
+
)
|
|
22
|
+
from mx_bluesky.common.utils.log import (
|
|
23
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER,
|
|
24
|
+
NEXUS_LOGGER,
|
|
25
|
+
_get_logging_dir,
|
|
26
|
+
tag_filter,
|
|
27
|
+
)
|
|
14
28
|
from mx_bluesky.hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
|
|
15
29
|
RobotLoadISPyBCallback,
|
|
16
30
|
)
|
|
@@ -20,21 +34,15 @@ from mx_bluesky.hyperion.external_interaction.callbacks.rotation.ispyb_callback
|
|
|
20
34
|
from mx_bluesky.hyperion.external_interaction.callbacks.rotation.nexus_callback import (
|
|
21
35
|
RotationNexusFileCallback,
|
|
22
36
|
)
|
|
23
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.nexus_callback import (
|
|
27
|
-
GridscanNexusFileCallback,
|
|
28
|
-
)
|
|
29
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.zocalo_callback import (
|
|
30
|
-
ZocaloCallback,
|
|
31
|
-
)
|
|
32
|
-
from mx_bluesky.hyperion.log import (
|
|
33
|
-
ISPYB_LOGGER,
|
|
34
|
-
NEXUS_LOGGER,
|
|
37
|
+
from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import (
|
|
38
|
+
SampleHandlingCallback,
|
|
35
39
|
)
|
|
36
40
|
from mx_bluesky.hyperion.parameters.cli import parse_callback_dev_mode_arg
|
|
37
41
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
42
|
+
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
43
|
+
GridCommonWithHyperionDetectorParams,
|
|
44
|
+
HyperionSpecifiedThreeDGridScan,
|
|
45
|
+
)
|
|
38
46
|
|
|
39
47
|
LIVENESS_POLL_SECONDS = 1
|
|
40
48
|
ERROR_LOG_BUFFER_LINES = 5000
|
|
@@ -43,18 +51,21 @@ ERROR_LOG_BUFFER_LINES = 5000
|
|
|
43
51
|
def setup_callbacks():
|
|
44
52
|
zocalo = ZocaloCallback()
|
|
45
53
|
return [
|
|
46
|
-
GridscanNexusFileCallback(),
|
|
47
|
-
GridscanISPyBCallback(
|
|
54
|
+
GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
|
|
55
|
+
GridscanISPyBCallback(
|
|
56
|
+
param_type=GridCommonWithHyperionDetectorParams, emit=zocalo
|
|
57
|
+
),
|
|
48
58
|
RotationNexusFileCallback(),
|
|
49
59
|
RotationISPyBCallback(emit=zocalo),
|
|
50
60
|
LogUidTaggingCallback(),
|
|
51
61
|
RobotLoadISPyBCallback(),
|
|
62
|
+
SampleHandlingCallback(),
|
|
52
63
|
]
|
|
53
64
|
|
|
54
65
|
|
|
55
66
|
def setup_logging(dev_mode: bool):
|
|
56
67
|
for logger, filename in [
|
|
57
|
-
(
|
|
68
|
+
(ISPYB_ZOCALO_CALLBACK_LOGGER, "hyperion_ispyb_callback.log"),
|
|
58
69
|
(NEXUS_LOGGER, "hyperion_nexus_callback.log"),
|
|
59
70
|
]:
|
|
60
71
|
if logger.handlers == []:
|
|
@@ -70,7 +81,7 @@ def setup_logging(dev_mode: bool):
|
|
|
70
81
|
log_info(f"Loggers initialised with dev_mode={dev_mode}")
|
|
71
82
|
nexgen_logger = logging.getLogger("nexgen")
|
|
72
83
|
nexgen_logger.parent = NEXUS_LOGGER
|
|
73
|
-
dodal_logger.parent =
|
|
84
|
+
dodal_logger.parent = ISPYB_ZOCALO_CALLBACK_LOGGER
|
|
74
85
|
log_debug("nexgen logger added to nexus logger")
|
|
75
86
|
|
|
76
87
|
|
|
@@ -90,12 +101,12 @@ def setup_threads():
|
|
|
90
101
|
|
|
91
102
|
|
|
92
103
|
def log_info(msg, *args, **kwargs):
|
|
93
|
-
|
|
104
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(msg, *args, **kwargs)
|
|
94
105
|
NEXUS_LOGGER.info(msg, *args, **kwargs)
|
|
95
106
|
|
|
96
107
|
|
|
97
108
|
def log_debug(msg, *args, **kwargs):
|
|
98
|
-
|
|
109
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug(msg, *args, **kwargs)
|
|
99
110
|
NEXUS_LOGGER.debug(msg, *args, **kwargs)
|
|
100
111
|
|
|
101
112
|
|
|
@@ -2,6 +2,15 @@ from collections.abc import Callable
|
|
|
2
2
|
|
|
3
3
|
from bluesky.callbacks import CallbackBase
|
|
4
4
|
|
|
5
|
+
from mx_bluesky.common.external_interaction.callbacks.common.zocalo_callback import (
|
|
6
|
+
ZocaloCallback,
|
|
7
|
+
)
|
|
8
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
9
|
+
GridscanISPyBCallback,
|
|
10
|
+
)
|
|
11
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.nexus_callback import (
|
|
12
|
+
GridscanNexusFileCallback,
|
|
13
|
+
)
|
|
5
14
|
from mx_bluesky.hyperion.external_interaction.callbacks.robot_load.ispyb_callback import (
|
|
6
15
|
RobotLoadISPyBCallback,
|
|
7
16
|
)
|
|
@@ -11,54 +20,61 @@ from mx_bluesky.hyperion.external_interaction.callbacks.rotation.ispyb_callback
|
|
|
11
20
|
from mx_bluesky.hyperion.external_interaction.callbacks.rotation.nexus_callback import (
|
|
12
21
|
RotationNexusFileCallback,
|
|
13
22
|
)
|
|
14
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.
|
|
15
|
-
|
|
23
|
+
from mx_bluesky.hyperion.external_interaction.callbacks.sample_handling.sample_handling_callback import (
|
|
24
|
+
SampleHandlingCallback,
|
|
16
25
|
)
|
|
17
|
-
from mx_bluesky.hyperion.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.zocalo_callback import (
|
|
21
|
-
ZocaloCallback,
|
|
26
|
+
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
27
|
+
GridCommonWithHyperionDetectorParams,
|
|
28
|
+
HyperionSpecifiedThreeDGridScan,
|
|
22
29
|
)
|
|
23
30
|
|
|
24
31
|
CallbacksFactory = Callable[[], tuple[CallbackBase, ...]]
|
|
25
32
|
|
|
26
33
|
|
|
27
|
-
def create_robot_load_and_centre_callbacks() ->
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
def create_robot_load_and_centre_callbacks() -> tuple[
|
|
35
|
+
GridscanNexusFileCallback, GridscanISPyBCallback, RobotLoadISPyBCallback
|
|
36
|
+
]:
|
|
30
37
|
return (
|
|
31
|
-
GridscanNexusFileCallback(),
|
|
32
|
-
GridscanISPyBCallback(
|
|
38
|
+
GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
|
|
39
|
+
GridscanISPyBCallback(
|
|
40
|
+
param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback()
|
|
41
|
+
),
|
|
33
42
|
RobotLoadISPyBCallback(),
|
|
34
43
|
)
|
|
35
44
|
|
|
36
45
|
|
|
37
|
-
def create_gridscan_callbacks() ->
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return (
|
|
46
|
+
def create_gridscan_callbacks() -> tuple[
|
|
47
|
+
GridscanNexusFileCallback, GridscanISPyBCallback
|
|
48
|
+
]:
|
|
49
|
+
return (
|
|
50
|
+
GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
|
|
51
|
+
GridscanISPyBCallback(
|
|
52
|
+
param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback()
|
|
53
|
+
),
|
|
54
|
+
)
|
|
41
55
|
|
|
42
56
|
|
|
43
|
-
def create_rotation_callbacks() ->
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
def create_rotation_callbacks() -> tuple[
|
|
58
|
+
RotationNexusFileCallback, RotationISPyBCallback
|
|
59
|
+
]:
|
|
46
60
|
return (RotationNexusFileCallback(), RotationISPyBCallback(emit=ZocaloCallback()))
|
|
47
61
|
|
|
48
62
|
|
|
49
|
-
def create_load_centre_collect_callbacks() ->
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
):
|
|
63
|
+
def create_load_centre_collect_callbacks() -> tuple[
|
|
64
|
+
GridscanNexusFileCallback,
|
|
65
|
+
GridscanISPyBCallback,
|
|
66
|
+
RobotLoadISPyBCallback,
|
|
67
|
+
RotationNexusFileCallback,
|
|
68
|
+
RotationISPyBCallback,
|
|
69
|
+
SampleHandlingCallback,
|
|
70
|
+
]:
|
|
58
71
|
return (
|
|
59
|
-
GridscanNexusFileCallback(),
|
|
60
|
-
GridscanISPyBCallback(
|
|
72
|
+
GridscanNexusFileCallback(param_type=HyperionSpecifiedThreeDGridScan),
|
|
73
|
+
GridscanISPyBCallback(
|
|
74
|
+
param_type=GridCommonWithHyperionDetectorParams, emit=ZocaloCallback()
|
|
75
|
+
),
|
|
61
76
|
RobotLoadISPyBCallback(),
|
|
62
77
|
RotationNexusFileCallback(),
|
|
63
78
|
RotationISPyBCallback(emit=ZocaloCallback()),
|
|
79
|
+
SampleHandlingCallback(),
|
|
64
80
|
)
|
|
@@ -2,19 +2,18 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.common.ispyb_mapping import (
|
|
5
|
+
from mx_bluesky.common.external_interaction.callbacks.common.ispyb_mapping import (
|
|
8
6
|
get_proposal_and_session_from_visit_string,
|
|
9
7
|
)
|
|
10
|
-
from mx_bluesky.
|
|
8
|
+
from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import (
|
|
11
9
|
PlanReactiveCallback,
|
|
12
10
|
)
|
|
13
|
-
from mx_bluesky.
|
|
11
|
+
from mx_bluesky.common.external_interaction.ispyb.exp_eye_store import (
|
|
12
|
+
BLSampleStatus,
|
|
14
13
|
ExpeyeInteraction,
|
|
15
14
|
RobotActionID,
|
|
16
15
|
)
|
|
17
|
-
from mx_bluesky.
|
|
16
|
+
from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER
|
|
18
17
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
19
18
|
|
|
20
19
|
if TYPE_CHECKING:
|
|
@@ -23,28 +22,35 @@ if TYPE_CHECKING:
|
|
|
23
22
|
|
|
24
23
|
class RobotLoadISPyBCallback(PlanReactiveCallback):
|
|
25
24
|
def __init__(self) -> None:
|
|
26
|
-
|
|
27
|
-
super().__init__(log=
|
|
25
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug("Initialising ISPyB Robot Load Callback")
|
|
26
|
+
super().__init__(log=ISPYB_ZOCALO_CALLBACK_LOGGER)
|
|
27
|
+
self._metadata: dict | None = None
|
|
28
|
+
|
|
28
29
|
self.run_uid: str | None = None
|
|
29
30
|
self.descriptors: dict[str, EventDescriptor] = {}
|
|
30
31
|
self.action_id: RobotActionID | None = None
|
|
31
32
|
self.expeye = ExpeyeInteraction()
|
|
32
33
|
|
|
33
34
|
def activity_gated_start(self, doc: RunStart):
|
|
34
|
-
|
|
35
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
|
|
36
|
+
"ISPyB robot load callback received start document."
|
|
37
|
+
)
|
|
35
38
|
if doc.get("subplan_name") == CONST.PLAN.ROBOT_LOAD:
|
|
36
|
-
|
|
39
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
|
|
40
|
+
f"ISPyB robot load callback received: {doc}"
|
|
41
|
+
)
|
|
37
42
|
self.run_uid = doc.get("uid")
|
|
38
|
-
|
|
43
|
+
self._metadata = doc.get("metadata")
|
|
44
|
+
assert isinstance(self._metadata, dict)
|
|
39
45
|
proposal, session = get_proposal_and_session_from_visit_string(
|
|
40
|
-
|
|
46
|
+
self._metadata["visit"]
|
|
41
47
|
)
|
|
42
48
|
self.action_id = self.expeye.start_load(
|
|
43
49
|
proposal,
|
|
44
50
|
session,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
self._metadata["sample_id"],
|
|
52
|
+
self._metadata["sample_puck"],
|
|
53
|
+
self._metadata["sample_pin"],
|
|
48
54
|
)
|
|
49
55
|
return super().activity_gated_start(doc)
|
|
50
56
|
|
|
@@ -58,9 +64,9 @@ class RobotLoadISPyBCallback(PlanReactiveCallback):
|
|
|
58
64
|
event_descriptor
|
|
59
65
|
and event_descriptor.get("name") == CONST.DESCRIPTORS.ROBOT_LOAD
|
|
60
66
|
):
|
|
61
|
-
assert (
|
|
62
|
-
|
|
63
|
-
)
|
|
67
|
+
assert self.action_id is not None, (
|
|
68
|
+
"ISPyB Robot load callback event called unexpectedly"
|
|
69
|
+
)
|
|
64
70
|
barcode = doc["data"]["robot-barcode"]
|
|
65
71
|
oav_snapshot = doc["data"]["oav-snapshot-last_saved_path"]
|
|
66
72
|
webcam_snapshot = doc["data"]["webcam-last_saved_path"]
|
|
@@ -72,15 +78,24 @@ class RobotLoadISPyBCallback(PlanReactiveCallback):
|
|
|
72
78
|
return super().activity_gated_event(doc)
|
|
73
79
|
|
|
74
80
|
def activity_gated_stop(self, doc: RunStop) -> RunStop | None:
|
|
75
|
-
|
|
81
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.debug(
|
|
82
|
+
"ISPyB robot load callback received stop document."
|
|
83
|
+
)
|
|
76
84
|
if doc.get("run_start") == self.run_uid:
|
|
77
|
-
assert (
|
|
78
|
-
|
|
79
|
-
), "ISPyB Robot load callback stop called unexpectedly"
|
|
80
|
-
exit_status = (
|
|
81
|
-
doc.get("exit_status") or "Exit status not available in stop document!"
|
|
85
|
+
assert self.action_id is not None, (
|
|
86
|
+
"ISPyB Robot load callback stop called unexpectedly"
|
|
82
87
|
)
|
|
88
|
+
exit_status = doc.get("exit_status")
|
|
89
|
+
assert exit_status, "Exit status not available in stop document!"
|
|
90
|
+
assert self._metadata, "Metadata not received before stop document."
|
|
83
91
|
reason = doc.get("reason") or "OK"
|
|
92
|
+
|
|
84
93
|
self.expeye.end_load(self.action_id, exit_status, reason)
|
|
94
|
+
self.expeye.update_sample_status(
|
|
95
|
+
self._metadata["sample_id"],
|
|
96
|
+
BLSampleStatus.LOADED
|
|
97
|
+
if exit_status == "success"
|
|
98
|
+
else BLSampleStatus.ERROR_BEAMLINE,
|
|
99
|
+
)
|
|
85
100
|
self.action_id = None
|
|
86
101
|
return super().activity_gated_stop(doc)
|
|
@@ -3,28 +3,27 @@ from __future__ import annotations
|
|
|
3
3
|
from collections.abc import Callable, Sequence
|
|
4
4
|
from typing import TYPE_CHECKING, Any, cast
|
|
5
5
|
|
|
6
|
-
from mx_bluesky.common.
|
|
7
|
-
from mx_bluesky.common.utils.log import set_dcgid_tag
|
|
8
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.common.ispyb_mapping import (
|
|
9
|
-
populate_data_collection_group,
|
|
10
|
-
populate_remaining_data_collection_info,
|
|
11
|
-
)
|
|
12
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.ispyb_callback_base import (
|
|
6
|
+
from mx_bluesky.common.external_interaction.callbacks.common.ispyb_callback_base import (
|
|
13
7
|
BaseISPyBCallback,
|
|
14
8
|
)
|
|
15
|
-
from mx_bluesky.
|
|
16
|
-
|
|
9
|
+
from mx_bluesky.common.external_interaction.callbacks.common.ispyb_mapping import (
|
|
10
|
+
populate_data_collection_group,
|
|
11
|
+
populate_remaining_data_collection_info,
|
|
17
12
|
)
|
|
18
|
-
from mx_bluesky.
|
|
13
|
+
from mx_bluesky.common.external_interaction.ispyb.data_model import (
|
|
19
14
|
DataCollectionInfo,
|
|
20
15
|
DataCollectionPositionInfo,
|
|
21
16
|
ScanDataInfo,
|
|
22
17
|
)
|
|
23
|
-
from mx_bluesky.
|
|
18
|
+
from mx_bluesky.common.external_interaction.ispyb.ispyb_store import (
|
|
24
19
|
IspybIds,
|
|
25
20
|
StoreInIspyb,
|
|
26
21
|
)
|
|
27
|
-
from mx_bluesky.
|
|
22
|
+
from mx_bluesky.common.parameters.components import IspybExperimentType
|
|
23
|
+
from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER, set_dcgid_tag
|
|
24
|
+
from mx_bluesky.hyperion.external_interaction.callbacks.rotation.ispyb_mapping import (
|
|
25
|
+
populate_data_collection_info_for_rotation,
|
|
26
|
+
)
|
|
28
27
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
29
28
|
from mx_bluesky.hyperion.parameters.rotation import RotationScan
|
|
30
29
|
|
|
@@ -58,10 +57,10 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
58
57
|
|
|
59
58
|
def activity_gated_start(self, doc: RunStart):
|
|
60
59
|
if doc.get("subplan_name") == CONST.PLAN.ROTATION_OUTER:
|
|
61
|
-
|
|
60
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
62
61
|
"ISPyB callback received start document with experiment parameters."
|
|
63
62
|
)
|
|
64
|
-
hyperion_params = doc.get("
|
|
63
|
+
hyperion_params = doc.get("mx_bluesky_parameters")
|
|
65
64
|
assert isinstance(hyperion_params, str)
|
|
66
65
|
self.params = RotationScan.model_validate_json(hyperion_params)
|
|
67
66
|
dcgid = (
|
|
@@ -73,16 +72,18 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
73
72
|
self.params.ispyb_experiment_type
|
|
74
73
|
== IspybExperimentType.CHARACTERIZATION
|
|
75
74
|
):
|
|
76
|
-
|
|
75
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
76
|
+
"Screening collection - using new DCG"
|
|
77
|
+
)
|
|
77
78
|
dcgid = None
|
|
78
79
|
self.last_sample_id = None
|
|
79
80
|
else:
|
|
80
|
-
|
|
81
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
81
82
|
f"Collection is {self.params.ispyb_experiment_type} - storing sampleID to bundle images"
|
|
82
83
|
)
|
|
83
84
|
self.last_sample_id = self.params.sample_id
|
|
84
85
|
self.ispyb = StoreInIspyb(self.ispyb_config)
|
|
85
|
-
|
|
86
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info("Beginning ispyb deposition")
|
|
86
87
|
data_collection_group_info = populate_data_collection_group(self.params)
|
|
87
88
|
data_collection_info = populate_data_collection_info_for_rotation(
|
|
88
89
|
cast(RotationScan, self.params)
|
|
@@ -100,7 +101,7 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
100
101
|
self.ispyb_ids = self.ispyb.begin_deposition(
|
|
101
102
|
data_collection_group_info, [scan_data_info]
|
|
102
103
|
)
|
|
103
|
-
|
|
104
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info("ISPYB handler received start document.")
|
|
104
105
|
if doc.get("subplan_name") == CONST.PLAN.ROTATION_MAIN:
|
|
105
106
|
self.uid_to_finalize_on = doc.get("uid")
|
|
106
107
|
return super().activity_gated_start(doc)
|
|
@@ -111,9 +112,9 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
111
112
|
event_sourced_position_info: DataCollectionPositionInfo | None,
|
|
112
113
|
params,
|
|
113
114
|
) -> Sequence[ScanDataInfo]:
|
|
114
|
-
assert (
|
|
115
|
-
|
|
116
|
-
)
|
|
115
|
+
assert self.ispyb_ids.data_collection_ids, (
|
|
116
|
+
"Expect an existing DataCollection to update"
|
|
117
|
+
)
|
|
117
118
|
|
|
118
119
|
return [
|
|
119
120
|
ScanDataInfo(
|
|
@@ -131,9 +132,9 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
131
132
|
doc["data"]["smargon-y"],
|
|
132
133
|
doc["data"]["smargon-z"],
|
|
133
134
|
]
|
|
134
|
-
assert (
|
|
135
|
-
|
|
136
|
-
)
|
|
135
|
+
assert self.params, (
|
|
136
|
+
"handle_ispyb_hardware_read triggered before activity_gated_start"
|
|
137
|
+
)
|
|
137
138
|
motor_positions_um = [position * 1000 for position in motor_positions_mm]
|
|
138
139
|
comment = f"Sample position (µm): ({motor_positions_um[0]:.0f}, {motor_positions_um[1]:.0f}, {motor_positions_um[2]:.0f}) {self.params.comment} "
|
|
139
140
|
scan_data_infos[0].data_collection_info.comments = comment
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from mx_bluesky.
|
|
3
|
+
from mx_bluesky.common.external_interaction.ispyb.data_model import DataCollectionInfo
|
|
4
4
|
from mx_bluesky.hyperion.parameters.rotation import RotationScan
|
|
5
5
|
|
|
6
6
|
|
|
@@ -2,20 +2,22 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from mx_bluesky.
|
|
5
|
+
from mx_bluesky.common.external_interaction.callbacks.common.logging_callback import (
|
|
6
|
+
format_doc_for_log,
|
|
7
|
+
)
|
|
8
|
+
from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import (
|
|
6
9
|
PlanReactiveCallback,
|
|
7
10
|
)
|
|
8
|
-
from mx_bluesky.
|
|
11
|
+
from mx_bluesky.common.external_interaction.nexus.nexus_utils import (
|
|
12
|
+
AxisDirection,
|
|
9
13
|
create_beam_and_attenuator_parameters,
|
|
10
14
|
vds_type_based_on_bit_depth,
|
|
11
15
|
)
|
|
12
|
-
from mx_bluesky.
|
|
13
|
-
from mx_bluesky.
|
|
16
|
+
from mx_bluesky.common.external_interaction.nexus.write_nexus import NexusWriter
|
|
17
|
+
from mx_bluesky.common.utils.log import NEXUS_LOGGER
|
|
14
18
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
15
19
|
from mx_bluesky.hyperion.parameters.rotation import RotationScan
|
|
16
20
|
|
|
17
|
-
from ..logging_callback import format_doc_for_log
|
|
18
|
-
|
|
19
21
|
if TYPE_CHECKING:
|
|
20
22
|
from event_model.documents import Event, EventDescriptor, RunStart
|
|
21
23
|
|
|
@@ -64,7 +66,7 @@ class RotationNexusFileCallback(PlanReactiveCallback):
|
|
|
64
66
|
self.writer.attenuator,
|
|
65
67
|
) = create_beam_and_attenuator_parameters(
|
|
66
68
|
data["dcm-energy_in_kev"],
|
|
67
|
-
data["
|
|
69
|
+
data["flux-flux_reading"],
|
|
68
70
|
data["attenuator-actual_transmission"],
|
|
69
71
|
)
|
|
70
72
|
vds_data_type = vds_type_based_on_bit_depth(doc["data"]["eiger_bit_depth"])
|
|
@@ -78,7 +80,7 @@ class RotationNexusFileCallback(PlanReactiveCallback):
|
|
|
78
80
|
self.meta_data_run_number = doc.get("meta_data_run_number")
|
|
79
81
|
if doc.get("subplan_name") == CONST.PLAN.ROTATION_OUTER:
|
|
80
82
|
self.run_uid = doc.get("uid")
|
|
81
|
-
hyperion_params = doc.get("
|
|
83
|
+
hyperion_params = doc.get("mx_bluesky_parameters")
|
|
82
84
|
assert isinstance(hyperion_params, str)
|
|
83
85
|
NEXUS_LOGGER.info(
|
|
84
86
|
f"Nexus writer received start document with experiment parameters {hyperion_params}"
|
|
@@ -100,5 +102,7 @@ class RotationNexusFileCallback(PlanReactiveCallback):
|
|
|
100
102
|
vds_start_index=parameters.nexus_vds_start_img,
|
|
101
103
|
full_num_of_images=self.full_num_of_images,
|
|
102
104
|
meta_data_run_number=self.meta_data_run_number,
|
|
103
|
-
|
|
105
|
+
axis_direction=AxisDirection.NEGATIVE
|
|
106
|
+
if parameters.features.omega_flip
|
|
107
|
+
else AxisDirection.POSITIVE,
|
|
104
108
|
)
|
|
File without changes
|
mx_bluesky/hyperion/external_interaction/callbacks/sample_handling/sample_handling_callback.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from event_model import RunStart, RunStop
|
|
2
|
+
|
|
3
|
+
from mx_bluesky.common.external_interaction.callbacks.common.plan_reactive_callback import (
|
|
4
|
+
PlanReactiveCallback,
|
|
5
|
+
)
|
|
6
|
+
from mx_bluesky.common.external_interaction.ispyb.exp_eye_store import (
|
|
7
|
+
BLSampleStatus,
|
|
8
|
+
ExpeyeInteraction,
|
|
9
|
+
)
|
|
10
|
+
from mx_bluesky.common.utils.exceptions import CrystalNotFoundException, SampleException
|
|
11
|
+
from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SampleHandlingCallback(PlanReactiveCallback):
|
|
15
|
+
"""Intercepts exceptions from experiment plans and updates the ISPyB BLSampleStatus
|
|
16
|
+
field according to the type of exception raised."""
|
|
17
|
+
|
|
18
|
+
def __init__(self):
|
|
19
|
+
super().__init__(log=ISPYB_ZOCALO_CALLBACK_LOGGER)
|
|
20
|
+
self._sample_id: int | None = None
|
|
21
|
+
self._descriptor: str | None = None
|
|
22
|
+
|
|
23
|
+
def activity_gated_start(self, doc: RunStart):
|
|
24
|
+
if not self._sample_id:
|
|
25
|
+
sample_id = doc.get("metadata", {}).get("sample_id")
|
|
26
|
+
self.log.info(f"Recording sample ID at run start {sample_id}")
|
|
27
|
+
self._sample_id = sample_id
|
|
28
|
+
|
|
29
|
+
def activity_gated_stop(self, doc: RunStop) -> RunStop:
|
|
30
|
+
if doc["exit_status"] != "success":
|
|
31
|
+
exception_type, message = SampleException.type_and_message_from_reason(
|
|
32
|
+
doc.get("reason", "")
|
|
33
|
+
)
|
|
34
|
+
self.log.info(
|
|
35
|
+
f"Sample handling callback intercepted exception of type {exception_type}: {message}"
|
|
36
|
+
)
|
|
37
|
+
self._record_exception(exception_type)
|
|
38
|
+
return doc
|
|
39
|
+
|
|
40
|
+
def _record_exception(self, exception_type: str):
|
|
41
|
+
expeye = ExpeyeInteraction()
|
|
42
|
+
assert self._sample_id, "Unable to record exception due to no sample ID"
|
|
43
|
+
sample_status = self._decode_sample_status(exception_type)
|
|
44
|
+
expeye.update_sample_status(self._sample_id, sample_status)
|
|
45
|
+
|
|
46
|
+
def _decode_sample_status(self, exception_type: str) -> BLSampleStatus:
|
|
47
|
+
match exception_type:
|
|
48
|
+
case SampleException.__name__ | CrystalNotFoundException.__name__:
|
|
49
|
+
return BLSampleStatus.ERROR_SAMPLE
|
|
50
|
+
return BLSampleStatus.ERROR_BEAMLINE
|
|
@@ -3,11 +3,24 @@ from functools import cache
|
|
|
3
3
|
from daq_config_server.client import ConfigServer
|
|
4
4
|
|
|
5
5
|
from mx_bluesky.common.external_interaction.config_server import FeatureFlags
|
|
6
|
-
from mx_bluesky.
|
|
6
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
7
7
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class HyperionFeatureFlags(FeatureFlags):
|
|
11
|
+
"""
|
|
12
|
+
Feature flags specific to Hyperion.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
use_panda_for_gridscan: If True then the PandA is used for gridscans, otherwise the zebra is used
|
|
16
|
+
compare_cpu_and_gpu_zocalo: If True then GPU result processing is enabled alongside CPU, if False then
|
|
17
|
+
CPU only is used.
|
|
18
|
+
set_stub_offsets: If True then set the stub offsets after moving to the crystal (ignored for
|
|
19
|
+
multi-centre)
|
|
20
|
+
omega_flip: If True then invert the smargon omega motor rotation commands with respect to
|
|
21
|
+
the hyperion request.
|
|
22
|
+
"""
|
|
23
|
+
|
|
11
24
|
@staticmethod
|
|
12
25
|
@cache
|
|
13
26
|
def get_config_server() -> ConfigServer:
|
|
@@ -16,3 +29,4 @@ class HyperionFeatureFlags(FeatureFlags):
|
|
|
16
29
|
use_panda_for_gridscan: bool = CONST.I03.USE_PANDA_FOR_GRIDSCAN
|
|
17
30
|
compare_cpu_and_gpu_zocalo: bool = CONST.I03.COMPARE_CPU_AND_GPU_ZOCALO
|
|
18
31
|
set_stub_offsets: bool = CONST.I03.SET_STUB_OFFSETS
|
|
32
|
+
omega_flip: bool = CONST.I03.OMEGA_FLIP
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from pydantic import
|
|
1
|
+
from pydantic import Field
|
|
2
2
|
|
|
3
|
+
from mx_bluesky.common.parameters.components import WithPandaGridScan
|
|
3
4
|
from mx_bluesky.hyperion.external_interaction.config_server import HyperionFeatureFlags
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
class
|
|
7
|
+
class WithHyperionUDCFeatures(WithPandaGridScan):
|
|
7
8
|
features: HyperionFeatureFlags = Field(default=HyperionFeatureFlags())
|
|
@@ -28,6 +28,7 @@ class I03Constants:
|
|
|
28
28
|
SHUTTER_TIME_S = 0.06
|
|
29
29
|
USE_PANDA_FOR_GRIDSCAN = False
|
|
30
30
|
SET_STUB_OFFSETS = False
|
|
31
|
+
OMEGA_FLIP = True
|
|
31
32
|
|
|
32
33
|
# Turns on GPU processing for zocalo and logs a comparison between GPU and CPU-
|
|
33
34
|
# processed results. GPU results never used in analysis for now
|