mx-bluesky 1.4.7__py3-none-any.whl → 1.4.8__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 +4 -4
- mx_bluesky/beamlines/i04/thawing_plan.py +8 -2
- mx_bluesky/beamlines/i23/__init__.py +3 -0
- mx_bluesky/beamlines/i23/serial.py +71 -0
- mx_bluesky/beamlines/i24/serial/__init__.py +2 -0
- mx_bluesky/beamlines/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +7 -2
- mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +3 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +6 -56
- mx_bluesky/beamlines/i24/serial/log.py +9 -10
- mx_bluesky/beamlines/i24/serial/parameters/utils.py +36 -7
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +0 -1
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv_abstract.py +4 -4
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +4 -4
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +2 -1
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +71 -11
- mx_bluesky/beamlines/i24/serial/write_nexus.py +3 -3
- mx_bluesky/{hyperion → common}/device_setup_plans/check_beamstop.py +1 -1
- mx_bluesky/{hyperion → common}/device_setup_plans/manipulate_sample.py +1 -1
- mx_bluesky/{hyperion → common}/device_setup_plans/setup_oav.py +12 -6
- mx_bluesky/{hyperion → common}/experiment_plans/change_aperture_then_move_plan.py +4 -5
- mx_bluesky/{hyperion → common}/experiment_plans/oav_grid_detection_plan.py +6 -6
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +6 -5
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +16 -47
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +4 -1
- mx_bluesky/common/external_interaction/ispyb/ispyb_utils.py +4 -4
- mx_bluesky/common/parameters/components.py +22 -2
- mx_bluesky/common/parameters/constants.py +4 -16
- mx_bluesky/common/parameters/gridscan.py +36 -32
- mx_bluesky/common/plans/common_flyscan_xray_centre_plan.py +316 -0
- mx_bluesky/common/plans/inner_plans/__init__ .py +0 -0
- mx_bluesky/common/plans/read_hardware.py +3 -3
- mx_bluesky/common/utils/log.py +15 -12
- mx_bluesky/hyperion/__main__.py +2 -15
- mx_bluesky/hyperion/device_setup_plans/dcm_pitch_roll_mirror_adjuster.py +4 -4
- mx_bluesky/hyperion/device_setup_plans/setup_zebra.py +0 -33
- mx_bluesky/hyperion/device_setup_plans/utils.py +4 -4
- mx_bluesky/hyperion/experiment_plans/__init__.py +0 -6
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +0 -9
- mx_bluesky/hyperion/experiment_plans/grid_detect_then_xray_centre_plan.py +71 -88
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +183 -0
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +12 -7
- mx_bluesky/hyperion/experiment_plans/oav_snapshot_plan.py +28 -7
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +4 -4
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +1 -1
- mx_bluesky/hyperion/experiment_plans/robot_load_and_change_energy.py +11 -3
- mx_bluesky/hyperion/experiment_plans/robot_load_then_centre_plan.py +9 -8
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +18 -56
- mx_bluesky/hyperion/experiment_plans/set_energy_plan.py +2 -2
- mx_bluesky/hyperion/external_interaction/agamemnon.py +62 -70
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +8 -6
- mx_bluesky/hyperion/external_interaction/callbacks/snapshot_callback.py +183 -31
- mx_bluesky/hyperion/parameters/cli.py +2 -10
- mx_bluesky/hyperion/parameters/constants.py +0 -5
- mx_bluesky/hyperion/parameters/device_composites.py +40 -5
- mx_bluesky/hyperion/parameters/gridscan.py +9 -58
- mx_bluesky/hyperion/parameters/rotation.py +0 -4
- mx_bluesky/hyperion/utils/context.py +2 -5
- mx_bluesky/hyperion/utils/validation.py +13 -10
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/METADATA +5 -4
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/RECORD +69 -65
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/WHEEL +1 -1
- mx_bluesky/hyperion/experiment_plans/flyscan_xray_centre_plan.py +0 -467
- /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short1-laser.png → s1l.png} +0 -0
- /mx_bluesky/beamlines/i24/serial/fixed_target/FT-gui-edm/{short2-laser.png → s2l.png} +0 -0
- /mx_bluesky/{hyperion → common}/device_setup_plans/position_detector.py +0 -0
- /mx_bluesky/common/plans/{do_fgs.py → inner_plans/do_fgs.py} +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.4.7.dist-info → mx_bluesky-1.4.8.dist-info}/top_level.txt +0 -0
|
@@ -21,7 +21,7 @@ def call_nexgen(
|
|
|
21
21
|
parameters: ExtruderParameters | FixedTargetParameters,
|
|
22
22
|
wavelength_in_a: float,
|
|
23
23
|
beam_center_in_pix: tuple[float, float],
|
|
24
|
-
start_time: datetime
|
|
24
|
+
start_time: datetime,
|
|
25
25
|
):
|
|
26
26
|
"""Call the nexus writer by sending a request to nexgen-server.
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ def call_nexgen(
|
|
|
32
32
|
parameters (SerialAndLaserExperiment): Collection parameters.
|
|
33
33
|
wavelength_in_a (float): Wavelength, in A.
|
|
34
34
|
beam_center_in_pix (list[float]): Beam center position on detector, in pixels.
|
|
35
|
-
start_time (datetime
|
|
35
|
+
start_time (datetime): Collection start time.
|
|
36
36
|
|
|
37
37
|
Raises:
|
|
38
38
|
ValueError: For a wrong experiment type passed (either unknwon or not matched \
|
|
@@ -96,7 +96,7 @@ def call_nexgen(
|
|
|
96
96
|
"visitpath": os.fspath(meta_h5.parent),
|
|
97
97
|
"wavelength": wavelength_in_a,
|
|
98
98
|
"bit_depth": bit_depth,
|
|
99
|
-
"start_time": start_time,
|
|
99
|
+
"start_time": start_time.isoformat(),
|
|
100
100
|
}
|
|
101
101
|
SSX_LOGGER.info(f"Sending POST request to {url} with payload:")
|
|
102
102
|
SSX_LOGGER.info(pprint.pformat(payload))
|
|
@@ -6,15 +6,18 @@ from dodal.devices.oav.oav_detector import OAV
|
|
|
6
6
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
7
7
|
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
8
8
|
|
|
9
|
-
from mx_bluesky.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
set_using_group = partial(bps.abs_set, group=CONST.WAIT.READY_FOR_OAV)
|
|
9
|
+
from mx_bluesky.common.parameters.constants import (
|
|
10
|
+
PlanGroupCheckpointConstants,
|
|
11
|
+
)
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
def setup_pin_tip_detection_params(
|
|
16
|
-
pin_tip_detect_device: PinTipDetection,
|
|
15
|
+
pin_tip_detect_device: PinTipDetection,
|
|
16
|
+
parameters: OAVParameters,
|
|
17
17
|
):
|
|
18
|
+
set_using_group = partial(
|
|
19
|
+
bps.abs_set, group=PlanGroupCheckpointConstants.READY_FOR_OAV
|
|
20
|
+
)
|
|
18
21
|
# select which blur to apply to image
|
|
19
22
|
yield from set_using_group(
|
|
20
23
|
pin_tip_detect_device.preprocess_operation, parameters.preprocess
|
|
@@ -55,6 +58,9 @@ def setup_pin_tip_detection_params(
|
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
def setup_general_oav_params(oav: OAV, parameters: OAVParameters):
|
|
61
|
+
set_using_group = partial(
|
|
62
|
+
bps.abs_set, group=PlanGroupCheckpointConstants.READY_FOR_OAV
|
|
63
|
+
)
|
|
58
64
|
yield from set_using_group(oav.cam.color_mode, ColorMode.RGB1)
|
|
59
65
|
yield from set_using_group(oav.cam.acquire_period, parameters.acquire_period)
|
|
60
66
|
yield from set_using_group(oav.cam.acquire_time, parameters.exposure)
|
|
@@ -78,4 +84,4 @@ def pre_centring_setup_oav(
|
|
|
78
84
|
"""
|
|
79
85
|
yield from setup_general_oav_params(oav, parameters)
|
|
80
86
|
yield from setup_pin_tip_detection_params(pin_tip_detection_device, parameters)
|
|
81
|
-
yield from bps.wait(
|
|
87
|
+
yield from bps.wait(PlanGroupCheckpointConstants.READY_FOR_OAV)
|
|
@@ -3,18 +3,17 @@ import numpy
|
|
|
3
3
|
from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
|
|
4
4
|
from dodal.devices.smargon import Smargon, StubPosition
|
|
5
5
|
|
|
6
|
+
from mx_bluesky.common.device_setup_plans.manipulate_sample import move_x_y_z
|
|
6
7
|
from mx_bluesky.common.utils.log import LOGGER
|
|
7
8
|
from mx_bluesky.common.utils.tracing import TRACER
|
|
8
9
|
from mx_bluesky.common.xrc_result import XRayCentreResult
|
|
9
|
-
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_x_y_z
|
|
10
|
-
from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def change_aperture_then_move_to_xtal(
|
|
14
13
|
best_hit: XRayCentreResult,
|
|
15
14
|
smargon: Smargon,
|
|
16
15
|
aperture_scatterguard: ApertureScatterguard,
|
|
17
|
-
|
|
16
|
+
set_stub_offsets: bool | None = None,
|
|
18
17
|
):
|
|
19
18
|
"""For the given x-ray centring result,
|
|
20
19
|
* Change the aperture so that the beam size is comparable to the crystal size
|
|
@@ -36,7 +35,7 @@ def change_aperture_then_move_to_xtal(
|
|
|
36
35
|
|
|
37
36
|
# TODO support for setting stub offsets in multipin
|
|
38
37
|
# https://github.com/DiamondLightSource/mx-bluesky/issues/552
|
|
39
|
-
if
|
|
38
|
+
if set_stub_offsets:
|
|
40
39
|
LOGGER.info("Recentring smargon co-ordinate system to this point.")
|
|
41
40
|
yield from bps.mv(smargon.stub_offsets, StubPosition.CURRENT_AS_CENTER)
|
|
42
41
|
|
|
@@ -72,4 +71,4 @@ def set_aperture_for_bbox_mm(
|
|
|
72
71
|
f"Setting aperture to {new_selected_aperture} based on bounding box size {bbox_size_mm}."
|
|
73
72
|
)
|
|
74
73
|
|
|
75
|
-
yield from bps.abs_set(aperture_device, new_selected_aperture)
|
|
74
|
+
yield from bps.abs_set(aperture_device.selected_aperture, new_selected_aperture)
|
|
@@ -14,13 +14,13 @@ from dodal.devices.oav.pin_image_recognition.utils import NONE_VALUE
|
|
|
14
14
|
from dodal.devices.oav.utils import PinNotFoundException, wait_for_tip_to_be_found
|
|
15
15
|
from dodal.devices.smargon import Smargon
|
|
16
16
|
|
|
17
|
+
from mx_bluesky.common.device_setup_plans.setup_oav import (
|
|
18
|
+
pre_centring_setup_oav,
|
|
19
|
+
)
|
|
20
|
+
from mx_bluesky.common.parameters.constants import DocDescriptorNames, HardwareConstants
|
|
17
21
|
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
18
22
|
from mx_bluesky.common.utils.exceptions import catch_exception_and_warn
|
|
19
23
|
from mx_bluesky.common.utils.log import LOGGER
|
|
20
|
-
from mx_bluesky.hyperion.device_setup_plans.setup_oav import (
|
|
21
|
-
pre_centring_setup_oav,
|
|
22
|
-
)
|
|
23
|
-
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
26
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
@@ -103,7 +103,7 @@ def grid_detection_plan(
|
|
|
103
103
|
yield from bps.mv(smargon.omega, angle)
|
|
104
104
|
# need to wait for the OAV image to update
|
|
105
105
|
# See #673 for improvements
|
|
106
|
-
yield from bps.sleep(
|
|
106
|
+
yield from bps.sleep(HardwareConstants.OAV_REFRESH_DELAY)
|
|
107
107
|
|
|
108
108
|
tip_x_px, tip_y_px = yield from catch_exception_and_warn(
|
|
109
109
|
PinNotFoundException, wait_for_tip_to_be_found, pin_tip_detection
|
|
@@ -163,7 +163,7 @@ def grid_detection_plan(
|
|
|
163
163
|
yield from bps.abs_set(oav.grid_snapshot.filename, snapshot_filename)
|
|
164
164
|
yield from bps.abs_set(oav.grid_snapshot.directory, snapshot_dir)
|
|
165
165
|
yield from bps.trigger(oav.grid_snapshot, wait=True)
|
|
166
|
-
yield from bps.create(
|
|
166
|
+
yield from bps.create(DocDescriptorNames.OAV_GRID_SNAPSHOT_TRIGGERED)
|
|
167
167
|
|
|
168
168
|
yield from bps.read(oav)
|
|
169
169
|
yield from bps.read(smargon)
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
4
|
from collections.abc import Callable, Sequence
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
|
6
7
|
|
|
7
8
|
from dodal.beamline_specific_utils.i03 import beam_size_from_aperture
|
|
@@ -26,7 +27,7 @@ from mx_bluesky.common.external_interaction.ispyb.ispyb_store import (
|
|
|
26
27
|
)
|
|
27
28
|
from mx_bluesky.common.external_interaction.ispyb.ispyb_utils import get_ispyb_config
|
|
28
29
|
from mx_bluesky.common.parameters.components import DiffractionExperimentWithSample
|
|
29
|
-
from mx_bluesky.common.parameters.constants import DocDescriptorNames
|
|
30
|
+
from mx_bluesky.common.parameters.constants import DocDescriptorNames
|
|
30
31
|
from mx_bluesky.common.utils.log import ISPYB_ZOCALO_CALLBACK_LOGGER, set_dcgid_tag
|
|
31
32
|
from mx_bluesky.common.utils.utils import convert_eV_to_angstrom
|
|
32
33
|
|
|
@@ -70,10 +71,10 @@ class BaseISPyBCallback(PlanReactiveCallback):
|
|
|
70
71
|
self.ispyb: StoreInIspyb
|
|
71
72
|
self.descriptors: dict[str, EventDescriptor] = {}
|
|
72
73
|
self.ispyb_config = get_ispyb_config()
|
|
73
|
-
|
|
74
|
-
self.ispyb_config
|
|
75
|
-
|
|
76
|
-
):
|
|
74
|
+
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
75
|
+
f"Using ISPyB configuration from {self.ispyb_config}"
|
|
76
|
+
)
|
|
77
|
+
if not self.ispyb_config or not Path(self.ispyb_config).is_absolute():
|
|
77
78
|
ISPYB_ZOCALO_CALLBACK_LOGGER.warning(
|
|
78
79
|
f"{self.__class__} using dev ISPyB config: {self.ispyb_config}. If you"
|
|
79
80
|
"want to use the real database, please set the ISPYB_CONFIG_PATH "
|
|
@@ -4,13 +4,8 @@ from collections.abc import Callable, Sequence
|
|
|
4
4
|
from time import time
|
|
5
5
|
from typing import TYPE_CHECKING, Any, TypeVar
|
|
6
6
|
|
|
7
|
-
import numpy as np
|
|
8
7
|
from bluesky import preprocessors as bpp
|
|
9
|
-
from bluesky.utils import MsgGenerator
|
|
10
|
-
from dodal.devices.zocalo.zocalo_results import (
|
|
11
|
-
ZOCALO_READING_PLAN_NAME,
|
|
12
|
-
get_processing_results_from_event,
|
|
13
|
-
)
|
|
8
|
+
from bluesky.utils import MsgGenerator, make_decorator
|
|
14
9
|
|
|
15
10
|
from mx_bluesky.common.external_interaction.callbacks.common.ispyb_callback_base import (
|
|
16
11
|
BaseISPyBCallback,
|
|
@@ -19,9 +14,6 @@ from mx_bluesky.common.external_interaction.callbacks.common.ispyb_mapping impor
|
|
|
19
14
|
populate_data_collection_group,
|
|
20
15
|
populate_remaining_data_collection_info,
|
|
21
16
|
)
|
|
22
|
-
from mx_bluesky.common.external_interaction.callbacks.common.logging_callback import (
|
|
23
|
-
format_doc_for_log,
|
|
24
|
-
)
|
|
25
17
|
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_mapping import (
|
|
26
18
|
construct_comment_for_gridscan,
|
|
27
19
|
populate_xy_data_collection_info,
|
|
@@ -71,6 +63,9 @@ def ispyb_activation_wrapper(plan_generator: MsgGenerator, parameters):
|
|
|
71
63
|
)
|
|
72
64
|
|
|
73
65
|
|
|
66
|
+
ispyb_activation_decorator = make_decorator(ispyb_activation_wrapper)
|
|
67
|
+
|
|
68
|
+
|
|
74
69
|
class GridscanISPyBCallback(BaseISPyBCallback):
|
|
75
70
|
"""Callback class to handle the deposition of experiment parameters into the ISPyB
|
|
76
71
|
database. Listens for 'event' and 'descriptor' documents. Creates the ISpyB entry on
|
|
@@ -103,6 +98,7 @@ class GridscanISPyBCallback(BaseISPyBCallback):
|
|
|
103
98
|
def activity_gated_start(self, doc: RunStart):
|
|
104
99
|
if doc.get("subplan_name") == PlanNameConstants.DO_FGS:
|
|
105
100
|
self._start_of_fgs_uid = doc.get("uid")
|
|
101
|
+
|
|
106
102
|
if doc.get("subplan_name") == PlanNameConstants.GRID_DETECT_AND_DO_GRIDSCAN:
|
|
107
103
|
self.uid_to_finalize_on = doc.get("uid")
|
|
108
104
|
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
@@ -146,12 +142,11 @@ class GridscanISPyBCallback(BaseISPyBCallback):
|
|
|
146
142
|
|
|
147
143
|
def activity_gated_event(self, doc: Event):
|
|
148
144
|
assert self.data_collection_group_info, ASSERT_START_BEFORE_EVENT_DOC_MESSAGE
|
|
145
|
+
|
|
149
146
|
doc = super().activity_gated_event(doc)
|
|
150
147
|
|
|
151
148
|
descriptor_name = self.descriptors[doc["descriptor"]].get("name")
|
|
152
|
-
if descriptor_name ==
|
|
153
|
-
self._handle_zocalo_read_event(doc)
|
|
154
|
-
elif descriptor_name == DocDescriptorNames.OAV_GRID_SNAPSHOT_TRIGGERED:
|
|
149
|
+
if descriptor_name == DocDescriptorNames.OAV_GRID_SNAPSHOT_TRIGGERED:
|
|
155
150
|
scan_data_infos = self._handle_oav_grid_snapshot_triggered(doc)
|
|
156
151
|
self.ispyb_ids = self.ispyb.update_deposition(
|
|
157
152
|
self.ispyb_ids, scan_data_infos
|
|
@@ -162,38 +157,10 @@ class GridscanISPyBCallback(BaseISPyBCallback):
|
|
|
162
157
|
|
|
163
158
|
return doc
|
|
164
159
|
|
|
165
|
-
def
|
|
160
|
+
def _add_processing_time_to_comment(self, processing_start_time: float):
|
|
166
161
|
assert self.data_collection_group_info, ASSERT_START_BEFORE_EVENT_DOC_MESSAGE
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
proc_time = time() - self._processing_start_time
|
|
170
|
-
crystal_summary = f"Zocalo processing took {proc_time:.2f} s. "
|
|
171
|
-
bboxes: list[np.ndarray] = []
|
|
172
|
-
ISPYB_ZOCALO_CALLBACK_LOGGER.info(
|
|
173
|
-
f"Amending comment based on Zocalo reading doc: {format_doc_for_log(doc)}"
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
raw_results = get_processing_results_from_event("zocalo", doc)
|
|
177
|
-
if len(raw_results) > 0:
|
|
178
|
-
for n, res in enumerate(raw_results):
|
|
179
|
-
bb = res["bounding_box"]
|
|
180
|
-
diff = np.array(bb[1]) - np.array(bb[0])
|
|
181
|
-
bboxes.append(diff)
|
|
182
|
-
|
|
183
|
-
nicely_formatted_com = [
|
|
184
|
-
f"{np.round(com, 2)}" for com in res["centre_of_mass"]
|
|
185
|
-
]
|
|
186
|
-
crystal_summary += (
|
|
187
|
-
f"Crystal {n + 1}: "
|
|
188
|
-
f"Strength {res['total_count']}; "
|
|
189
|
-
f"Position (grid boxes) {nicely_formatted_com}; "
|
|
190
|
-
f"Size (grid boxes) {bboxes[n]}; "
|
|
191
|
-
)
|
|
192
|
-
else:
|
|
193
|
-
crystal_summary += "Zocalo found no crystals in this gridscan."
|
|
194
|
-
assert self.ispyb_ids.data_collection_ids, (
|
|
195
|
-
"No data collection to add results to"
|
|
196
|
-
)
|
|
162
|
+
proc_time = time() - processing_start_time
|
|
163
|
+
crystal_summary = f"Zocalo processing took {proc_time:.2f} s."
|
|
197
164
|
|
|
198
165
|
self.data_collection_group_info.comments = (
|
|
199
166
|
self.data_collection_group_info.comments or ""
|
|
@@ -320,10 +287,12 @@ class GridscanISPyBCallback(BaseISPyBCallback):
|
|
|
320
287
|
if exception_type:
|
|
321
288
|
doc["reason"] = message
|
|
322
289
|
self.data_collection_group_info.comments = message
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
290
|
+
elif self._processing_start_time:
|
|
291
|
+
self._add_processing_time_to_comment(self._processing_start_time)
|
|
292
|
+
self.ispyb.update_data_collection_group_table(
|
|
293
|
+
self.data_collection_group_info,
|
|
294
|
+
self.ispyb_ids.data_collection_group_id,
|
|
295
|
+
)
|
|
327
296
|
self.data_collection_group_info = None
|
|
328
297
|
return super().activity_gated_stop(doc)
|
|
329
298
|
return self._tag_doc(doc)
|
|
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
|
|
7
7
|
import ispyb
|
|
8
8
|
import ispyb.sqlalchemy
|
|
9
|
+
import numpy as np
|
|
9
10
|
from ispyb.connector.mysqlsp.main import ISPyBMySQLSPConnector as Connector
|
|
10
11
|
from ispyb.sp.mxacquisition import MXAcquisition
|
|
11
12
|
from ispyb.strictordereddict import StrictOrderedDict
|
|
@@ -280,7 +281,9 @@ class StoreInIspyb:
|
|
|
280
281
|
conn, data_collection_info.visit_string
|
|
281
282
|
)
|
|
282
283
|
params |= {
|
|
283
|
-
k: v
|
|
284
|
+
k: v.item() if isinstance(v, np.generic) else v # Convert to native types
|
|
285
|
+
for k, v in asdict(data_collection_info).items()
|
|
286
|
+
if k != "visit_string"
|
|
284
287
|
}
|
|
285
288
|
|
|
286
289
|
return params
|
|
@@ -7,11 +7,11 @@ from ispyb import NoResult
|
|
|
7
7
|
from ispyb.connector.mysqlsp.main import ISPyBMySQLSPConnector as Connector
|
|
8
8
|
from ispyb.sp.core import Core
|
|
9
9
|
|
|
10
|
-
from mx_bluesky.common.parameters.constants import SimConstants
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
def get_ispyb_config() -> str:
|
|
12
|
+
ispyb_config = os.environ.get("ISPYB_CONFIG_PATH")
|
|
13
|
+
assert ispyb_config, "ISPYB_CONFIG_PATH must be set"
|
|
14
|
+
return ispyb_config
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def get_session_id_from_visit(conn: Connector, visit: str):
|
|
@@ -5,7 +5,7 @@ from abc import abstractmethod
|
|
|
5
5
|
from collections.abc import Sequence
|
|
6
6
|
from enum import StrEnum
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Literal, SupportsInt, cast
|
|
8
|
+
from typing import Literal, Self, SupportsInt, cast
|
|
9
9
|
|
|
10
10
|
from dodal.devices.aperturescatterguard import ApertureValue
|
|
11
11
|
from dodal.devices.detector import (
|
|
@@ -114,12 +114,32 @@ class MxBlueskyParameters(BaseModel):
|
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
class WithSnapshot(BaseModel):
|
|
117
|
+
"""
|
|
118
|
+
Configures how snapshot images are created.
|
|
119
|
+
Attributes:
|
|
120
|
+
snapshot_directory: Path to the directory where snapshot images will be stored
|
|
121
|
+
snapshot_omegas_deg: list of omega values at which snapshots will be taken. For
|
|
122
|
+
gridscans, this attribute is ignored.
|
|
123
|
+
use_grid_snapshots: This may be specified for rotation snapshots to speed up rotation
|
|
124
|
+
execution. If set to True then rotation snapshots are generated from the
|
|
125
|
+
previously captured grid snapshots. Otherwise they are captured using
|
|
126
|
+
freshly captured snapshots during the rotation plan.
|
|
127
|
+
"""
|
|
128
|
+
|
|
117
129
|
snapshot_directory: Path
|
|
118
130
|
snapshot_omegas_deg: list[float] | None = None
|
|
131
|
+
use_grid_snapshots: bool = False
|
|
119
132
|
|
|
120
133
|
@property
|
|
121
134
|
def take_snapshots(self) -> bool:
|
|
122
|
-
return bool(self.snapshot_omegas_deg)
|
|
135
|
+
return bool(self.snapshot_omegas_deg) or self.use_grid_snapshots
|
|
136
|
+
|
|
137
|
+
@model_validator(mode="after")
|
|
138
|
+
def _validate_omegas_with_grid_snapshots(self) -> Self:
|
|
139
|
+
assert not self.use_grid_snapshots or self.snapshot_omegas_deg is None, (
|
|
140
|
+
"snapshot_omegas may not be specified with use_grid_snapshots"
|
|
141
|
+
)
|
|
142
|
+
return self
|
|
123
143
|
|
|
124
144
|
|
|
125
145
|
class WithOptionalEnergyChange(BaseModel):
|
|
@@ -55,6 +55,7 @@ class PlanNameConstants:
|
|
|
55
55
|
ROBOT_LOAD_AND_SNAPSHOTS = "robot_load_and_snapshots"
|
|
56
56
|
# Rotation scan
|
|
57
57
|
ROTATION_MULTI = "multi_rotation_wrapper"
|
|
58
|
+
ROTATION_MULTI_OUTER = "multi_rotation_outer"
|
|
58
59
|
ROTATION_OUTER = "rotation_scan_with_cleanup"
|
|
59
60
|
ROTATION_MAIN = "rotation_scan_main"
|
|
60
61
|
FLYSCAN_RESULTS = "xray_centre_results"
|
|
@@ -67,17 +68,12 @@ class EnvironmentConstants:
|
|
|
67
68
|
ZOCALO_ENV = ZOCALO_ENV_FROM_DODAL
|
|
68
69
|
|
|
69
70
|
|
|
70
|
-
@dataclass(frozen=True)
|
|
71
|
-
class TriggerConstants:
|
|
72
|
-
ZOCALO = "trigger_zocalo_on"
|
|
73
|
-
|
|
74
|
-
|
|
75
71
|
@dataclass(frozen=True)
|
|
76
72
|
class HardwareConstants:
|
|
77
73
|
OAV_REFRESH_DELAY = 0.3
|
|
78
74
|
PANDA_FGS_RUN_UP_DEFAULT = 0.17
|
|
79
75
|
CRYOJET_MARGIN_MM = 0.2
|
|
80
|
-
THAWING_TIME =
|
|
76
|
+
THAWING_TIME = 40
|
|
81
77
|
TIP_OFFSET_UM = 0
|
|
82
78
|
|
|
83
79
|
# Value quoted in https://www.dectris.com/en/detectors/x-ray-detectors/eiger2/eiger2-for-synchrotrons/eiger2-x/,
|
|
@@ -94,6 +90,7 @@ class GridscanParamConstants:
|
|
|
94
90
|
OMEGA_1 = 0.0
|
|
95
91
|
OMEGA_2 = 90.0
|
|
96
92
|
PANDA_RUN_UP_DISTANCE_MM = 0.2
|
|
93
|
+
ZOCALO_MIN_TOTAL_COUNT_THRESHOLD = 3
|
|
97
94
|
|
|
98
95
|
|
|
99
96
|
@dataclass(frozen=True)
|
|
@@ -125,6 +122,7 @@ class PlanGroupCheckpointConstants:
|
|
|
125
122
|
ROTATION_READY_FOR_DC = "rotation_ready_for_data_collection"
|
|
126
123
|
MOVE_GONIO_TO_START = "move_gonio_to_start"
|
|
127
124
|
READY_FOR_OAV = "ready_for_oav"
|
|
125
|
+
PREPARE_APERTURE = "prepare_aperture"
|
|
128
126
|
|
|
129
127
|
|
|
130
128
|
# Eventually replace below with https://github.com/DiamondLightSource/mx-bluesky/issues/798
|
|
@@ -136,16 +134,6 @@ class DeviceSettingsConstants:
|
|
|
136
134
|
)
|
|
137
135
|
|
|
138
136
|
|
|
139
|
-
@dataclass(frozen=True)
|
|
140
|
-
class SimConstants:
|
|
141
|
-
BEAMLINE = "BL03S"
|
|
142
|
-
INSERTION_PREFIX = "SR03S"
|
|
143
|
-
# this one is for unit tests
|
|
144
|
-
ISPYB_CONFIG = "tests/test_data/test_config.cfg"
|
|
145
|
-
# this one is for system tests
|
|
146
|
-
DEV_ISPYB_DATABASE_CFG = "/dls_sw/dasc/mariadb/credentials/ispyb-hyperion-dev.cfg"
|
|
147
|
-
|
|
148
|
-
|
|
149
137
|
class Actions(Enum):
|
|
150
138
|
START = "start"
|
|
151
139
|
STOP = "stop"
|
|
@@ -26,7 +26,11 @@ from mx_bluesky.common.parameters.constants import (
|
|
|
26
26
|
HardwareConstants,
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
DETECTOR_SIZE_PER_BEAMLINE = {
|
|
29
|
+
DETECTOR_SIZE_PER_BEAMLINE = {
|
|
30
|
+
"i02-1": EIGER2_X_9M_SIZE,
|
|
31
|
+
"dev": EIGER2_X_16M_SIZE,
|
|
32
|
+
"i03": EIGER2_X_16M_SIZE,
|
|
33
|
+
}
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
class GridCommon(
|
|
@@ -50,6 +54,37 @@ class GridCommon(
|
|
|
50
54
|
|
|
51
55
|
tip_offset_um: float = Field(default=HardwareConstants.TIP_OFFSET_UM)
|
|
52
56
|
|
|
57
|
+
@property
|
|
58
|
+
def detector_params(self):
|
|
59
|
+
self.det_dist_to_beam_converter_path = (
|
|
60
|
+
self.det_dist_to_beam_converter_path
|
|
61
|
+
or DetectorParamConstants.BEAM_XY_LUT_PATH
|
|
62
|
+
)
|
|
63
|
+
optional_args = {}
|
|
64
|
+
if self.run_number:
|
|
65
|
+
optional_args["run_number"] = self.run_number
|
|
66
|
+
assert self.detector_distance_mm is not None, (
|
|
67
|
+
"Detector distance must be filled before generating DetectorParams"
|
|
68
|
+
)
|
|
69
|
+
return DetectorParams(
|
|
70
|
+
detector_size_constants=DETECTOR_SIZE_PER_BEAMLINE[
|
|
71
|
+
get_beamline_name("dev")
|
|
72
|
+
],
|
|
73
|
+
expected_energy_ev=self.demand_energy_ev,
|
|
74
|
+
exposure_time_s=self.exposure_time_s,
|
|
75
|
+
directory=self.storage_directory,
|
|
76
|
+
prefix=self.file_name,
|
|
77
|
+
detector_distance=self.detector_distance_mm,
|
|
78
|
+
omega_start=self.omega_start_deg or 0,
|
|
79
|
+
omega_increment=0,
|
|
80
|
+
num_images_per_trigger=1,
|
|
81
|
+
num_triggers=self.num_images,
|
|
82
|
+
use_roi_mode=self.use_roi_mode,
|
|
83
|
+
det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path,
|
|
84
|
+
trigger_mode=self.trigger_mode,
|
|
85
|
+
**optional_args,
|
|
86
|
+
)
|
|
87
|
+
|
|
53
88
|
|
|
54
89
|
class SpecifiedGrid(XyzStarts, WithScan):
|
|
55
90
|
"""A specified grid is one which has defined values for the start position,
|
|
@@ -150,34 +185,3 @@ class SpecifiedThreeDGridScan(
|
|
|
150
185
|
@property
|
|
151
186
|
def num_images(self) -> int:
|
|
152
187
|
return len(self.scan_points["sam_x"])
|
|
153
|
-
|
|
154
|
-
@property
|
|
155
|
-
def detector_params(self):
|
|
156
|
-
self.det_dist_to_beam_converter_path = (
|
|
157
|
-
self.det_dist_to_beam_converter_path
|
|
158
|
-
or DetectorParamConstants.BEAM_XY_LUT_PATH
|
|
159
|
-
)
|
|
160
|
-
optional_args = {}
|
|
161
|
-
if self.run_number:
|
|
162
|
-
optional_args["run_number"] = self.run_number
|
|
163
|
-
assert self.detector_distance_mm is not None, (
|
|
164
|
-
"Detector distance must be filled before generating DetectorParams"
|
|
165
|
-
)
|
|
166
|
-
return DetectorParams(
|
|
167
|
-
detector_size_constants=DETECTOR_SIZE_PER_BEAMLINE[
|
|
168
|
-
get_beamline_name("dev")
|
|
169
|
-
],
|
|
170
|
-
expected_energy_ev=self.demand_energy_ev,
|
|
171
|
-
exposure_time_s=self.exposure_time_s,
|
|
172
|
-
directory=self.storage_directory,
|
|
173
|
-
prefix=self.file_name,
|
|
174
|
-
detector_distance=self.detector_distance_mm,
|
|
175
|
-
omega_start=self.omega_start_deg or 0,
|
|
176
|
-
omega_increment=0,
|
|
177
|
-
num_images_per_trigger=1,
|
|
178
|
-
num_triggers=self.num_images,
|
|
179
|
-
use_roi_mode=self.use_roi_mode,
|
|
180
|
-
det_dist_to_beam_converter_path=self.det_dist_to_beam_converter_path,
|
|
181
|
-
trigger_mode=self.trigger_mode,
|
|
182
|
-
**optional_args,
|
|
183
|
-
)
|