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
|
@@ -5,11 +5,11 @@ import bluesky.preprocessors as bpp
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import pydantic
|
|
7
7
|
from blueapi.core import BlueskyContext
|
|
8
|
-
from dodal.devices.attenuator import
|
|
8
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
9
9
|
from dodal.devices.xspress3.xspress3 import Xspress3
|
|
10
|
-
from dodal.devices.zebra_controlled_shutter import ZebraShutter, ZebraShutterState
|
|
10
|
+
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter, ZebraShutterState
|
|
11
11
|
|
|
12
|
-
from mx_bluesky.
|
|
12
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
13
13
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
14
14
|
|
|
15
15
|
|
|
@@ -26,7 +26,7 @@ class Direction(Enum):
|
|
|
26
26
|
class OptimizeAttenuationComposite:
|
|
27
27
|
"""All devices which are directly or indirectly required by this plan"""
|
|
28
28
|
|
|
29
|
-
attenuator:
|
|
29
|
+
attenuator: BinaryFilterAttenuator
|
|
30
30
|
sample_shutter: ZebraShutter
|
|
31
31
|
xspress3mini: Xspress3
|
|
32
32
|
|
|
@@ -197,11 +197,7 @@ def deadtime_optimisation(
|
|
|
197
197
|
cycles to complete.
|
|
198
198
|
|
|
199
199
|
Args:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
xspress3mini: (Xspress3Mini) Ophyd device
|
|
203
|
-
|
|
204
|
-
sample_shutter: (ZebraShutter) Ophyd_async device for the fast shutter
|
|
200
|
+
composite: (OptimizeAttenuationComposite) Devices required to optimise attenuation
|
|
205
201
|
|
|
206
202
|
transmission: (float)
|
|
207
203
|
The initial transmission value to use for the optimising
|
|
@@ -302,11 +298,7 @@ def total_counts_optimisation(
|
|
|
302
298
|
defined by the lower and upper limit. To protect the sample, the transmission has a maximum value of 10%.
|
|
303
299
|
|
|
304
300
|
Args:
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
xspress3mini: (Xspress3Mini) Ophyd device
|
|
308
|
-
|
|
309
|
-
sample_shutter: (ZebraShutter) Ophyd_async device for the fast shutter
|
|
301
|
+
composite: (OptimizeAttenuationComposite) Devices required to optimise attenuation
|
|
310
302
|
|
|
311
303
|
transmission: (float)
|
|
312
304
|
The initial transmission value to use for the optimising
|
|
@@ -8,11 +8,11 @@ from bluesky.utils import MsgGenerator
|
|
|
8
8
|
from dodal.devices.eiger import EigerDetector
|
|
9
9
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
10
10
|
|
|
11
|
-
from mx_bluesky.common.
|
|
12
|
-
|
|
13
|
-
GridScanWithEdgeDetect,
|
|
14
|
-
PinTipCentreThenXrayCentre,
|
|
11
|
+
from mx_bluesky.common.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
12
|
+
ispyb_activation_wrapper,
|
|
15
13
|
)
|
|
14
|
+
from mx_bluesky.common.parameters.constants import OavConstants
|
|
15
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
16
16
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import move_phi_chi_omega
|
|
17
17
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
18
18
|
start_preparing_data_collection_then_do_plan,
|
|
@@ -34,11 +34,11 @@ from mx_bluesky.hyperion.experiment_plans.pin_tip_centring_plan import (
|
|
|
34
34
|
PinTipCentringComposite,
|
|
35
35
|
pin_tip_centre_plan,
|
|
36
36
|
)
|
|
37
|
-
from mx_bluesky.hyperion.external_interaction.callbacks.xray_centre.ispyb_callback import (
|
|
38
|
-
ispyb_activation_wrapper,
|
|
39
|
-
)
|
|
40
|
-
from mx_bluesky.hyperion.log import LOGGER
|
|
41
37
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
38
|
+
from mx_bluesky.hyperion.parameters.gridscan import (
|
|
39
|
+
GridScanWithEdgeDetect,
|
|
40
|
+
PinTipCentreThenXrayCentre,
|
|
41
|
+
)
|
|
42
42
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
43
43
|
|
|
44
44
|
|
|
@@ -121,6 +121,7 @@ def pin_tip_centre_then_xray_centre(
|
|
|
121
121
|
@bpp.subs_decorator(flyscan_event_handler)
|
|
122
122
|
def pin_centre_flyscan_then_fetch_results() -> MsgGenerator:
|
|
123
123
|
yield from start_preparing_data_collection_then_do_plan(
|
|
124
|
+
composite.beamstop,
|
|
124
125
|
eiger,
|
|
125
126
|
composite.detector_motion,
|
|
126
127
|
parameters.detector_params.detector_distance,
|
|
@@ -130,9 +131,9 @@ def pin_tip_centre_then_xray_centre(
|
|
|
130
131
|
|
|
131
132
|
yield from pin_centre_flyscan_then_fetch_results()
|
|
132
133
|
flyscan_results = flyscan_event_handler.xray_centre_results
|
|
133
|
-
assert (
|
|
134
|
-
|
|
135
|
-
)
|
|
134
|
+
assert flyscan_results, (
|
|
135
|
+
"Flyscan result event not received or no crystal found and exception not raised"
|
|
136
|
+
)
|
|
136
137
|
yield from change_aperture_then_move_to_xtal(
|
|
137
138
|
flyscan_results[0], composite.smargon, composite.aperture_scatterguard
|
|
138
139
|
)
|
|
@@ -15,12 +15,12 @@ from dodal.devices.oav.utils import (
|
|
|
15
15
|
)
|
|
16
16
|
from dodal.devices.smargon import Smargon
|
|
17
17
|
|
|
18
|
+
from mx_bluesky.common.utils.exceptions import SampleException
|
|
19
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
18
20
|
from mx_bluesky.hyperion.device_setup_plans.setup_oav import pre_centring_setup_oav
|
|
19
21
|
from mx_bluesky.hyperion.device_setup_plans.smargon import (
|
|
20
22
|
move_smargon_warn_on_out_of_range,
|
|
21
23
|
)
|
|
22
|
-
from mx_bluesky.hyperion.exceptions import WarningException
|
|
23
|
-
from mx_bluesky.hyperion.log import LOGGER
|
|
24
24
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
25
25
|
from mx_bluesky.hyperion.utils.context import device_composite_from_context
|
|
26
26
|
|
|
@@ -68,7 +68,7 @@ def move_pin_into_view(
|
|
|
68
68
|
max_steps (int, optional): The number of steps to search with. Defaults to 2.
|
|
69
69
|
|
|
70
70
|
Raises:
|
|
71
|
-
|
|
71
|
+
SampleException: Error if the pin tip is never found
|
|
72
72
|
|
|
73
73
|
Returns:
|
|
74
74
|
Tuple[int, int]: The location of the pin tip in pixels
|
|
@@ -105,7 +105,7 @@ def move_pin_into_view(
|
|
|
105
105
|
tip_xy_px = yield from trigger_and_return_pin_tip(pin_tip_device)
|
|
106
106
|
|
|
107
107
|
if not pin_tip_valid(tip_xy_px):
|
|
108
|
-
raise
|
|
108
|
+
raise SampleException(
|
|
109
109
|
"Pin tip centring failed - pin too long/short/bent and out of range"
|
|
110
110
|
)
|
|
111
111
|
else:
|
|
@@ -10,8 +10,8 @@ import bluesky.preprocessors as bpp
|
|
|
10
10
|
import pydantic
|
|
11
11
|
from blueapi.core import BlueskyContext
|
|
12
12
|
from bluesky.utils import Msg
|
|
13
|
-
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
14
|
-
from dodal.devices.attenuator import
|
|
13
|
+
from dodal.devices.aperturescatterguard import ApertureScatterguard, ApertureValue
|
|
14
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
15
15
|
from dodal.devices.dcm import DCM
|
|
16
16
|
from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
|
|
17
17
|
from dodal.devices.motors import XYZPositioner
|
|
@@ -24,13 +24,13 @@ from dodal.devices.webcam import Webcam
|
|
|
24
24
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
25
25
|
from dodal.plan_stubs.motor_utils import MoveTooLarge, home_and_reset_wrapper
|
|
26
26
|
|
|
27
|
-
from mx_bluesky.common.
|
|
27
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
28
28
|
from mx_bluesky.hyperion.experiment_plans.set_energy_plan import (
|
|
29
29
|
SetEnergyComposite,
|
|
30
30
|
set_energy_plan,
|
|
31
31
|
)
|
|
32
|
-
from mx_bluesky.hyperion.log import LOGGER
|
|
33
32
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
33
|
+
from mx_bluesky.hyperion.parameters.robot_load import RobotLoadAndEnergyChange
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
@@ -41,7 +41,7 @@ class RobotLoadAndEnergyChangeComposite:
|
|
|
41
41
|
dcm: DCM
|
|
42
42
|
undulator_dcm: UndulatorDCM
|
|
43
43
|
xbpm_feedback: XBPMFeedback
|
|
44
|
-
attenuator:
|
|
44
|
+
attenuator: BinaryFilterAttenuator
|
|
45
45
|
|
|
46
46
|
# RobotLoad fields
|
|
47
47
|
robot: BartRobot
|
|
@@ -94,7 +94,11 @@ def take_robot_snapshots(oav: OAV, webcam: Webcam, directory: Path):
|
|
|
94
94
|
def prepare_for_robot_load(
|
|
95
95
|
aperture_scatterguard: ApertureScatterguard, smargon: Smargon
|
|
96
96
|
):
|
|
97
|
-
yield from bps.
|
|
97
|
+
yield from bps.abs_set(
|
|
98
|
+
aperture_scatterguard,
|
|
99
|
+
ApertureValue.ROBOT_LOAD,
|
|
100
|
+
group="prepare_robot_load",
|
|
101
|
+
)
|
|
98
102
|
|
|
99
103
|
yield from bps.mv(smargon.stub_offsets, StubPosition.RESET_TO_ROBOT_LOAD) # type: ignore # See: https://github.com/bluesky/bluesky/issues/1809
|
|
100
104
|
|
|
@@ -118,17 +122,18 @@ def do_robot_load(
|
|
|
118
122
|
demand_energy_ev: float | None,
|
|
119
123
|
thawing_time: float,
|
|
120
124
|
):
|
|
125
|
+
error_code = yield from bps.rd(composite.robot.error_code)
|
|
126
|
+
# Reset robot if light curtains were tripped
|
|
127
|
+
if error_code == 40:
|
|
128
|
+
yield from bps.trigger(composite.robot.reset, wait=True)
|
|
129
|
+
|
|
121
130
|
yield from bps.abs_set(
|
|
122
131
|
composite.robot,
|
|
123
132
|
sample_location,
|
|
124
133
|
group="robot_load",
|
|
125
134
|
)
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
yield from set_energy_plan(
|
|
129
|
-
demand_energy_ev / 1000,
|
|
130
|
-
cast(SetEnergyComposite, composite),
|
|
131
|
-
)
|
|
136
|
+
yield from set_energy_plan(demand_energy_ev, cast(SetEnergyComposite, composite))
|
|
132
137
|
|
|
133
138
|
yield from bps.wait("robot_load")
|
|
134
139
|
|
|
@@ -214,24 +219,28 @@ def robot_load_and_change_energy_plan(
|
|
|
214
219
|
yield from prepare_for_robot_load(
|
|
215
220
|
composite.aperture_scatterguard, composite.smargon
|
|
216
221
|
)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"
|
|
229
|
-
"
|
|
230
|
-
|
|
231
|
-
|
|
222
|
+
|
|
223
|
+
yield from bpp.set_run_key_wrapper(
|
|
224
|
+
bpp.run_wrapper(
|
|
225
|
+
robot_load_and_snapshots(
|
|
226
|
+
composite,
|
|
227
|
+
sample_location,
|
|
228
|
+
params.snapshot_directory,
|
|
229
|
+
params.thawing_time,
|
|
230
|
+
params.demand_energy_ev,
|
|
231
|
+
),
|
|
232
|
+
md={
|
|
233
|
+
"subplan_name": CONST.PLAN.ROBOT_LOAD,
|
|
234
|
+
"metadata": {
|
|
235
|
+
"visit": params.visit,
|
|
236
|
+
"sample_id": params.sample_id,
|
|
237
|
+
"sample_puck": sample_location.puck,
|
|
238
|
+
"sample_pin": sample_location.pin,
|
|
239
|
+
},
|
|
240
|
+
"activate_callbacks": [
|
|
241
|
+
"RobotLoadISPyBCallback",
|
|
242
|
+
],
|
|
232
243
|
},
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
],
|
|
236
|
-
},
|
|
244
|
+
),
|
|
245
|
+
CONST.PLAN.ROBOT_LOAD_AND_SNAPSHOTS,
|
|
237
246
|
)
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from math import isclose
|
|
3
4
|
from typing import cast
|
|
4
5
|
|
|
5
6
|
import bluesky.preprocessors as bpp
|
|
6
7
|
import pydantic
|
|
7
8
|
from blueapi.core import BlueskyContext
|
|
9
|
+
from bluesky import plan_stubs as bps
|
|
8
10
|
from bluesky.utils import MsgGenerator
|
|
9
11
|
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
10
|
-
from dodal.devices.attenuator import
|
|
12
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
11
13
|
from dodal.devices.backlight import Backlight
|
|
12
14
|
from dodal.devices.dcm import DCM
|
|
13
15
|
from dodal.devices.detector.detector_motion import DetectorMotion
|
|
@@ -15,6 +17,7 @@ from dodal.devices.eiger import EigerDetector
|
|
|
15
17
|
from dodal.devices.fast_grid_scan import PandAFastGridScan, ZebraFastGridScan
|
|
16
18
|
from dodal.devices.flux import Flux
|
|
17
19
|
from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
|
|
20
|
+
from dodal.devices.i03.beamstop import Beamstop
|
|
18
21
|
from dodal.devices.motors import XYZPositioner
|
|
19
22
|
from dodal.devices.oav.oav_detector import OAV
|
|
20
23
|
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
@@ -27,14 +30,13 @@ from dodal.devices.undulator import Undulator
|
|
|
27
30
|
from dodal.devices.undulator_dcm import UndulatorDCM
|
|
28
31
|
from dodal.devices.webcam import Webcam
|
|
29
32
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
30
|
-
from dodal.devices.zebra import Zebra
|
|
31
|
-
from dodal.devices.zebra_controlled_shutter import ZebraShutter
|
|
33
|
+
from dodal.devices.zebra.zebra import Zebra
|
|
34
|
+
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
32
35
|
from dodal.devices.zocalo import ZocaloResults
|
|
33
36
|
from dodal.log import LOGGER
|
|
34
37
|
from ophyd_async.fastcs.panda import HDFPanda
|
|
35
38
|
|
|
36
39
|
from mx_bluesky.common.parameters.constants import OavConstants
|
|
37
|
-
from mx_bluesky.common.parameters.gridscan import RobotLoadThenCentre
|
|
38
40
|
from mx_bluesky.hyperion.device_setup_plans.utils import (
|
|
39
41
|
fill_in_energy_if_not_supplied,
|
|
40
42
|
start_preparing_data_collection_then_do_plan,
|
|
@@ -56,14 +58,19 @@ from mx_bluesky.hyperion.experiment_plans.robot_load_and_change_energy import (
|
|
|
56
58
|
pin_already_loaded,
|
|
57
59
|
robot_load_and_change_energy_plan,
|
|
58
60
|
)
|
|
61
|
+
from mx_bluesky.hyperion.experiment_plans.set_energy_plan import (
|
|
62
|
+
SetEnergyComposite,
|
|
63
|
+
set_energy_plan,
|
|
64
|
+
)
|
|
59
65
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
66
|
+
from mx_bluesky.hyperion.parameters.robot_load import RobotLoadThenCentre
|
|
60
67
|
|
|
61
68
|
|
|
62
69
|
@pydantic.dataclasses.dataclass(config={"arbitrary_types_allowed": True})
|
|
63
70
|
class RobotLoadThenCentreComposite:
|
|
64
71
|
# common fields
|
|
65
72
|
xbpm_feedback: XBPMFeedback
|
|
66
|
-
attenuator:
|
|
73
|
+
attenuator: BinaryFilterAttenuator
|
|
67
74
|
|
|
68
75
|
# GridDetectThenXRayCentreComposite fields
|
|
69
76
|
aperture_scatterguard: ApertureScatterguard
|
|
@@ -95,10 +102,7 @@ class RobotLoadThenCentreComposite:
|
|
|
95
102
|
robot: BartRobot
|
|
96
103
|
webcam: Webcam
|
|
97
104
|
lower_gonio: XYZPositioner
|
|
98
|
-
|
|
99
|
-
@property
|
|
100
|
-
def sample_motors(self):
|
|
101
|
-
return self.smargon
|
|
105
|
+
beamstop: Beamstop
|
|
102
106
|
|
|
103
107
|
|
|
104
108
|
def create_devices(context: BlueskyContext) -> RobotLoadThenCentreComposite:
|
|
@@ -114,7 +118,7 @@ def _flyscan_plan_from_robot_load_params(
|
|
|
114
118
|
):
|
|
115
119
|
yield from pin_centre_then_flyscan_plan(
|
|
116
120
|
cast(GridDetectThenXRayCentreComposite, composite),
|
|
117
|
-
params.pin_centre_then_xray_centre_params
|
|
121
|
+
params.pin_centre_then_xray_centre_params,
|
|
118
122
|
)
|
|
119
123
|
|
|
120
124
|
|
|
@@ -125,7 +129,7 @@ def _robot_load_then_flyscan_plan(
|
|
|
125
129
|
):
|
|
126
130
|
yield from robot_load_and_change_energy_plan(
|
|
127
131
|
cast(RobotLoadAndEnergyChangeComposite, composite),
|
|
128
|
-
params.robot_load_params
|
|
132
|
+
params.robot_load_params,
|
|
129
133
|
)
|
|
130
134
|
|
|
131
135
|
yield from _flyscan_plan_from_robot_load_params(composite, params, oav_config_file)
|
|
@@ -170,20 +174,33 @@ def robot_load_then_xray_centre(
|
|
|
170
174
|
yield from pin_already_loaded(composite.robot, sample_location)
|
|
171
175
|
)
|
|
172
176
|
|
|
173
|
-
|
|
177
|
+
current_chi = yield from bps.rd(composite.smargon.chi)
|
|
178
|
+
LOGGER.info(f"Read back current smargon chi of {current_chi} degrees.")
|
|
179
|
+
doing_chi_change = parameters.chi_start_deg is not None and not isclose(
|
|
180
|
+
current_chi, parameters.chi_start_deg, abs_tol=0.001
|
|
181
|
+
)
|
|
174
182
|
|
|
175
183
|
if doing_sample_load:
|
|
184
|
+
LOGGER.info("Pin not loaded, loading and centring")
|
|
176
185
|
plan = _robot_load_then_flyscan_plan(
|
|
177
186
|
composite,
|
|
178
187
|
parameters,
|
|
179
188
|
)
|
|
180
|
-
LOGGER.info("Pin not loaded, loading and centring")
|
|
181
|
-
elif doing_chi_change:
|
|
182
|
-
plan = _flyscan_plan_from_robot_load_params(composite, parameters)
|
|
183
|
-
LOGGER.info("Pin already loaded but chi changed so centring")
|
|
184
189
|
else:
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
# Robot load normally sets the energy so we should do this explicitly if no load is
|
|
191
|
+
# being done
|
|
192
|
+
demand_energy_ev = parameters.demand_energy_ev
|
|
193
|
+
LOGGER.info(f"Setting the energy to {demand_energy_ev}eV")
|
|
194
|
+
yield from set_energy_plan(
|
|
195
|
+
demand_energy_ev, cast(SetEnergyComposite, composite)
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
if doing_chi_change:
|
|
199
|
+
plan = _flyscan_plan_from_robot_load_params(composite, parameters)
|
|
200
|
+
LOGGER.info("Pin already loaded but chi changed so centring")
|
|
201
|
+
else:
|
|
202
|
+
LOGGER.info("Pin already loaded and chi not changed so doing nothing")
|
|
203
|
+
return
|
|
187
204
|
|
|
188
205
|
detector_params = yield from fill_in_energy_if_not_supplied(
|
|
189
206
|
composite.dcm, parameters.detector_params
|
|
@@ -192,6 +209,7 @@ def robot_load_then_xray_centre(
|
|
|
192
209
|
eiger.set_detector_parameters(detector_params)
|
|
193
210
|
|
|
194
211
|
yield from start_preparing_data_collection_then_do_plan(
|
|
212
|
+
composite.beamstop,
|
|
195
213
|
eiger,
|
|
196
214
|
composite.detector_motion,
|
|
197
215
|
parameters.detector_distance_mm,
|
|
@@ -8,12 +8,13 @@ import pydantic
|
|
|
8
8
|
from blueapi.core import BlueskyContext
|
|
9
9
|
from bluesky.utils import MsgGenerator
|
|
10
10
|
from dodal.devices.aperturescatterguard import ApertureScatterguard
|
|
11
|
-
from dodal.devices.attenuator import
|
|
11
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
12
12
|
from dodal.devices.backlight import Backlight
|
|
13
13
|
from dodal.devices.dcm import DCM
|
|
14
14
|
from dodal.devices.detector.detector_motion import DetectorMotion
|
|
15
15
|
from dodal.devices.eiger import EigerDetector
|
|
16
16
|
from dodal.devices.flux import Flux
|
|
17
|
+
from dodal.devices.i03.beamstop import Beamstop
|
|
17
18
|
from dodal.devices.oav.oav_detector import OAV
|
|
18
19
|
from dodal.devices.oav.oav_parameters import OAVParameters
|
|
19
20
|
from dodal.devices.robot import BartRobot
|
|
@@ -22,13 +23,14 @@ from dodal.devices.smargon import Smargon
|
|
|
22
23
|
from dodal.devices.synchrotron import Synchrotron
|
|
23
24
|
from dodal.devices.undulator import Undulator
|
|
24
25
|
from dodal.devices.xbpm_feedback import XBPMFeedback
|
|
25
|
-
from dodal.devices.zebra import RotationDirection, Zebra
|
|
26
|
-
from dodal.devices.zebra_controlled_shutter import ZebraShutter
|
|
26
|
+
from dodal.devices.zebra.zebra import RotationDirection, Zebra
|
|
27
|
+
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
27
28
|
from dodal.plan_stubs.check_topup import check_topup_and_wait_if_necessary
|
|
28
29
|
|
|
29
30
|
from mx_bluesky.common.device_setup_plans.read_hardware_for_setup import (
|
|
30
31
|
read_hardware_for_zocalo,
|
|
31
32
|
)
|
|
33
|
+
from mx_bluesky.common.utils.log import LOGGER
|
|
32
34
|
from mx_bluesky.hyperion.device_setup_plans.manipulate_sample import (
|
|
33
35
|
cleanup_sample_environment,
|
|
34
36
|
move_phi_chi_omega,
|
|
@@ -55,7 +57,6 @@ from mx_bluesky.hyperion.experiment_plans.oav_snapshot_plan import (
|
|
|
55
57
|
oav_snapshot_plan,
|
|
56
58
|
setup_beamline_for_OAV,
|
|
57
59
|
)
|
|
58
|
-
from mx_bluesky.hyperion.log import LOGGER
|
|
59
60
|
from mx_bluesky.hyperion.parameters.constants import CONST
|
|
60
61
|
from mx_bluesky.hyperion.parameters.rotation import (
|
|
61
62
|
MultiRotationScan,
|
|
@@ -69,8 +70,9 @@ class RotationScanComposite(OavSnapshotComposite):
|
|
|
69
70
|
"""All devices which are directly or indirectly required by this plan"""
|
|
70
71
|
|
|
71
72
|
aperture_scatterguard: ApertureScatterguard
|
|
72
|
-
attenuator:
|
|
73
|
+
attenuator: BinaryFilterAttenuator
|
|
73
74
|
backlight: Backlight
|
|
75
|
+
beamstop: Beamstop
|
|
74
76
|
dcm: DCM
|
|
75
77
|
detector_motion: DetectorMotion
|
|
76
78
|
eiger: EigerDetector
|
|
@@ -126,13 +128,26 @@ def calculate_motion_profile(
|
|
|
126
128
|
See https://github.com/DiamondLightSource/hyperion/wiki/rotation-scan-geometry
|
|
127
129
|
for a simple pictorial explanation."""
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
assert params.rotation_increment_deg > 0
|
|
132
|
+
|
|
133
|
+
direction = params.rotation_direction
|
|
134
|
+
start_scan_deg = params.omega_start_deg
|
|
135
|
+
|
|
136
|
+
if params.features.omega_flip:
|
|
137
|
+
# If omega_flip is True then the motor omega axis is inverted with respect to the
|
|
138
|
+
# hyperion coordinate system.
|
|
139
|
+
start_scan_deg = -start_scan_deg
|
|
140
|
+
direction = (
|
|
141
|
+
direction.POSITIVE
|
|
142
|
+
if direction == direction.NEGATIVE
|
|
143
|
+
else direction.NEGATIVE
|
|
144
|
+
)
|
|
145
|
+
|
|
130
146
|
num_images = params.num_images
|
|
131
147
|
shutter_time_s = params.shutter_opening_time_s
|
|
132
148
|
image_width_deg = params.rotation_increment_deg
|
|
133
149
|
exposure_time_s = params.exposure_time_s
|
|
134
150
|
motor_time_to_speed_s *= ACCELERATION_MARGIN
|
|
135
|
-
start_scan_deg = params.omega_start_deg
|
|
136
151
|
|
|
137
152
|
LOGGER.info("Calculating rotation scan motion profile:")
|
|
138
153
|
LOGGER.info(
|
|
@@ -153,9 +168,9 @@ def calculate_motion_profile(
|
|
|
153
168
|
f"{acceleration_offset_deg=} = {motor_time_to_speed_s=} * {speed_for_rotation_deg_s=}"
|
|
154
169
|
)
|
|
155
170
|
|
|
156
|
-
start_motion_deg = start_scan_deg - (acceleration_offset_deg * direction)
|
|
171
|
+
start_motion_deg = start_scan_deg - (acceleration_offset_deg * direction.multiplier)
|
|
157
172
|
LOGGER.info(
|
|
158
|
-
f"{start_motion_deg=} = {start_scan_deg=} - ({acceleration_offset_deg=} * {direction=})"
|
|
173
|
+
f"{start_motion_deg=} = {start_scan_deg=} - ({acceleration_offset_deg=} * {direction.multiplier=})"
|
|
159
174
|
)
|
|
160
175
|
|
|
161
176
|
shutter_opening_deg = speed_for_rotation_deg_s * shutter_time_s
|
|
@@ -173,7 +188,7 @@ def calculate_motion_profile(
|
|
|
173
188
|
|
|
174
189
|
distance_to_move_deg = (
|
|
175
190
|
scan_width_deg + shutter_opening_deg + acceleration_offset_deg * 2
|
|
176
|
-
) * direction
|
|
191
|
+
) * direction.multiplier
|
|
177
192
|
LOGGER.info(
|
|
178
193
|
f"{distance_to_move_deg=} = ({scan_width_deg=} + {shutter_opening_deg=} + {acceleration_offset_deg=} * 2) * {direction=})"
|
|
179
194
|
)
|
|
@@ -183,7 +198,7 @@ def calculate_motion_profile(
|
|
|
183
198
|
start_motion_deg=start_motion_deg,
|
|
184
199
|
scan_width_deg=scan_width_deg,
|
|
185
200
|
shutter_time_s=shutter_time_s,
|
|
186
|
-
direction=
|
|
201
|
+
direction=direction,
|
|
187
202
|
speed_for_rotation_deg_s=speed_for_rotation_deg_s,
|
|
188
203
|
acceleration_offset_deg=acceleration_offset_deg,
|
|
189
204
|
shutter_opening_deg=shutter_opening_deg,
|
|
@@ -331,13 +346,6 @@ def _move_and_rotation(
|
|
|
331
346
|
yield from setup_beamline_for_OAV(
|
|
332
347
|
composite.smargon, composite.backlight, composite.aperture_scatterguard
|
|
333
348
|
)
|
|
334
|
-
yield from bps.wait(group=CONST.WAIT.READY_FOR_OAV)
|
|
335
|
-
if params.selected_aperture:
|
|
336
|
-
yield from bps.abs_set(
|
|
337
|
-
composite.aperture_scatterguard.aperture_outside_beam,
|
|
338
|
-
params.selected_aperture,
|
|
339
|
-
group=CONST.WAIT.ROTATION_READY_FOR_DC,
|
|
340
|
-
)
|
|
341
349
|
yield from oav_snapshot_plan(composite, params, oav_params)
|
|
342
350
|
yield from rotation_scan_plan(
|
|
343
351
|
composite,
|
|
@@ -351,6 +359,8 @@ def rotation_scan(
|
|
|
351
359
|
parameters: RotationScan,
|
|
352
360
|
oav_params: OAVParameters | None = None,
|
|
353
361
|
) -> MsgGenerator:
|
|
362
|
+
parameters.features.update_self_from_server()
|
|
363
|
+
|
|
354
364
|
if not oav_params:
|
|
355
365
|
oav_params = OAVParameters(context="xrayCentring")
|
|
356
366
|
|
|
@@ -360,7 +370,7 @@ def rotation_scan(
|
|
|
360
370
|
"subplan_name": CONST.PLAN.ROTATION_OUTER,
|
|
361
371
|
CONST.TRIGGER.ZOCALO: CONST.PLAN.ROTATION_MAIN,
|
|
362
372
|
"zocalo_environment": CONST.ZOCALO_ENV,
|
|
363
|
-
"
|
|
373
|
+
"mx_bluesky_parameters": parameters.model_dump_json(),
|
|
364
374
|
"activate_callbacks": [
|
|
365
375
|
"RotationISPyBCallback",
|
|
366
376
|
"RotationNexusFileCallback",
|
|
@@ -384,6 +394,7 @@ def rotation_scan(
|
|
|
384
394
|
|
|
385
395
|
LOGGER.info("setting up and staging eiger...")
|
|
386
396
|
yield from start_preparing_data_collection_then_do_plan(
|
|
397
|
+
composite.beamstop,
|
|
387
398
|
eiger,
|
|
388
399
|
composite.detector_motion,
|
|
389
400
|
params.detector_distance_mm,
|
|
@@ -400,6 +411,7 @@ def multi_rotation_scan(
|
|
|
400
411
|
parameters: MultiRotationScan,
|
|
401
412
|
oav_params: OAVParameters | None = None,
|
|
402
413
|
) -> MsgGenerator:
|
|
414
|
+
parameters.features.update_self_from_server()
|
|
403
415
|
if not oav_params:
|
|
404
416
|
oav_params = OAVParameters(context="xrayCentring")
|
|
405
417
|
eiger: EigerDetector = composite.eiger
|
|
@@ -432,8 +444,7 @@ def multi_rotation_scan(
|
|
|
432
444
|
md={
|
|
433
445
|
"subplan_name": CONST.PLAN.ROTATION_OUTER,
|
|
434
446
|
CONST.TRIGGER.ZOCALO: CONST.PLAN.ROTATION_MAIN,
|
|
435
|
-
"
|
|
436
|
-
"hyperion_parameters": single_scan.model_dump_json(),
|
|
447
|
+
"mx_bluesky_parameters": single_scan.model_dump_json(),
|
|
437
448
|
}
|
|
438
449
|
)
|
|
439
450
|
def rotation_scan_core(
|
|
@@ -445,6 +456,7 @@ def multi_rotation_scan(
|
|
|
445
456
|
|
|
446
457
|
LOGGER.info("setting up and staging eiger...")
|
|
447
458
|
yield from start_preparing_data_collection_then_do_plan(
|
|
459
|
+
composite.beamstop,
|
|
448
460
|
eiger,
|
|
449
461
|
composite.detector_motion,
|
|
450
462
|
parameters.detector_distance_mm,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import pydantic
|
|
9
9
|
from bluesky import plan_stubs as bps
|
|
10
|
-
from dodal.devices.attenuator import
|
|
10
|
+
from dodal.devices.attenuator.attenuator import BinaryFilterAttenuator
|
|
11
11
|
from dodal.devices.dcm import DCM
|
|
12
12
|
from dodal.devices.focusing_mirror import FocusingMirrorWithStripes, MirrorVoltages
|
|
13
13
|
from dodal.devices.undulator_dcm import UndulatorDCM
|
|
@@ -30,7 +30,7 @@ class SetEnergyComposite:
|
|
|
30
30
|
dcm: DCM
|
|
31
31
|
undulator_dcm: UndulatorDCM
|
|
32
32
|
xbpm_feedback: XBPMFeedback
|
|
33
|
-
attenuator:
|
|
33
|
+
attenuator: BinaryFilterAttenuator
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def _set_energy_plan(
|
|
@@ -48,12 +48,13 @@ def _set_energy_plan(
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
def set_energy_plan(
|
|
51
|
-
|
|
51
|
+
energy_ev: float | None,
|
|
52
52
|
composite: SetEnergyComposite,
|
|
53
53
|
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
if energy_ev:
|
|
55
|
+
yield from transmission_and_xbpm_feedback_for_collection_wrapper(
|
|
56
|
+
_set_energy_plan(energy_ev / 1000, composite),
|
|
57
|
+
composite.xbpm_feedback,
|
|
58
|
+
composite.attenuator,
|
|
59
|
+
DESIRED_TRANSMISSION_FRACTION,
|
|
60
|
+
)
|