mx-bluesky 1.5.10__py3-none-any.whl → 1.5.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mx_bluesky/_version.py +2 -2
- mx_bluesky/beamlines/aithre_lasershaping/goniometer_controls.py +2 -2
- mx_bluesky/beamlines/i02_1/parameters/gridscan.py +1 -1
- mx_bluesky/beamlines/i04/experiment_plans/i04_grid_detect_then_xray_centre_plan.py +7 -7
- mx_bluesky/beamlines/i04/thawing_plan.py +9 -9
- mx_bluesky/beamlines/i24/jungfrau_commissioning/experiment_plans/do_darks.py +55 -10
- mx_bluesky/beamlines/i24/jungfrau_commissioning/plan_stubs/do_external_acquisition.py +1 -1
- mx_bluesky/beamlines/i24/jungfrau_commissioning/plan_stubs/plan_utils.py +1 -1
- mx_bluesky/beamlines/i24/serial/__init__.py +7 -5
- mx_bluesky/beamlines/i24/serial/dcid.py +3 -3
- mx_bluesky/beamlines/i24/serial/extruder/{i24ssx_Extruder_Collect_py3v2.py → i24ssx_extruder_collect_py3v2.py} +65 -35
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_Collect_py3v1.py → i24ssx_chip_collect_py3v1.py} +5 -5
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_Manager_py3v1.py → i24ssx_chip_manager_py3v1.py} +46 -46
- mx_bluesky/beamlines/i24/serial/fixed_target/{i24ssx_Chip_StartUp_py3v1.py → i24ssx_chip_startup_py3v1.py} +3 -3
- mx_bluesky/beamlines/i24/serial/fixed_target/i24ssx_moveonclick.py +33 -33
- mx_bluesky/beamlines/i24/serial/log.py +11 -11
- mx_bluesky/beamlines/i24/serial/parameters/fixed_target/cs/cs_maker.json +3 -3
- mx_bluesky/beamlines/i24/serial/setup_beamline/ca.py +0 -12
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv.py +13 -32
- mx_bluesky/beamlines/i24/serial/setup_beamline/pv_abstract.py +5 -5
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_beamline.py +22 -249
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_detector.py +2 -2
- mx_bluesky/beamlines/i24/serial/setup_beamline/setup_zebra_plans.py +4 -4
- mx_bluesky/beamlines/i24/serial/web_gui_plans/general_plans.py +102 -15
- mx_bluesky/beamlines/i24/serial/write_nexus.py +4 -4
- mx_bluesky/common/experiment_plans/common_flyscan_xray_centre_plan.py +6 -6
- mx_bluesky/common/experiment_plans/common_grid_detect_then_xray_centre_plan.py +2 -2
- mx_bluesky/common/experiment_plans/inner_plans/do_fgs.py +1 -1
- mx_bluesky/common/experiment_plans/inner_plans/read_hardware.py +2 -2
- mx_bluesky/common/experiment_plans/inner_plans/udc_default_state.py +22 -1
- mx_bluesky/common/experiment_plans/inner_plans/write_sample_status.py +2 -2
- mx_bluesky/common/experiment_plans/oav_snapshot_plan.py +1 -1
- mx_bluesky/common/external_interaction/callbacks/common/ispyb_callback_base.py +3 -3
- mx_bluesky/common/external_interaction/callbacks/common/plan_reactive_callback.py +1 -1
- mx_bluesky/common/external_interaction/callbacks/common/zocalo_callback.py +2 -2
- mx_bluesky/common/external_interaction/callbacks/sample_handling/sample_handling_callback.py +3 -3
- mx_bluesky/common/external_interaction/callbacks/xray_centre/ispyb_callback.py +7 -5
- mx_bluesky/common/external_interaction/callbacks/xray_centre/nexus_callback.py +2 -2
- mx_bluesky/common/external_interaction/config_server.py +2 -2
- mx_bluesky/common/external_interaction/ispyb/exp_eye_store.py +4 -2
- mx_bluesky/common/external_interaction/ispyb/ispyb_store.py +0 -1
- mx_bluesky/common/external_interaction/nexus/nexus_utils.py +2 -2
- mx_bluesky/common/external_interaction/nexus/write_nexus.py +3 -3
- mx_bluesky/common/parameters/constants.py +1 -1
- mx_bluesky/common/parameters/gridscan.py +2 -2
- mx_bluesky/common/utils/exceptions.py +9 -7
- mx_bluesky/common/utils/log.py +4 -4
- mx_bluesky/common/utils/tracing.py +5 -5
- mx_bluesky/common/utils/utils.py +8 -8
- mx_bluesky/hyperion/__main__.py +5 -5
- mx_bluesky/hyperion/baton_handler.py +15 -8
- mx_bluesky/hyperion/device_setup_plans/smargon.py +5 -5
- mx_bluesky/hyperion/device_setup_plans/utils.py +1 -1
- mx_bluesky/hyperion/experiment_plans/experiment_registry.py +1 -1
- mx_bluesky/hyperion/experiment_plans/hyperion_flyscan_xray_centre_plan.py +15 -13
- mx_bluesky/hyperion/experiment_plans/load_centre_collect_full_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/optimise_attenuation_plan.py +9 -9
- mx_bluesky/hyperion/experiment_plans/pin_centre_then_xray_centre_plan.py +2 -2
- mx_bluesky/hyperion/experiment_plans/pin_tip_centring_plan.py +3 -3
- mx_bluesky/hyperion/experiment_plans/rotation_scan_plan.py +2 -2
- mx_bluesky/hyperion/external_interaction/agamemnon.py +2 -2
- mx_bluesky/hyperion/external_interaction/callbacks/__main__.py +2 -2
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/ispyb_callback.py +1 -1
- mx_bluesky/hyperion/external_interaction/callbacks/rotation/nexus_callback.py +2 -2
- mx_bluesky/hyperion/external_interaction/config_server.py +2 -2
- mx_bluesky/hyperion/parameters/constants.py +2 -2
- mx_bluesky/hyperion/parameters/gridscan.py +4 -4
- mx_bluesky/hyperion/plan_runner.py +6 -6
- mx_bluesky/hyperion/runner.py +10 -8
- mx_bluesky/jupyter_example.ipynb +3 -3
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/METADATA +6 -5
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/RECORD +76 -76
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/WHEEL +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/entry_points.txt +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/licenses/LICENSE +0 -0
- {mx_bluesky-1.5.10.dist-info → mx_bluesky-1.5.11.dist-info}/top_level.txt +0 -0
|
@@ -2,23 +2,23 @@ import numpy as np
|
|
|
2
2
|
from bluesky import plan_stubs as bps
|
|
3
3
|
from bluesky.utils import FailedStatus
|
|
4
4
|
from dodal.devices.smargon import CombinedMove, Smargon
|
|
5
|
-
from ophyd_async.epics.motor import
|
|
5
|
+
from ophyd_async.epics.motor import MotorLimitsError
|
|
6
6
|
|
|
7
|
-
from mx_bluesky.common.utils.exceptions import
|
|
7
|
+
from mx_bluesky.common.utils.exceptions import SampleError
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def move_smargon_warn_on_out_of_range(
|
|
11
11
|
smargon: Smargon, position: np.ndarray | list[float] | tuple[float, float, float]
|
|
12
12
|
):
|
|
13
|
-
"""Throws a
|
|
13
|
+
"""Throws a SampleError if the specified position is out of range for the
|
|
14
14
|
smargon. Otherwise moves to that position. The check is from ophyd-async"""
|
|
15
15
|
try:
|
|
16
16
|
yield from bps.mv(
|
|
17
17
|
smargon, CombinedMove(x=position[0], y=position[1], z=position[2])
|
|
18
18
|
)
|
|
19
19
|
except FailedStatus as fs:
|
|
20
|
-
if isinstance(fs.__cause__,
|
|
21
|
-
raise
|
|
20
|
+
if isinstance(fs.__cause__, MotorLimitsError):
|
|
21
|
+
raise SampleError(
|
|
22
22
|
"Pin tip centring failed - pin too long/short/bent and out of range"
|
|
23
23
|
) from fs.__cause__
|
|
24
24
|
else:
|
|
@@ -7,6 +7,6 @@ from dodal.devices.i03.dcm import DCM
|
|
|
7
7
|
|
|
8
8
|
def fill_in_energy_if_not_supplied(dcm: DCM, detector_params: DetectorParams):
|
|
9
9
|
if not detector_params.expected_energy_ev:
|
|
10
|
-
actual_energy_ev = 1000 * (yield from bps.rd(dcm.
|
|
10
|
+
actual_energy_ev = 1000 * (yield from bps.rd(dcm.energy_in_keV))
|
|
11
11
|
detector_params.expected_energy_ev = actual_energy_ev
|
|
12
12
|
return detector_params
|
|
@@ -15,7 +15,7 @@ from mx_bluesky.common.device_setup_plans.setup_zebra_and_shutter import (
|
|
|
15
15
|
tidy_up_zebra_after_gridscan,
|
|
16
16
|
)
|
|
17
17
|
from mx_bluesky.common.experiment_plans.common_flyscan_xray_centre_plan import (
|
|
18
|
-
|
|
18
|
+
construct_beamline_specific_fast_gridscan_features,
|
|
19
19
|
)
|
|
20
20
|
from mx_bluesky.common.utils.log import LOGGER
|
|
21
21
|
from mx_bluesky.hyperion.device_setup_plans.setup_panda import (
|
|
@@ -35,7 +35,7 @@ from mx_bluesky.hyperion.parameters.device_composites import (
|
|
|
35
35
|
from mx_bluesky.hyperion.parameters.gridscan import HyperionSpecifiedThreeDGridScan
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
38
|
+
class SmargonSpeedError(Exception):
|
|
39
39
|
pass
|
|
40
40
|
|
|
41
41
|
|
|
@@ -54,14 +54,14 @@ def construct_hyperion_specific_features(
|
|
|
54
54
|
xrc_composite.smargon.x,
|
|
55
55
|
xrc_composite.smargon.y,
|
|
56
56
|
xrc_composite.smargon.z,
|
|
57
|
-
xrc_composite.dcm.
|
|
57
|
+
xrc_composite.dcm.energy_in_keV,
|
|
58
58
|
]
|
|
59
59
|
|
|
60
60
|
signals_to_read_during_collection = [
|
|
61
61
|
xrc_composite.aperture_scatterguard,
|
|
62
62
|
xrc_composite.attenuator.actual_transmission,
|
|
63
63
|
xrc_composite.flux.flux_reading,
|
|
64
|
-
xrc_composite.dcm.
|
|
64
|
+
xrc_composite.dcm.energy_in_keV,
|
|
65
65
|
xrc_composite.eiger.bit_depth,
|
|
66
66
|
]
|
|
67
67
|
|
|
@@ -73,7 +73,7 @@ def construct_hyperion_specific_features(
|
|
|
73
73
|
set_flyscan_params_plan = partial(
|
|
74
74
|
set_fast_grid_scan_params,
|
|
75
75
|
xrc_composite.panda_fast_grid_scan,
|
|
76
|
-
xrc_parameters.
|
|
76
|
+
xrc_parameters.panda_fast_gridscan_params,
|
|
77
77
|
)
|
|
78
78
|
fgs_motors = xrc_composite.panda_fast_grid_scan
|
|
79
79
|
|
|
@@ -91,10 +91,10 @@ def construct_hyperion_specific_features(
|
|
|
91
91
|
set_flyscan_params_plan = partial(
|
|
92
92
|
set_fast_grid_scan_params,
|
|
93
93
|
xrc_composite.zebra_fast_grid_scan,
|
|
94
|
-
xrc_parameters.
|
|
94
|
+
xrc_parameters.fast_gridscan_params,
|
|
95
95
|
)
|
|
96
96
|
fgs_motors = xrc_composite.zebra_fast_grid_scan
|
|
97
|
-
return
|
|
97
|
+
return construct_beamline_specific_fast_gridscan_features(
|
|
98
98
|
setup_trigger_plan,
|
|
99
99
|
tidy_plan,
|
|
100
100
|
set_flyscan_params_plan,
|
|
@@ -126,21 +126,23 @@ def _panda_triggering_setup(
|
|
|
126
126
|
xrc_composite.panda_fast_grid_scan.run_up_distance_mm
|
|
127
127
|
)
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
detector_deadtime_s = 1e-4 # This value was empirically found to be safer than the documented deadtime in the Eiger manual
|
|
130
130
|
|
|
131
|
-
time_between_x_steps_ms = (
|
|
131
|
+
time_between_x_steps_ms = (detector_deadtime_s + parameters.exposure_time_s) * 1e3
|
|
132
132
|
|
|
133
133
|
smargon_speed_limit_mm_per_s = yield from bps.rd(
|
|
134
134
|
xrc_composite.smargon.x.max_velocity
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
sample_velocity_mm_per_s = (
|
|
138
|
-
parameters.
|
|
138
|
+
parameters.panda_fast_gridscan_params.x_step_size_mm
|
|
139
|
+
* 1e3
|
|
140
|
+
/ time_between_x_steps_ms
|
|
139
141
|
)
|
|
140
142
|
if sample_velocity_mm_per_s > smargon_speed_limit_mm_per_s:
|
|
141
|
-
raise
|
|
143
|
+
raise SmargonSpeedError(
|
|
142
144
|
f"Smargon speed was calculated from x step size\
|
|
143
|
-
{parameters.
|
|
145
|
+
{parameters.panda_fast_gridscan_params.x_step_size_mm}mm and\
|
|
144
146
|
time_between_x_steps_ms {time_between_x_steps_ms} as\
|
|
145
147
|
{sample_velocity_mm_per_s}mm/s. The smargon's speed limit is\
|
|
146
148
|
{smargon_speed_limit_mm_per_s}mm/s."
|
|
@@ -161,7 +163,7 @@ def _panda_triggering_setup(
|
|
|
161
163
|
|
|
162
164
|
yield from setup_panda_for_flyscan(
|
|
163
165
|
xrc_composite.panda,
|
|
164
|
-
parameters.
|
|
166
|
+
parameters.panda_fast_gridscan_params,
|
|
165
167
|
xrc_composite.smargon,
|
|
166
168
|
parameters.exposure_time_s,
|
|
167
169
|
time_between_x_steps_ms,
|
|
@@ -14,7 +14,7 @@ from dodal.devices.oav.oav_parameters import OAVParameters
|
|
|
14
14
|
import mx_bluesky.common.xrc_result as flyscan_result
|
|
15
15
|
from mx_bluesky.common.parameters.components import WithSnapshot
|
|
16
16
|
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
17
|
-
from mx_bluesky.common.utils.exceptions import
|
|
17
|
+
from mx_bluesky.common.utils.exceptions import CrystalNotFoundError
|
|
18
18
|
from mx_bluesky.common.utils.log import LOGGER
|
|
19
19
|
from mx_bluesky.common.xrc_result import XRayCentreEventHandler
|
|
20
20
|
from mx_bluesky.hyperion.experiment_plans.robot_load_then_centre_plan import (
|
|
@@ -93,7 +93,7 @@ def load_centre_collect_full(
|
|
|
93
93
|
),
|
|
94
94
|
flyscan_event_handler,
|
|
95
95
|
)
|
|
96
|
-
except
|
|
96
|
+
except CrystalNotFoundError:
|
|
97
97
|
if parameters.select_centres.ignore_xtal_not_found:
|
|
98
98
|
LOGGER.info("Ignoring crystal not found due to parameter settings.")
|
|
99
99
|
else:
|
|
@@ -13,7 +13,7 @@ from mx_bluesky.common.utils.context import device_composite_from_context
|
|
|
13
13
|
from mx_bluesky.common.utils.log import LOGGER
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
class AttenuationOptimisationFailedError(Exception):
|
|
17
17
|
pass
|
|
18
18
|
|
|
19
19
|
|
|
@@ -59,7 +59,7 @@ def check_parameters(
|
|
|
59
59
|
|
|
60
60
|
if upper_transmission < lower_transmission:
|
|
61
61
|
raise ValueError(
|
|
62
|
-
f"Upper transmission limit {upper_transmission} must be greater than lower
|
|
62
|
+
f"Upper transmission limit {upper_transmission} must be greater than lower transmission limit {lower_transmission}"
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
if not upper_transmission >= initial_transmission >= lower_transmission:
|
|
@@ -80,7 +80,7 @@ def calculate_new_direction(direction: Direction, deadtime, deadtime_threshold):
|
|
|
80
80
|
if deadtime > deadtime_threshold:
|
|
81
81
|
direction = Direction.NEGATIVE
|
|
82
82
|
LOGGER.info(
|
|
83
|
-
"Found
|
|
83
|
+
"Found transmission to go above deadtime threshold. Reducing transmission..."
|
|
84
84
|
)
|
|
85
85
|
return direction
|
|
86
86
|
|
|
@@ -111,7 +111,7 @@ def deadtime_calc_new_transmission(
|
|
|
111
111
|
Minimum expected transmission. Raise an error if transmission goes lower.
|
|
112
112
|
|
|
113
113
|
Raises:
|
|
114
|
-
|
|
114
|
+
AttenuationOptimisationFailedError:
|
|
115
115
|
This error is thrown if the transmission goes below the expected value or if the maximum cycles are reached
|
|
116
116
|
|
|
117
117
|
Returns:
|
|
@@ -124,7 +124,7 @@ def deadtime_calc_new_transmission(
|
|
|
124
124
|
else:
|
|
125
125
|
transmission /= increment
|
|
126
126
|
if transmission < lower_transmission_limit:
|
|
127
|
-
raise
|
|
127
|
+
raise AttenuationOptimisationFailedError(
|
|
128
128
|
"Calculated transmission is below expected limit"
|
|
129
129
|
)
|
|
130
130
|
return transmission
|
|
@@ -218,7 +218,7 @@ def deadtime_optimisation(
|
|
|
218
218
|
Minimum expected transmission. Raise an error if transmission goes lower.
|
|
219
219
|
|
|
220
220
|
Raises:
|
|
221
|
-
|
|
221
|
+
AttenuationOptimisationFailedError:
|
|
222
222
|
This error is thrown if the transmission goes below the expected value or the maximum cycles are reached
|
|
223
223
|
|
|
224
224
|
Returns:
|
|
@@ -262,7 +262,7 @@ def deadtime_optimisation(
|
|
|
262
262
|
break
|
|
263
263
|
|
|
264
264
|
if cycle == max_cycles - 1:
|
|
265
|
-
raise
|
|
265
|
+
raise AttenuationOptimisationFailedError(
|
|
266
266
|
f"Unable to optimise attenuation after maximum cycles.\
|
|
267
267
|
Deadtime did not get lower than threshold: {deadtime_threshold} in maximum cycles {max_cycles}"
|
|
268
268
|
)
|
|
@@ -367,12 +367,12 @@ def total_counts_optimisation(
|
|
|
367
367
|
if transmission > upper_transmission_limit:
|
|
368
368
|
transmission = upper_transmission_limit
|
|
369
369
|
elif transmission < lower_transmission_limit:
|
|
370
|
-
raise
|
|
370
|
+
raise AttenuationOptimisationFailedError(
|
|
371
371
|
f"Transmission has gone below lower threshold {lower_transmission_limit}"
|
|
372
372
|
)
|
|
373
373
|
|
|
374
374
|
if cycle == max_cycles - 1:
|
|
375
|
-
raise
|
|
375
|
+
raise AttenuationOptimisationFailedError(
|
|
376
376
|
f"Unable to optimise attenuation after maximum cycles.\
|
|
377
377
|
Total count is not within limits: {lower_count_limit} <= {total_count}\
|
|
378
378
|
<= {upper_count_limit}"
|
|
@@ -19,7 +19,7 @@ from mx_bluesky.common.experiment_plans.common_grid_detect_then_xray_centre_plan
|
|
|
19
19
|
detect_grid_and_do_gridscan,
|
|
20
20
|
)
|
|
21
21
|
from mx_bluesky.common.experiment_plans.oav_snapshot_plan import (
|
|
22
|
-
|
|
22
|
+
setup_beamline_for_oav,
|
|
23
23
|
)
|
|
24
24
|
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
25
25
|
ispyb_activation_wrapper,
|
|
@@ -84,7 +84,7 @@ def pin_centre_then_flyscan_plan(
|
|
|
84
84
|
)
|
|
85
85
|
|
|
86
86
|
def _pin_centre_then_flyscan_plan():
|
|
87
|
-
yield from
|
|
87
|
+
yield from setup_beamline_for_oav(
|
|
88
88
|
composite.smargon, composite.backlight, composite.aperture_scatterguard
|
|
89
89
|
)
|
|
90
90
|
|
|
@@ -18,7 +18,7 @@ from dodal.devices.smargon import Smargon
|
|
|
18
18
|
|
|
19
19
|
from mx_bluesky.common.device_setup_plans.setup_oav import pre_centring_setup_oav
|
|
20
20
|
from mx_bluesky.common.utils.context import device_composite_from_context
|
|
21
|
-
from mx_bluesky.common.utils.exceptions import
|
|
21
|
+
from mx_bluesky.common.utils.exceptions import SampleError, catch_exception_and_warn
|
|
22
22
|
from mx_bluesky.common.utils.log import LOGGER
|
|
23
23
|
from mx_bluesky.hyperion.device_setup_plans.smargon import (
|
|
24
24
|
move_smargon_warn_on_out_of_range,
|
|
@@ -69,7 +69,7 @@ def move_pin_into_view(
|
|
|
69
69
|
max_steps (int, optional): The number of steps to search with. Defaults to 2.
|
|
70
70
|
|
|
71
71
|
Raises:
|
|
72
|
-
|
|
72
|
+
SampleError: Error if the pin tip is never found
|
|
73
73
|
|
|
74
74
|
Returns:
|
|
75
75
|
Tuple[int, int]: The location of the pin tip in pixels
|
|
@@ -106,7 +106,7 @@ def move_pin_into_view(
|
|
|
106
106
|
tip_xy_px = yield from trigger_and_return_pin_tip(pin_tip_device)
|
|
107
107
|
|
|
108
108
|
if not pin_tip_valid(tip_xy_px):
|
|
109
|
-
raise
|
|
109
|
+
raise SampleError(
|
|
110
110
|
"Pin tip centring failed - pin too long/short/bent and out of range"
|
|
111
111
|
)
|
|
112
112
|
else:
|
|
@@ -49,7 +49,7 @@ from mx_bluesky.common.experiment_plans.inner_plans.read_hardware import (
|
|
|
49
49
|
from mx_bluesky.common.experiment_plans.oav_snapshot_plan import (
|
|
50
50
|
OavSnapshotComposite,
|
|
51
51
|
oav_snapshot_plan,
|
|
52
|
-
|
|
52
|
+
setup_beamline_for_oav,
|
|
53
53
|
)
|
|
54
54
|
from mx_bluesky.common.parameters.components import WithSnapshot
|
|
55
55
|
from mx_bluesky.common.preprocessors.preprocessors import (
|
|
@@ -346,7 +346,7 @@ def _move_and_rotation(
|
|
|
346
346
|
yield from bps.wait(CONST.WAIT.MOVE_GONIO_TO_START)
|
|
347
347
|
|
|
348
348
|
if not params.use_grid_snapshots:
|
|
349
|
-
yield from
|
|
349
|
+
yield from setup_beamline_for_oav(
|
|
350
350
|
composite.smargon,
|
|
351
351
|
composite.backlight,
|
|
352
352
|
composite.aperture_scatterguard,
|
|
@@ -23,7 +23,7 @@ from mx_bluesky.common.parameters.constants import (
|
|
|
23
23
|
GridscanParamConstants,
|
|
24
24
|
)
|
|
25
25
|
from mx_bluesky.common.utils.log import LOGGER
|
|
26
|
-
from mx_bluesky.common.utils.utils import
|
|
26
|
+
from mx_bluesky.common.utils.utils import convert_angstrom_to_ev
|
|
27
27
|
from mx_bluesky.hyperion.parameters.components import Wait
|
|
28
28
|
from mx_bluesky.hyperion.parameters.load_centre_collect import LoadCentreCollect
|
|
29
29
|
|
|
@@ -222,7 +222,7 @@ def _get_withenergy_parameters_from_agamemnon(parameters: dict) -> dict[str, Any
|
|
|
222
222
|
first_collection: dict = parameters["collection"][0]
|
|
223
223
|
wavelength = first_collection.get("wavelength")
|
|
224
224
|
assert isinstance(wavelength, float)
|
|
225
|
-
demand_energy_ev =
|
|
225
|
+
demand_energy_ev = convert_angstrom_to_ev(wavelength)
|
|
226
226
|
return {"demand_energy_ev": demand_energy_ev}
|
|
227
227
|
except (KeyError, IndexError, AttributeError, TypeError):
|
|
228
228
|
return {"demand_energy_ev": None}
|
|
@@ -5,7 +5,7 @@ from time import sleep # noqa
|
|
|
5
5
|
|
|
6
6
|
from bluesky.callbacks import CallbackBase
|
|
7
7
|
from bluesky.callbacks.zmq import Proxy, RemoteDispatcher
|
|
8
|
-
from dodal.log import LOGGER as
|
|
8
|
+
from dodal.log import LOGGER as DODAL_LOGGER
|
|
9
9
|
from dodal.log import set_up_all_logging_handlers
|
|
10
10
|
|
|
11
11
|
from mx_bluesky.common.external_interaction.alerting import set_alerting_service
|
|
@@ -124,7 +124,7 @@ def setup_logging(dev_mode: bool):
|
|
|
124
124
|
log_info(f"Loggers initialised with dev_mode={dev_mode}")
|
|
125
125
|
nexgen_logger = logging.getLogger("nexgen")
|
|
126
126
|
nexgen_logger.parent = NEXUS_LOGGER
|
|
127
|
-
|
|
127
|
+
DODAL_LOGGER.parent = ISPYB_ZOCALO_CALLBACK_LOGGER
|
|
128
128
|
log_debug("nexgen logger added to nexus logger")
|
|
129
129
|
|
|
130
130
|
|
|
@@ -46,7 +46,7 @@ class RotationISPyBCallback(BaseISPyBCallback):
|
|
|
46
46
|
To use, subscribe the Bluesky RunEngine to an instance of this class.
|
|
47
47
|
E.g.:
|
|
48
48
|
ispyb_handler_callback = RotationISPyBCallback(parameters)
|
|
49
|
-
|
|
49
|
+
run_engine.subscribe(ispyb_handler_callback)
|
|
50
50
|
Or decorate a plan using bluesky.preprocessors.subs_decorator.
|
|
51
51
|
|
|
52
52
|
See: https://blueskyproject.io/bluesky/callbacks.html#ways-to-invoke-callbacks
|
|
@@ -29,7 +29,7 @@ class RotationNexusFileCallback(PlanReactiveCallback):
|
|
|
29
29
|
To use, subscribe the Bluesky RunEngine to an instance of this class.
|
|
30
30
|
E.g.:
|
|
31
31
|
nexus_file_handler_callback = NexusFileCallback(parameters)
|
|
32
|
-
|
|
32
|
+
run_engine.subscribe(nexus_file_handler_callback)
|
|
33
33
|
Or decorate a plan using bluesky.preprocessors.subs_decorator.
|
|
34
34
|
|
|
35
35
|
See: https://blueskyproject.io/bluesky/callbacks.html#ways-to-invoke-callbacks
|
|
@@ -65,7 +65,7 @@ class RotationNexusFileCallback(PlanReactiveCallback):
|
|
|
65
65
|
self.writer.beam,
|
|
66
66
|
self.writer.attenuator,
|
|
67
67
|
) = create_beam_and_attenuator_parameters(
|
|
68
|
-
data["dcm-
|
|
68
|
+
data["dcm-energy_in_keV"],
|
|
69
69
|
data["flux-flux_reading"],
|
|
70
70
|
data["attenuator-actual_transmission"],
|
|
71
71
|
)
|
|
@@ -3,14 +3,14 @@ from functools import cache
|
|
|
3
3
|
from mx_bluesky.common.external_interaction.config_server import MXConfigClient
|
|
4
4
|
from mx_bluesky.hyperion.parameters.constants import (
|
|
5
5
|
HyperionFeatureSetting,
|
|
6
|
-
|
|
6
|
+
HyperionFeatureSettingSources,
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@cache
|
|
11
11
|
def get_hyperion_config_client() -> MXConfigClient[HyperionFeatureSetting]:
|
|
12
12
|
return MXConfigClient(
|
|
13
|
-
feature_sources=
|
|
13
|
+
feature_sources=HyperionFeatureSettingSources,
|
|
14
14
|
feature_dc=HyperionFeatureSetting,
|
|
15
15
|
url="https://daq-config.diamond.ac.uk",
|
|
16
16
|
)
|
|
@@ -9,7 +9,7 @@ from mx_bluesky.common.parameters.constants import (
|
|
|
9
9
|
EnvironmentConstants,
|
|
10
10
|
ExperimentParamConstants,
|
|
11
11
|
FeatureSetting,
|
|
12
|
-
|
|
12
|
+
FeatureSettingSources,
|
|
13
13
|
HardwareConstants,
|
|
14
14
|
OavConstants,
|
|
15
15
|
PlanGroupCheckpointConstants,
|
|
@@ -32,7 +32,7 @@ class I03Constants:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
# These currently exist in GDA domain.properties
|
|
35
|
-
class
|
|
35
|
+
class HyperionFeatureSettingSources(FeatureSettingSources):
|
|
36
36
|
USE_GPU_RESULTS = "gda.mx.hyperion.xrc.use_gpu_results"
|
|
37
37
|
USE_PANDA_FOR_GRIDSCAN = "gda.mx.hyperion.use_panda_for_gridscans"
|
|
38
38
|
SET_STUB_OFFSETS = "gda.mx.hyperion.do_stub_offsets"
|
|
@@ -44,7 +44,7 @@ class HyperionSpecifiedThreeDGridScan(SpecifiedThreeDGridScan):
|
|
|
44
44
|
|
|
45
45
|
# Relative to common grid scan, stub offsets are defined by config server
|
|
46
46
|
@property
|
|
47
|
-
def
|
|
47
|
+
def fast_gridscan_params(self) -> ZebraGridScanParamsThreeD:
|
|
48
48
|
return ZebraGridScanParamsThreeD(
|
|
49
49
|
x_steps=self.x_steps,
|
|
50
50
|
y_steps=self.y_steps,
|
|
@@ -65,10 +65,10 @@ class HyperionSpecifiedThreeDGridScan(SpecifiedThreeDGridScan):
|
|
|
65
65
|
)
|
|
66
66
|
|
|
67
67
|
@property
|
|
68
|
-
def
|
|
68
|
+
def panda_fast_gridscan_params(self) -> PandAGridScanParams:
|
|
69
69
|
if self.y_steps % 2 and self.z_steps > 0:
|
|
70
70
|
# See https://github.com/DiamondLightSource/hyperion/issues/1118 for explanation
|
|
71
|
-
raise
|
|
71
|
+
raise OddYStepsError(
|
|
72
72
|
"The number of Y steps must be even for a PandA gridscan"
|
|
73
73
|
)
|
|
74
74
|
return PandAGridScanParams(
|
|
@@ -93,7 +93,7 @@ class HyperionSpecifiedThreeDGridScan(SpecifiedThreeDGridScan):
|
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
class
|
|
96
|
+
class OddYStepsError(Exception): ...
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
class PinTipCentreThenXrayCentre(GridCommonWithHyperionDetectorParams):
|
|
@@ -5,12 +5,12 @@ from blueapi.core import BlueskyContext
|
|
|
5
5
|
from bluesky.utils import MsgGenerator, RequestAbort
|
|
6
6
|
|
|
7
7
|
from mx_bluesky.common.parameters.constants import Status
|
|
8
|
-
from mx_bluesky.common.utils.exceptions import
|
|
8
|
+
from mx_bluesky.common.utils.exceptions import WarningError
|
|
9
9
|
from mx_bluesky.common.utils.log import LOGGER
|
|
10
10
|
from mx_bluesky.hyperion.runner import BaseRunner
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class PlanError(Exception):
|
|
14
14
|
"""Identifies an exception that was encountered during plan execution."""
|
|
15
15
|
|
|
16
16
|
pass
|
|
@@ -32,7 +32,7 @@ class PlanRunner(BaseRunner):
|
|
|
32
32
|
Args:
|
|
33
33
|
experiment: The experiment to run
|
|
34
34
|
Raises:
|
|
35
|
-
|
|
35
|
+
PlanError: If the plan raised an exception
|
|
36
36
|
RequestAbort: If the RunEngine aborted during execution"""
|
|
37
37
|
|
|
38
38
|
self.current_status = Status.BUSY
|
|
@@ -40,7 +40,7 @@ class PlanRunner(BaseRunner):
|
|
|
40
40
|
try:
|
|
41
41
|
yield from experiment()
|
|
42
42
|
self.current_status = Status.IDLE
|
|
43
|
-
except
|
|
43
|
+
except WarningError as e:
|
|
44
44
|
LOGGER.warning("Plan failed with warning", exc_info=e)
|
|
45
45
|
self.current_status = Status.FAILED
|
|
46
46
|
except RequestAbort:
|
|
@@ -50,7 +50,7 @@ class PlanRunner(BaseRunner):
|
|
|
50
50
|
except Exception as e:
|
|
51
51
|
LOGGER.error("Plan failed with exception", exc_info=e)
|
|
52
52
|
self.current_status = Status.FAILED
|
|
53
|
-
raise
|
|
53
|
+
raise PlanError("Exception thrown in plan execution") from e
|
|
54
54
|
|
|
55
55
|
def shutdown(self):
|
|
56
56
|
"""Performs a prompt shutdown. Aborts the run engine and terminates the loop
|
|
@@ -61,7 +61,7 @@ class PlanRunner(BaseRunner):
|
|
|
61
61
|
# abort() causes the run engine to throw a RequestAbort exception
|
|
62
62
|
# inside the plan, which will propagate through the contingency wrappers.
|
|
63
63
|
# When the plan returns, the run engine will raise RunEngineInterrupted
|
|
64
|
-
self.
|
|
64
|
+
self.run_engine.abort()
|
|
65
65
|
except Exception as e:
|
|
66
66
|
LOGGER.warning(
|
|
67
67
|
"Exception encountered when issuing abort() to RunEngine:",
|
mx_bluesky/hyperion/runner.py
CHANGED
|
@@ -14,7 +14,7 @@ from mx_bluesky.common.external_interaction.callbacks.common.log_uid_tag_callbac
|
|
|
14
14
|
)
|
|
15
15
|
from mx_bluesky.common.parameters.components import MxBlueskyParameters
|
|
16
16
|
from mx_bluesky.common.parameters.constants import Actions, Status
|
|
17
|
-
from mx_bluesky.common.utils.exceptions import
|
|
17
|
+
from mx_bluesky.common.utils.exceptions import WarningError
|
|
18
18
|
from mx_bluesky.common.utils.log import LOGGER
|
|
19
19
|
from mx_bluesky.common.utils.tracing import TRACER
|
|
20
20
|
from mx_bluesky.hyperion.experiment_plans.experiment_registry import PLAN_REGISTRY
|
|
@@ -65,15 +65,15 @@ class BaseRunner:
|
|
|
65
65
|
|
|
66
66
|
def __init__(self, context: BlueskyContext):
|
|
67
67
|
self.context: BlueskyContext = context
|
|
68
|
-
self.
|
|
69
|
-
# These references are necessary to maintain liveness of callbacks because
|
|
68
|
+
self.run_engine = context.run_engine
|
|
69
|
+
# These references are necessary to maintain liveness of callbacks because run_engine
|
|
70
70
|
# only keeps a weakref
|
|
71
71
|
self._logging_uid_tag_callback = LogUidTaggingCallback()
|
|
72
72
|
self._publisher = Publisher(f"localhost:{CONST.CALLBACK_0MQ_PROXY_PORTS[0]}")
|
|
73
73
|
|
|
74
|
-
self.
|
|
74
|
+
self.run_engine.subscribe(self._logging_uid_tag_callback)
|
|
75
75
|
LOGGER.info("Connecting to external callback ZMQ proxy...")
|
|
76
|
-
self.
|
|
76
|
+
self.run_engine.subscribe(self._publisher)
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
class GDARunner(BaseRunner):
|
|
@@ -145,7 +145,7 @@ class GDARunner(BaseRunner):
|
|
|
145
145
|
# abort() causes the run engine to throw a RequestAbort exception
|
|
146
146
|
# inside the plan, which will propagate through the contingency wrappers.
|
|
147
147
|
# When the plan returns, the run engine will raise RunEngineInterrupted
|
|
148
|
-
self.
|
|
148
|
+
self.run_engine.abort()
|
|
149
149
|
self.current_status = StatusAndMessage(Status.IDLE)
|
|
150
150
|
except Exception as e:
|
|
151
151
|
self.current_status = make_error_status_and_message(e)
|
|
@@ -171,12 +171,14 @@ class GDARunner(BaseRunner):
|
|
|
171
171
|
raise ValueError("No experiment provided for START")
|
|
172
172
|
try:
|
|
173
173
|
with TRACER.start_span("do_run"):
|
|
174
|
-
self.
|
|
174
|
+
self.run_engine(
|
|
175
|
+
command.experiment(command.devices, command.parameters)
|
|
176
|
+
)
|
|
175
177
|
|
|
176
178
|
self.current_status = StatusAndMessage(Status.IDLE)
|
|
177
179
|
|
|
178
180
|
self._last_run_aborted = False
|
|
179
|
-
except
|
|
181
|
+
except WarningError as exception:
|
|
180
182
|
LOGGER.warning("Warning Exception", exc_info=True)
|
|
181
183
|
self.current_status = make_error_status_and_message(exception)
|
|
182
184
|
except Exception as exception:
|
mx_bluesky/jupyter_example.ipynb
CHANGED
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"from bluesky import RunEngine\n",
|
|
19
19
|
"from bluesky.callbacks.best_effort import BestEffortCallback\n",
|
|
20
20
|
"\n",
|
|
21
|
-
"
|
|
21
|
+
"run_engine = RunEngine({})\n",
|
|
22
22
|
"\n",
|
|
23
23
|
"bec = BestEffortCallback()\n",
|
|
24
24
|
"\n",
|
|
25
25
|
"# Send all metadata/data captured to the BestEffortCallback.\n",
|
|
26
|
-
"
|
|
26
|
+
"run_engine.subscribe(bec)"
|
|
27
27
|
]
|
|
28
28
|
},
|
|
29
29
|
{
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"\n",
|
|
47
47
|
"dets = [det] # just one in this case, but it could be more than one\n",
|
|
48
48
|
"\n",
|
|
49
|
-
"
|
|
49
|
+
"run_engine(scan(dets, motor, -1, 1, 10))"
|
|
50
50
|
]
|
|
51
51
|
}
|
|
52
52
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mx-bluesky
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.11
|
|
4
4
|
Summary: Bluesky tools for MX Beamlines at DLS
|
|
5
5
|
Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
|
|
6
6
|
License: Apache License
|
|
@@ -210,6 +210,7 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
210
210
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
211
211
|
Classifier: Programming Language :: Python :: 3.11
|
|
212
212
|
Classifier: Programming Language :: Python :: 3.12
|
|
213
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
213
214
|
Requires-Python: >=3.11
|
|
214
215
|
Description-Content-Type: text/x-rst
|
|
215
216
|
License-File: LICENSE
|
|
@@ -237,11 +238,11 @@ Requires-Dist: deepdiff
|
|
|
237
238
|
Requires-Dist: matplotlib
|
|
238
239
|
Requires-Dist: cachetools
|
|
239
240
|
Requires-Dist: daq-config-server>=v1.0.0-rc.2
|
|
240
|
-
Requires-Dist: blueapi>=1.
|
|
241
|
+
Requires-Dist: blueapi>=1.6.3
|
|
241
242
|
Requires-Dist: ophyd>=1.10.5
|
|
242
|
-
Requires-Dist: ophyd-async>=0.
|
|
243
|
+
Requires-Dist: ophyd-async>=0.13.5
|
|
243
244
|
Requires-Dist: bluesky>=1.14.6
|
|
244
|
-
Requires-Dist: dls-dodal==1.
|
|
245
|
+
Requires-Dist: dls-dodal==1.65.0
|
|
245
246
|
Provides-Extra: dev
|
|
246
247
|
Requires-Dist: black; extra == "dev"
|
|
247
248
|
Requires-Dist: build; extra == "dev"
|
|
@@ -255,7 +256,7 @@ Requires-Dist: pipdeptree; extra == "dev"
|
|
|
255
256
|
Requires-Dist: plantweb; extra == "dev"
|
|
256
257
|
Requires-Dist: pre-commit; extra == "dev"
|
|
257
258
|
Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
|
|
258
|
-
Requires-Dist: pyright; extra == "dev"
|
|
259
|
+
Requires-Dist: pyright==1.1.406; extra == "dev"
|
|
259
260
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
260
261
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
261
262
|
Requires-Dist: pytest-random-order; extra == "dev"
|