dls-dodal 1.34.1__py3-none-any.whl → 1.36.0__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.
- {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/METADATA +4 -2
- dls_dodal-1.36.0.dist-info/RECORD +152 -0
- {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/WHEEL +1 -1
- dodal/_version.py +2 -2
- dodal/beamlines/i22.py +24 -11
- dodal/beamlines/i24.py +4 -4
- dodal/beamlines/p38.py +23 -11
- dodal/common/beamlines/beamline_utils.py +1 -2
- dodal/common/crystal_metadata.py +61 -0
- dodal/common/signal_utils.py +10 -14
- dodal/devices/CTAB.py +1 -1
- dodal/devices/aperture.py +1 -1
- dodal/devices/aperturescatterguard.py +20 -8
- dodal/devices/apple2_undulator.py +30 -29
- dodal/devices/areadetector/plugins/CAM.py +3 -5
- dodal/devices/areadetector/plugins/MJPG.py +1 -1
- dodal/devices/attenuator.py +1 -1
- dodal/devices/backlight.py +4 -5
- dodal/devices/cryostream.py +3 -5
- dodal/devices/dcm.py +26 -2
- dodal/devices/detector/detector_motion.py +3 -5
- dodal/devices/diamond_filter.py +3 -4
- dodal/devices/eiger.py +88 -49
- dodal/devices/fast_grid_scan.py +1 -1
- dodal/devices/fluorescence_detector_motion.py +5 -7
- dodal/devices/focusing_mirror.py +12 -11
- dodal/devices/hutch_shutter.py +4 -5
- dodal/devices/i10/i10_apple2.py +20 -19
- dodal/devices/i10/i10_setting_data.py +2 -2
- dodal/devices/i22/dcm.py +43 -75
- dodal/devices/i22/fswitch.py +5 -5
- dodal/devices/i24/aperture.py +3 -5
- dodal/devices/i24/beamstop.py +3 -5
- dodal/devices/i24/dcm.py +1 -1
- dodal/devices/i24/dual_backlight.py +4 -6
- dodal/devices/i24/pmac.py +35 -46
- dodal/devices/i24/vgonio.py +16 -0
- dodal/devices/ipin.py +5 -3
- dodal/devices/linkam3.py +7 -7
- dodal/devices/oav/oav_detector.py +3 -3
- dodal/devices/oav/oav_to_redis_forwarder.py +8 -7
- dodal/devices/oav/pin_image_recognition/__init__.py +9 -7
- dodal/devices/oav/snapshots/grid_overlay.py +16 -16
- dodal/devices/oav/snapshots/snapshot_with_beam_centre.py +5 -5
- dodal/devices/oav/snapshots/snapshot_with_grid.py +6 -6
- dodal/devices/oav/utils.py +2 -2
- dodal/devices/p99/sample_stage.py +3 -5
- dodal/devices/pgm.py +5 -6
- dodal/devices/qbpm.py +1 -1
- dodal/devices/robot.py +3 -3
- dodal/devices/smargon.py +1 -1
- dodal/devices/synchrotron.py +9 -4
- dodal/devices/tetramm.py +7 -7
- dodal/devices/thawer.py +13 -7
- dodal/devices/undulator.py +5 -5
- dodal/devices/util/epics_util.py +1 -1
- dodal/devices/watsonmarlow323_pump.py +45 -0
- dodal/devices/webcam.py +9 -2
- dodal/devices/xbpm_feedback.py +3 -5
- dodal/devices/xspress3/xspress3.py +8 -9
- dodal/devices/xspress3/xspress3_channel.py +3 -5
- dodal/devices/zebra.py +7 -6
- dodal/devices/zebra_controlled_shutter.py +5 -6
- dodal/devices/zocalo/__init__.py +2 -2
- dodal/devices/zocalo/zocalo_constants.py +3 -0
- dodal/devices/zocalo/zocalo_interaction.py +2 -1
- dodal/devices/zocalo/zocalo_results.py +92 -79
- dodal/plan_stubs/__init__.py +0 -0
- dodal/{plans/data_session_metadata.py → plan_stubs/data_session.py} +2 -2
- dodal/{plans/motor_util_plans.py → plan_stubs/motor_utils.py} +2 -2
- dodal/plan_stubs/wrapped.py +150 -0
- dodal/plans/__init__.py +4 -0
- dodal/plans/scanspec.py +66 -0
- dodal/plans/wrapped.py +57 -0
- dodal/utils.py +4 -0
- dls_dodal-1.34.1.dist-info/RECORD +0 -144
- dodal/devices/i24/i24_vgonio.py +0 -17
- {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/LICENSE +0 -0
- {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/top_level.txt +0 -0
- /dodal/{plans → plan_stubs}/check_topup.py +0 -0
dodal/devices/ipin.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
from ophyd_async.core import
|
|
2
|
-
from ophyd_async.epics.
|
|
1
|
+
from ophyd_async.core import StandardReadable, StandardReadableFormat
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class IPin(StandardReadable):
|
|
6
6
|
"""Simple device to get the ipin reading"""
|
|
7
7
|
|
|
8
8
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
9
|
-
with self.add_children_as_readables(
|
|
9
|
+
with self.add_children_as_readables(
|
|
10
|
+
format=StandardReadableFormat.HINTED_SIGNAL
|
|
11
|
+
):
|
|
10
12
|
self.pin_readback = epics_signal_r(float, prefix + "I")
|
|
11
13
|
super().__init__(name)
|
dodal/devices/linkam3.py
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import time
|
|
3
|
-
from enum import Enum
|
|
4
3
|
|
|
5
4
|
from bluesky.protocols import Location
|
|
6
5
|
from ophyd_async.core import (
|
|
7
|
-
ConfigSignal,
|
|
8
|
-
HintedSignal,
|
|
9
6
|
StandardReadable,
|
|
7
|
+
StandardReadableFormat,
|
|
8
|
+
StrictEnum,
|
|
10
9
|
WatchableAsyncStatus,
|
|
11
10
|
WatcherUpdate,
|
|
12
11
|
observe_value,
|
|
13
12
|
)
|
|
14
|
-
from ophyd_async.epics.
|
|
13
|
+
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
class PumpControl(
|
|
16
|
+
class PumpControl(StrictEnum):
|
|
18
17
|
Manual = "Manual"
|
|
19
18
|
Auto = "Auto"
|
|
20
19
|
|
|
@@ -62,9 +61,10 @@ class Linkam3(StandardReadable):
|
|
|
62
61
|
# status is a bitfield stored in a double?
|
|
63
62
|
self.status = epics_signal_r(float, prefix + "STATUS:")
|
|
64
63
|
|
|
65
|
-
self.add_readables((self.temp,),
|
|
64
|
+
self.add_readables((self.temp,), format=StandardReadableFormat.HINTED_SIGNAL)
|
|
66
65
|
self.add_readables(
|
|
67
|
-
(self.ramp_rate, self.speed, self.set_point),
|
|
66
|
+
(self.ramp_rate, self.speed, self.set_point),
|
|
67
|
+
format=StandardReadableFormat.CONFIG_SIGNAL,
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
super().__init__(name=name)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from enum import IntEnum
|
|
2
2
|
|
|
3
|
-
from ophyd_async.core import DEFAULT_TIMEOUT, AsyncStatus, StandardReadable
|
|
4
|
-
from ophyd_async.epics.
|
|
3
|
+
from ophyd_async.core import DEFAULT_TIMEOUT, AsyncStatus, LazyMock, StandardReadable
|
|
4
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
5
5
|
|
|
6
6
|
from dodal.common.signal_utils import create_hardware_backed_soft_signal
|
|
7
7
|
from dodal.devices.areadetector.plugins.CAM import Cam
|
|
@@ -118,7 +118,7 @@ class OAV(StandardReadable):
|
|
|
118
118
|
|
|
119
119
|
async def connect(
|
|
120
120
|
self,
|
|
121
|
-
mock: bool = False,
|
|
121
|
+
mock: bool | LazyMock = False,
|
|
122
122
|
timeout: float = DEFAULT_TIMEOUT,
|
|
123
123
|
force_reconnect: bool = False,
|
|
124
124
|
):
|
|
@@ -14,7 +14,7 @@ from ophyd_async.core import (
|
|
|
14
14
|
soft_signal_r_and_setter,
|
|
15
15
|
soft_signal_rw,
|
|
16
16
|
)
|
|
17
|
-
from ophyd_async.epics.
|
|
17
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
18
18
|
from redis.asyncio import StrictRedis
|
|
19
19
|
|
|
20
20
|
from dodal.log import LOGGER
|
|
@@ -42,6 +42,7 @@ class OAVSource(StandardReadable):
|
|
|
42
42
|
):
|
|
43
43
|
self.url = epics_signal_r(str, f"{prefix}MJPG_URL_RBV")
|
|
44
44
|
self.oav_name = oav_name
|
|
45
|
+
super().__init__()
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
class OAVToRedisForwarder(StandardReadable, Flyable, Stoppable):
|
|
@@ -78,13 +79,13 @@ class OAVToRedisForwarder(StandardReadable, Flyable, Stoppable):
|
|
|
78
79
|
"""
|
|
79
80
|
self.counter = epics_signal_r(int, f"{prefix}CAM:ArrayCounter_RBV")
|
|
80
81
|
|
|
81
|
-
self.
|
|
82
|
+
self.sources = DeviceVector(
|
|
82
83
|
{
|
|
83
84
|
Source.ROI.value: OAVSource(f"{prefix}MJPG:", "roi"),
|
|
84
85
|
Source.FULL_SCREEN.value: OAVSource(f"{prefix}XTAL:", "fullscreen"),
|
|
85
86
|
}
|
|
86
87
|
)
|
|
87
|
-
self.selected_source = soft_signal_rw(
|
|
88
|
+
self.selected_source = soft_signal_rw(int)
|
|
88
89
|
|
|
89
90
|
self.forwarding_task = None
|
|
90
91
|
self.redis_client = StrictRedis(
|
|
@@ -118,11 +119,11 @@ class OAVToRedisForwarder(StandardReadable, Flyable, Stoppable):
|
|
|
118
119
|
async def _open_connection_and_do_function(
|
|
119
120
|
self, function_to_do: Callable[[ClientResponse, OAVSource], Awaitable]
|
|
120
121
|
):
|
|
121
|
-
|
|
122
|
+
source_idx = await self.selected_source.get_value()
|
|
122
123
|
LOGGER.info(
|
|
123
|
-
f"Forwarding data from sample {await self.sample_id.get_value()} and OAV {
|
|
124
|
+
f"Forwarding data from sample {await self.sample_id.get_value()} and OAV {source_idx}"
|
|
124
125
|
)
|
|
125
|
-
source = self.
|
|
126
|
+
source = self.sources[source_idx]
|
|
126
127
|
stream_url = await source.url.get_value()
|
|
127
128
|
async with ClientSession() as session:
|
|
128
129
|
async with session.get(stream_url) as response:
|
|
@@ -164,7 +165,7 @@ class OAVToRedisForwarder(StandardReadable, Flyable, Stoppable):
|
|
|
164
165
|
async def stop(self, success=True):
|
|
165
166
|
if self.forwarding_task:
|
|
166
167
|
LOGGER.info(
|
|
167
|
-
f"Stopping forwarding for {await self.selected_source.get_value()}"
|
|
168
|
+
f"Stopping forwarding for source id {await self.selected_source.get_value()}"
|
|
168
169
|
)
|
|
169
170
|
self._stop_flag.set()
|
|
170
171
|
await self.forwarding_task
|
|
@@ -4,14 +4,15 @@ import time
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
from numpy.typing import NDArray
|
|
6
6
|
from ophyd_async.core import (
|
|
7
|
+
Array1D,
|
|
7
8
|
AsyncStatus,
|
|
8
|
-
HintedSignal,
|
|
9
9
|
StandardReadable,
|
|
10
|
+
StandardReadableFormat,
|
|
10
11
|
observe_value,
|
|
11
12
|
soft_signal_r_and_setter,
|
|
12
13
|
soft_signal_rw,
|
|
13
14
|
)
|
|
14
|
-
from ophyd_async.epics.
|
|
15
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
15
16
|
|
|
16
17
|
from dodal.devices.oav.pin_image_recognition.utils import (
|
|
17
18
|
ARRAY_PROCESSING_FUNCTIONS_MAP,
|
|
@@ -22,7 +23,8 @@ from dodal.devices.oav.pin_image_recognition.utils import (
|
|
|
22
23
|
)
|
|
23
24
|
from dodal.log import LOGGER
|
|
24
25
|
|
|
25
|
-
Tip
|
|
26
|
+
# Tip position in x, y pixel coordinates
|
|
27
|
+
Tip = Array1D[np.int32]
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
class InvalidPinException(Exception):
|
|
@@ -45,7 +47,7 @@ class PinTipDetection(StandardReadable):
|
|
|
45
47
|
no tip is found after this time it will not error but instead return {INVALID_POSITION}.
|
|
46
48
|
"""
|
|
47
49
|
|
|
48
|
-
INVALID_POSITION = (
|
|
50
|
+
INVALID_POSITION = np.array([np.iinfo(np.int32).min, np.iinfo(np.int32).min])
|
|
49
51
|
|
|
50
52
|
def __init__(self, prefix: str, name: str = ""):
|
|
51
53
|
self._prefix: str = prefix
|
|
@@ -84,16 +86,16 @@ class PinTipDetection(StandardReadable):
|
|
|
84
86
|
self.triggered_top_edge,
|
|
85
87
|
self.triggered_bottom_edge,
|
|
86
88
|
],
|
|
87
|
-
|
|
89
|
+
format=StandardReadableFormat.HINTED_SIGNAL,
|
|
88
90
|
)
|
|
89
91
|
|
|
90
92
|
super().__init__(name=name)
|
|
91
93
|
|
|
92
94
|
def _set_triggered_values(self, results: SampleLocation):
|
|
93
|
-
|
|
94
|
-
if tip == self.INVALID_POSITION:
|
|
95
|
+
if results.tip_x is None or results.tip_y is None:
|
|
95
96
|
raise InvalidPinException
|
|
96
97
|
else:
|
|
98
|
+
tip = np.array([results.tip_x, results.tip_y])
|
|
97
99
|
self._tip_setter(tip)
|
|
98
100
|
self._top_edge_setter(results.edge_top)
|
|
99
101
|
self._bottom_edge_setter(results.edge_bottom)
|
|
@@ -14,7 +14,7 @@ def _add_parallel_lines_to_image(
|
|
|
14
14
|
start_x: int,
|
|
15
15
|
start_y: int,
|
|
16
16
|
line_length: int,
|
|
17
|
-
spacing:
|
|
17
|
+
spacing: float,
|
|
18
18
|
num_lines: int,
|
|
19
19
|
orientation=Orientation.horizontal,
|
|
20
20
|
):
|
|
@@ -32,7 +32,7 @@ def _add_parallel_lines_to_image(
|
|
|
32
32
|
start_x (int): The x coordinate (in pixels) of the start of the initial line.
|
|
33
33
|
start_y (int): The y coordinate (in pixels) of the start of the initial line.
|
|
34
34
|
line_length (int): The length of each of the parallel lines in pixels.
|
|
35
|
-
spacing (
|
|
35
|
+
spacing (float): The spacing, in pixels, between each parallel line. Strictly, \
|
|
36
36
|
there are spacing-1 pixels between each line
|
|
37
37
|
num_lines (int): The total number of parallel lines to draw.
|
|
38
38
|
orientation (Orientation): The orientation (horizontal or vertical) of the \
|
|
@@ -40,13 +40,13 @@ def _add_parallel_lines_to_image(
|
|
|
40
40
|
lines = [
|
|
41
41
|
(
|
|
42
42
|
(
|
|
43
|
-
(start_x, start_y + i * spacing),
|
|
44
|
-
(start_x + line_length, start_y + i * spacing),
|
|
43
|
+
(start_x, start_y + int(i * spacing)),
|
|
44
|
+
(start_x + line_length, start_y + int(i * spacing)),
|
|
45
45
|
)
|
|
46
46
|
if orientation == Orientation.horizontal
|
|
47
47
|
else (
|
|
48
|
-
(start_x + i * spacing, start_y),
|
|
49
|
-
(start_x + i * spacing, start_y + line_length),
|
|
48
|
+
(start_x + int(i * spacing), start_y),
|
|
49
|
+
(start_x + int(i * spacing), start_y + line_length),
|
|
50
50
|
)
|
|
51
51
|
)
|
|
52
52
|
for i in range(num_lines)
|
|
@@ -70,7 +70,7 @@ def add_grid_border_overlay_to_image(
|
|
|
70
70
|
image: Image.Image,
|
|
71
71
|
top_left_x: int,
|
|
72
72
|
top_left_y: int,
|
|
73
|
-
box_width:
|
|
73
|
+
box_width: float,
|
|
74
74
|
num_boxes_x: int,
|
|
75
75
|
num_boxes_y: int,
|
|
76
76
|
):
|
|
@@ -78,16 +78,16 @@ def add_grid_border_overlay_to_image(
|
|
|
78
78
|
image,
|
|
79
79
|
start_x=top_left_x,
|
|
80
80
|
start_y=top_left_y,
|
|
81
|
-
line_length=num_boxes_y * box_width,
|
|
82
|
-
spacing=num_boxes_x * box_width,
|
|
81
|
+
line_length=int(num_boxes_y * box_width),
|
|
82
|
+
spacing=int(num_boxes_x * box_width),
|
|
83
83
|
num_lines=2,
|
|
84
84
|
)
|
|
85
85
|
_add_horizontal_parallel_lines_to_image(
|
|
86
86
|
image,
|
|
87
87
|
start_x=top_left_x,
|
|
88
88
|
start_y=top_left_y,
|
|
89
|
-
line_length=num_boxes_x * box_width,
|
|
90
|
-
spacing=num_boxes_y * box_width,
|
|
89
|
+
line_length=int(num_boxes_x * box_width),
|
|
90
|
+
spacing=int(num_boxes_y * box_width),
|
|
91
91
|
num_lines=2,
|
|
92
92
|
)
|
|
93
93
|
|
|
@@ -96,23 +96,23 @@ def add_grid_overlay_to_image(
|
|
|
96
96
|
image: Image.Image,
|
|
97
97
|
top_left_x: int,
|
|
98
98
|
top_left_y: int,
|
|
99
|
-
box_width:
|
|
99
|
+
box_width: float,
|
|
100
100
|
num_boxes_x: int,
|
|
101
101
|
num_boxes_y: int,
|
|
102
102
|
):
|
|
103
103
|
_add_vertical_parallel_lines_to_image(
|
|
104
104
|
image,
|
|
105
|
-
start_x=top_left_x + box_width,
|
|
105
|
+
start_x=int(top_left_x + box_width),
|
|
106
106
|
start_y=top_left_y,
|
|
107
|
-
line_length=num_boxes_y * box_width,
|
|
107
|
+
line_length=int(num_boxes_y * box_width),
|
|
108
108
|
spacing=box_width,
|
|
109
109
|
num_lines=num_boxes_x - 1,
|
|
110
110
|
)
|
|
111
111
|
_add_horizontal_parallel_lines_to_image(
|
|
112
112
|
image,
|
|
113
113
|
start_x=top_left_x,
|
|
114
|
-
start_y=top_left_y + box_width,
|
|
115
|
-
line_length=num_boxes_x * box_width,
|
|
114
|
+
start_y=int(top_left_y + box_width),
|
|
115
|
+
line_length=int(num_boxes_x * box_width),
|
|
116
116
|
spacing=box_width,
|
|
117
117
|
num_lines=num_boxes_y - 1,
|
|
118
118
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from ophyd_async.core import SignalR
|
|
1
|
+
from ophyd_async.core import Reference, SignalR
|
|
2
2
|
from PIL import Image, ImageDraw
|
|
3
3
|
|
|
4
4
|
from dodal.devices.areadetector.plugins.MJPG import MJPG
|
|
@@ -52,13 +52,13 @@ class SnapshotWithBeamCentre(MJPG):
|
|
|
52
52
|
name: str = "",
|
|
53
53
|
) -> None:
|
|
54
54
|
with self.add_children_as_readables():
|
|
55
|
-
self.
|
|
56
|
-
self.
|
|
55
|
+
self._beam_centre_i_ref = Reference(beam_x_signal)
|
|
56
|
+
self._beam_centre_j_ref = Reference(beam_y_signal)
|
|
57
57
|
super().__init__(prefix, name)
|
|
58
58
|
|
|
59
59
|
async def post_processing(self, image: Image.Image):
|
|
60
|
-
beam_x = await self.
|
|
61
|
-
beam_y = await self.
|
|
60
|
+
beam_x = await self._beam_centre_i_ref().get_value()
|
|
61
|
+
beam_y = await self._beam_centre_j_ref().get_value()
|
|
62
62
|
draw_crosshair(image, beam_x, beam_y)
|
|
63
63
|
|
|
64
64
|
await self._save_image(image)
|
|
@@ -14,9 +14,9 @@ from dodal.log import LOGGER
|
|
|
14
14
|
class SnapshotWithGrid(MJPG):
|
|
15
15
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
16
16
|
with self.add_children_as_readables():
|
|
17
|
-
self.top_left_x = soft_signal_rw(
|
|
18
|
-
self.top_left_y = soft_signal_rw(
|
|
19
|
-
self.box_width = soft_signal_rw(
|
|
17
|
+
self.top_left_x = soft_signal_rw(float)
|
|
18
|
+
self.top_left_y = soft_signal_rw(float)
|
|
19
|
+
self.box_width = soft_signal_rw(float)
|
|
20
20
|
self.num_boxes_x = soft_signal_rw(int)
|
|
21
21
|
self.num_boxes_y = soft_signal_rw(int)
|
|
22
22
|
|
|
@@ -31,7 +31,7 @@ class SnapshotWithGrid(MJPG):
|
|
|
31
31
|
|
|
32
32
|
top_left_x = await self.top_left_x.get_value()
|
|
33
33
|
top_left_y = await self.top_left_y.get_value()
|
|
34
|
-
|
|
34
|
+
box_width = await self.box_width.get_value()
|
|
35
35
|
num_boxes_x = await self.num_boxes_x.get_value()
|
|
36
36
|
num_boxes_y = await self.num_boxes_y.get_value()
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ class SnapshotWithGrid(MJPG):
|
|
|
39
39
|
assert isinstance(directory_str := await self.directory.get_value(), str)
|
|
40
40
|
|
|
41
41
|
add_grid_border_overlay_to_image(
|
|
42
|
-
image, top_left_x, top_left_y,
|
|
42
|
+
image, int(top_left_x), int(top_left_y), box_width, num_boxes_x, num_boxes_y
|
|
43
43
|
)
|
|
44
44
|
|
|
45
45
|
path = path_join(directory_str, f"{filename_str}_outer_overlay.{IMG_FORMAT}")
|
|
@@ -48,7 +48,7 @@ class SnapshotWithGrid(MJPG):
|
|
|
48
48
|
await asyncio_save_image(image, path)
|
|
49
49
|
|
|
50
50
|
add_grid_overlay_to_image(
|
|
51
|
-
image, top_left_x, top_left_y,
|
|
51
|
+
image, int(top_left_x), int(top_left_y), box_width, num_boxes_x, num_boxes_y
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
path = path_join(directory_str, f"{filename_str}_grid_overlay.{IMG_FORMAT}")
|
dodal/devices/oav/utils.py
CHANGED
|
@@ -103,8 +103,8 @@ def wait_for_tip_to_be_found(
|
|
|
103
103
|
) -> Generator[Msg, None, Pixel]:
|
|
104
104
|
yield from bps.trigger(ophyd_pin_tip_detection, wait=True)
|
|
105
105
|
found_tip = yield from bps.rd(ophyd_pin_tip_detection.triggered_tip)
|
|
106
|
-
if found_tip == ophyd_pin_tip_detection.INVALID_POSITION:
|
|
106
|
+
if all(found_tip == ophyd_pin_tip_detection.INVALID_POSITION):
|
|
107
107
|
timeout = yield from bps.rd(ophyd_pin_tip_detection.validity_timeout)
|
|
108
108
|
raise PinNotFoundException(f"No pin found after {timeout} seconds")
|
|
109
109
|
|
|
110
|
-
return found_tip
|
|
110
|
+
return Pixel((int(found_tip[0]), int(found_tip[1])))
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from ophyd_async.core import Device
|
|
4
|
-
from ophyd_async.epics.signal import epics_signal_rw
|
|
1
|
+
from ophyd_async.core import Device, SubsetEnum
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
5
3
|
|
|
6
4
|
|
|
7
5
|
class SampleAngleStage(Device):
|
|
@@ -18,7 +16,7 @@ class SampleAngleStage(Device):
|
|
|
18
16
|
super().__init__(name=name)
|
|
19
17
|
|
|
20
18
|
|
|
21
|
-
class p99StageSelections(
|
|
19
|
+
class p99StageSelections(SubsetEnum):
|
|
22
20
|
Empty = "Empty"
|
|
23
21
|
Mn5um = "Mn 5um"
|
|
24
22
|
Fe = "Fe (empty)"
|
dodal/devices/pgm.py
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
|
|
3
1
|
from ophyd_async.core import (
|
|
4
|
-
ConfigSignal,
|
|
5
2
|
StandardReadable,
|
|
3
|
+
StandardReadableFormat,
|
|
4
|
+
StrictEnum,
|
|
6
5
|
)
|
|
6
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
7
7
|
from ophyd_async.epics.motor import Motor
|
|
8
|
-
from ophyd_async.epics.signal import epics_signal_rw
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class PGM(StandardReadable):
|
|
@@ -16,7 +15,7 @@ class PGM(StandardReadable):
|
|
|
16
15
|
def __init__(
|
|
17
16
|
self,
|
|
18
17
|
prefix: str,
|
|
19
|
-
grating: type[
|
|
18
|
+
grating: type[StrictEnum],
|
|
20
19
|
gratingPv: str,
|
|
21
20
|
name: str = "",
|
|
22
21
|
) -> None:
|
|
@@ -34,7 +33,7 @@ class PGM(StandardReadable):
|
|
|
34
33
|
"""
|
|
35
34
|
with self.add_children_as_readables():
|
|
36
35
|
self.energy = Motor(prefix + "ENERGY")
|
|
37
|
-
with self.add_children_as_readables(
|
|
36
|
+
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
|
|
38
37
|
self.grating = epics_signal_rw(grating, prefix + gratingPv)
|
|
39
38
|
self.cff = epics_signal_rw(float, prefix + "CFF")
|
|
40
39
|
|
dodal/devices/qbpm.py
CHANGED
dodal/devices/robot.py
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from asyncio import FIRST_COMPLETED, CancelledError, Task, wait_for
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from enum import Enum
|
|
5
4
|
|
|
6
5
|
from bluesky.protocols import Movable
|
|
7
6
|
from ophyd_async.core import (
|
|
8
7
|
AsyncStatus,
|
|
9
8
|
StandardReadable,
|
|
9
|
+
StrictEnum,
|
|
10
10
|
set_and_wait_for_value,
|
|
11
11
|
wait_for_value,
|
|
12
12
|
)
|
|
13
|
-
from ophyd_async.epics.
|
|
13
|
+
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw_rbv, epics_signal_x
|
|
14
14
|
|
|
15
15
|
from dodal.log import LOGGER
|
|
16
16
|
|
|
@@ -33,7 +33,7 @@ class SampleLocation:
|
|
|
33
33
|
pin: int
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class PinMounted(
|
|
36
|
+
class PinMounted(StrictEnum):
|
|
37
37
|
NO_PIN_MOUNTED = "No Pin Mounted"
|
|
38
38
|
PIN_MOUNTED = "Pin Mounted"
|
|
39
39
|
|
dodal/devices/smargon.py
CHANGED
|
@@ -7,8 +7,8 @@ from typing import cast
|
|
|
7
7
|
from bluesky import plan_stubs as bps
|
|
8
8
|
from bluesky.utils import Msg
|
|
9
9
|
from ophyd_async.core import AsyncStatus, Device, StandardReadable, wait_for_value
|
|
10
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
10
11
|
from ophyd_async.epics.motor import Motor
|
|
11
|
-
from ophyd_async.epics.signal import epics_signal_r
|
|
12
12
|
|
|
13
13
|
from dodal.devices.util.epics_util import SetWhenEnabled
|
|
14
14
|
|
dodal/devices/synchrotron.py
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
|
-
from ophyd_async.core import
|
|
4
|
-
|
|
3
|
+
from ophyd_async.core import (
|
|
4
|
+
StandardReadable,
|
|
5
|
+
StandardReadableFormat,
|
|
6
|
+
StrictEnum,
|
|
7
|
+
soft_signal_r_and_setter,
|
|
8
|
+
)
|
|
9
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
5
10
|
|
|
6
11
|
|
|
7
12
|
class Prefix(str, Enum):
|
|
@@ -19,7 +24,7 @@ class Suffix(str, Enum):
|
|
|
19
24
|
END_COUNTDOWN = "ENDCOUNTDN"
|
|
20
25
|
|
|
21
26
|
|
|
22
|
-
class SynchrotronMode(
|
|
27
|
+
class SynchrotronMode(StrictEnum):
|
|
23
28
|
SHUTDOWN = "Shutdown"
|
|
24
29
|
INJECTION = "Injection"
|
|
25
30
|
NOBEAM = "No Beam"
|
|
@@ -44,7 +49,7 @@ class Synchrotron(StandardReadable):
|
|
|
44
49
|
self.current = epics_signal_r(float, signal_prefix + Suffix.SIGNAL)
|
|
45
50
|
self.energy = epics_signal_r(float, status_prefix + Suffix.BEAM_ENERGY)
|
|
46
51
|
|
|
47
|
-
with self.add_children_as_readables(
|
|
52
|
+
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
|
|
48
53
|
self.probe, _ = soft_signal_r_and_setter(str, initial_value="x-ray")
|
|
49
54
|
self.type, _ = soft_signal_r_and_setter(
|
|
50
55
|
str, initial_value="Synchrotron X-ray Source"
|
dodal/devices/tetramm.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from enum import Enum
|
|
3
2
|
|
|
4
3
|
from bluesky.protocols import Hints
|
|
5
4
|
from ophyd_async.core import (
|
|
@@ -9,42 +8,43 @@ from ophyd_async.core import (
|
|
|
9
8
|
Device,
|
|
10
9
|
PathProvider,
|
|
11
10
|
StandardDetector,
|
|
11
|
+
StrictEnum,
|
|
12
12
|
TriggerInfo,
|
|
13
13
|
set_and_wait_for_value,
|
|
14
14
|
soft_signal_r_and_setter,
|
|
15
15
|
)
|
|
16
16
|
from ophyd_async.epics.adcore import ADHDFWriter, NDFileHDFIO, stop_busy_record
|
|
17
|
-
from ophyd_async.epics.
|
|
17
|
+
from ophyd_async.epics.core import (
|
|
18
18
|
epics_signal_r,
|
|
19
19
|
epics_signal_rw,
|
|
20
20
|
epics_signal_rw_rbv,
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class TetrammRange(
|
|
24
|
+
class TetrammRange(StrictEnum):
|
|
25
25
|
uA = "+- 120 uA"
|
|
26
26
|
nA = "+- 120 nA"
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class TetrammTrigger(
|
|
29
|
+
class TetrammTrigger(StrictEnum):
|
|
30
30
|
FreeRun = "Free run"
|
|
31
31
|
ExtTrigger = "Ext. trig."
|
|
32
32
|
ExtBulb = "Ext. bulb"
|
|
33
33
|
ExtGate = "Ext. gate"
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class TetrammChannels(
|
|
36
|
+
class TetrammChannels(StrictEnum):
|
|
37
37
|
One = "1"
|
|
38
38
|
Two = "2"
|
|
39
39
|
Four = "4"
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class TetrammResolution(
|
|
42
|
+
class TetrammResolution(StrictEnum):
|
|
43
43
|
SixteenBits = "16 bits"
|
|
44
44
|
TwentyFourBits = "24 bits"
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
class TetrammGeometry(
|
|
47
|
+
class TetrammGeometry(StrictEnum):
|
|
48
48
|
Diamond = "Diamond"
|
|
49
49
|
Square = "Square"
|
|
50
50
|
|
dodal/devices/thawer.py
CHANGED
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
from asyncio import Task, create_task, sleep
|
|
2
|
-
from enum import Enum
|
|
3
2
|
|
|
4
3
|
from bluesky.protocols import Stoppable
|
|
5
|
-
from ophyd_async.core import
|
|
6
|
-
|
|
4
|
+
from ophyd_async.core import (
|
|
5
|
+
AsyncStatus,
|
|
6
|
+
Device,
|
|
7
|
+
Reference,
|
|
8
|
+
SignalRW,
|
|
9
|
+
StandardReadable,
|
|
10
|
+
StrictEnum,
|
|
11
|
+
)
|
|
12
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
7
13
|
|
|
8
14
|
|
|
9
15
|
class ThawingException(Exception):
|
|
10
16
|
pass
|
|
11
17
|
|
|
12
18
|
|
|
13
|
-
class ThawerStates(
|
|
19
|
+
class ThawerStates(StrictEnum):
|
|
14
20
|
OFF = "Off"
|
|
15
21
|
ON = "On"
|
|
16
22
|
|
|
17
23
|
|
|
18
24
|
class ThawingTimer(Device, Stoppable):
|
|
19
25
|
def __init__(self, control_signal: SignalRW[ThawerStates]) -> None:
|
|
20
|
-
self.
|
|
26
|
+
self._control_signal_ref = Reference(control_signal)
|
|
21
27
|
self._thawing_task: Task | None = None
|
|
22
28
|
super().__init__("thaw_for_time_s")
|
|
23
29
|
|
|
24
30
|
@AsyncStatus.wrap
|
|
25
31
|
async def set(self, time_to_thaw_for: float):
|
|
26
|
-
await self.
|
|
32
|
+
await self._control_signal_ref().set(ThawerStates.ON)
|
|
27
33
|
if self._thawing_task and not self._thawing_task.done():
|
|
28
34
|
raise ThawingException("Thawing task already in progress")
|
|
29
35
|
self._thawing_task = create_task(sleep(time_to_thaw_for))
|
|
30
36
|
try:
|
|
31
37
|
await self._thawing_task
|
|
32
38
|
finally:
|
|
33
|
-
await self.
|
|
39
|
+
await self._control_signal_ref().set(ThawerStates.OFF)
|
|
34
40
|
|
|
35
41
|
@AsyncStatus.wrap
|
|
36
42
|
async def stop(self, *args, **kwargs):
|
dodal/devices/undulator.py
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from enum import Enum
|
|
3
2
|
|
|
4
3
|
import numpy as np
|
|
5
4
|
from bluesky.protocols import Movable
|
|
6
5
|
from numpy import argmin, ndarray
|
|
7
6
|
from ophyd_async.core import (
|
|
8
7
|
AsyncStatus,
|
|
9
|
-
ConfigSignal,
|
|
10
8
|
StandardReadable,
|
|
9
|
+
StandardReadableFormat,
|
|
10
|
+
StrictEnum,
|
|
11
11
|
soft_signal_r_and_setter,
|
|
12
12
|
)
|
|
13
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
13
14
|
from ophyd_async.epics.motor import Motor
|
|
14
|
-
from ophyd_async.epics.signal import epics_signal_r
|
|
15
15
|
|
|
16
16
|
from dodal.log import LOGGER
|
|
17
17
|
|
|
@@ -33,7 +33,7 @@ UNDULATOR_DISCREPANCY_THRESHOLD_MM = 2e-3
|
|
|
33
33
|
STATUS_TIMEOUT_S: float = 10.0
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class UndulatorGapAccess(
|
|
36
|
+
class UndulatorGapAccess(StrictEnum):
|
|
37
37
|
ENABLED = "ENABLED"
|
|
38
38
|
DISABLED = "DISABLED"
|
|
39
39
|
|
|
@@ -75,7 +75,7 @@ class Undulator(StandardReadable, Movable):
|
|
|
75
75
|
self.current_gap = epics_signal_r(float, prefix + "CURRGAPD")
|
|
76
76
|
self.gap_access = epics_signal_r(UndulatorGapAccess, prefix + "IDBLENA")
|
|
77
77
|
|
|
78
|
-
with self.add_children_as_readables(
|
|
78
|
+
with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
|
|
79
79
|
self.gap_discrepancy_tolerance_mm, _ = soft_signal_r_and_setter(
|
|
80
80
|
float,
|
|
81
81
|
initial_value=UNDULATOR_DISCREPANCY_THRESHOLD_MM,
|
dodal/devices/util/epics_util.py
CHANGED
|
@@ -7,7 +7,7 @@ from ophyd import Device as OphydDevice
|
|
|
7
7
|
from ophyd.status import Status, StatusBase
|
|
8
8
|
from ophyd_async.core import AsyncStatus, wait_for_value
|
|
9
9
|
from ophyd_async.core import Device as OphydAsyncDevice
|
|
10
|
-
from ophyd_async.epics.
|
|
10
|
+
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
|
|
11
11
|
|
|
12
12
|
from dodal.log import LOGGER
|
|
13
13
|
|