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.
Files changed (81) hide show
  1. {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/METADATA +4 -2
  2. dls_dodal-1.36.0.dist-info/RECORD +152 -0
  3. {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/WHEEL +1 -1
  4. dodal/_version.py +2 -2
  5. dodal/beamlines/i22.py +24 -11
  6. dodal/beamlines/i24.py +4 -4
  7. dodal/beamlines/p38.py +23 -11
  8. dodal/common/beamlines/beamline_utils.py +1 -2
  9. dodal/common/crystal_metadata.py +61 -0
  10. dodal/common/signal_utils.py +10 -14
  11. dodal/devices/CTAB.py +1 -1
  12. dodal/devices/aperture.py +1 -1
  13. dodal/devices/aperturescatterguard.py +20 -8
  14. dodal/devices/apple2_undulator.py +30 -29
  15. dodal/devices/areadetector/plugins/CAM.py +3 -5
  16. dodal/devices/areadetector/plugins/MJPG.py +1 -1
  17. dodal/devices/attenuator.py +1 -1
  18. dodal/devices/backlight.py +4 -5
  19. dodal/devices/cryostream.py +3 -5
  20. dodal/devices/dcm.py +26 -2
  21. dodal/devices/detector/detector_motion.py +3 -5
  22. dodal/devices/diamond_filter.py +3 -4
  23. dodal/devices/eiger.py +88 -49
  24. dodal/devices/fast_grid_scan.py +1 -1
  25. dodal/devices/fluorescence_detector_motion.py +5 -7
  26. dodal/devices/focusing_mirror.py +12 -11
  27. dodal/devices/hutch_shutter.py +4 -5
  28. dodal/devices/i10/i10_apple2.py +20 -19
  29. dodal/devices/i10/i10_setting_data.py +2 -2
  30. dodal/devices/i22/dcm.py +43 -75
  31. dodal/devices/i22/fswitch.py +5 -5
  32. dodal/devices/i24/aperture.py +3 -5
  33. dodal/devices/i24/beamstop.py +3 -5
  34. dodal/devices/i24/dcm.py +1 -1
  35. dodal/devices/i24/dual_backlight.py +4 -6
  36. dodal/devices/i24/pmac.py +35 -46
  37. dodal/devices/i24/vgonio.py +16 -0
  38. dodal/devices/ipin.py +5 -3
  39. dodal/devices/linkam3.py +7 -7
  40. dodal/devices/oav/oav_detector.py +3 -3
  41. dodal/devices/oav/oav_to_redis_forwarder.py +8 -7
  42. dodal/devices/oav/pin_image_recognition/__init__.py +9 -7
  43. dodal/devices/oav/snapshots/grid_overlay.py +16 -16
  44. dodal/devices/oav/snapshots/snapshot_with_beam_centre.py +5 -5
  45. dodal/devices/oav/snapshots/snapshot_with_grid.py +6 -6
  46. dodal/devices/oav/utils.py +2 -2
  47. dodal/devices/p99/sample_stage.py +3 -5
  48. dodal/devices/pgm.py +5 -6
  49. dodal/devices/qbpm.py +1 -1
  50. dodal/devices/robot.py +3 -3
  51. dodal/devices/smargon.py +1 -1
  52. dodal/devices/synchrotron.py +9 -4
  53. dodal/devices/tetramm.py +7 -7
  54. dodal/devices/thawer.py +13 -7
  55. dodal/devices/undulator.py +5 -5
  56. dodal/devices/util/epics_util.py +1 -1
  57. dodal/devices/watsonmarlow323_pump.py +45 -0
  58. dodal/devices/webcam.py +9 -2
  59. dodal/devices/xbpm_feedback.py +3 -5
  60. dodal/devices/xspress3/xspress3.py +8 -9
  61. dodal/devices/xspress3/xspress3_channel.py +3 -5
  62. dodal/devices/zebra.py +7 -6
  63. dodal/devices/zebra_controlled_shutter.py +5 -6
  64. dodal/devices/zocalo/__init__.py +2 -2
  65. dodal/devices/zocalo/zocalo_constants.py +3 -0
  66. dodal/devices/zocalo/zocalo_interaction.py +2 -1
  67. dodal/devices/zocalo/zocalo_results.py +92 -79
  68. dodal/plan_stubs/__init__.py +0 -0
  69. dodal/{plans/data_session_metadata.py → plan_stubs/data_session.py} +2 -2
  70. dodal/{plans/motor_util_plans.py → plan_stubs/motor_utils.py} +2 -2
  71. dodal/plan_stubs/wrapped.py +150 -0
  72. dodal/plans/__init__.py +4 -0
  73. dodal/plans/scanspec.py +66 -0
  74. dodal/plans/wrapped.py +57 -0
  75. dodal/utils.py +4 -0
  76. dls_dodal-1.34.1.dist-info/RECORD +0 -144
  77. dodal/devices/i24/i24_vgonio.py +0 -17
  78. {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/LICENSE +0 -0
  79. {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/entry_points.txt +0 -0
  80. {dls_dodal-1.34.1.dist-info → dls_dodal-1.36.0.dist-info}/top_level.txt +0 -0
  81. /dodal/{plans → plan_stubs}/check_topup.py +0 -0
dodal/devices/ipin.py CHANGED
@@ -1,11 +1,13 @@
1
- from ophyd_async.core import HintedSignal, StandardReadable
2
- from ophyd_async.epics.signal import epics_signal_r
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(wrapper=HintedSignal):
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.signal import epics_signal_r, epics_signal_rw
13
+ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
15
14
 
16
15
 
17
- class PumpControl(str, Enum):
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,), wrapper=HintedSignal)
64
+ self.add_readables((self.temp,), format=StandardReadableFormat.HINTED_SIGNAL)
66
65
  self.add_readables(
67
- (self.ramp_rate, self.speed, self.set_point), wrapper=ConfigSignal
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.signal import epics_signal_rw
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.signal import epics_signal_r
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._sources = DeviceVector(
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(Source)
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
- source_name = await self.selected_source.get_value()
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 {source_name}"
124
+ f"Forwarding data from sample {await self.sample_id.get_value()} and OAV {source_idx}"
124
125
  )
125
- source = self._sources[source_name.value]
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.signal import epics_signal_r
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 = tuple[int | None, int | None]
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 = (None, None)
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
- wrapper=HintedSignal,
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
- tip = (results.tip_x, results.tip_y)
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: int,
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 (int): The spacing, in pixels, between each parallel line. Strictly, \
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: int,
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: int,
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.beam_centre_i = beam_x_signal
56
- self.beam_centre_j = beam_y_signal
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.beam_centre_i.get_value()
61
- beam_y = await self.beam_centre_j.get_value()
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(int)
18
- self.top_left_y = soft_signal_rw(int)
19
- self.box_width = soft_signal_rw(int)
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
- box_witdh = await self.box_width.get_value()
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, box_witdh, num_boxes_x, num_boxes_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, box_witdh, num_boxes_x, num_boxes_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}")
@@ -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 # type: ignore
110
+ return Pixel((int(found_tip[0]), int(found_tip[1])))
@@ -1,7 +1,5 @@
1
- from enum import Enum
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(str, Enum):
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[Enum],
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(ConfigSignal):
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
@@ -1,5 +1,5 @@
1
1
  from ophyd_async.core import StandardReadable
2
- from ophyd_async.epics.signal import epics_signal_r
2
+ from ophyd_async.epics.core import epics_signal_r
3
3
 
4
4
 
5
5
  class QBPM(StandardReadable):
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.signal import epics_signal_r, epics_signal_rw_rbv, epics_signal_x
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(str, Enum):
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
 
@@ -1,7 +1,12 @@
1
1
  from enum import Enum
2
2
 
3
- from ophyd_async.core import ConfigSignal, StandardReadable, soft_signal_r_and_setter
4
- from ophyd_async.epics.signal import epics_signal_r
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(str, Enum):
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(ConfigSignal):
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.signal import (
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(str, Enum):
24
+ class TetrammRange(StrictEnum):
25
25
  uA = "+- 120 uA"
26
26
  nA = "+- 120 nA"
27
27
 
28
28
 
29
- class TetrammTrigger(str, Enum):
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(str, Enum):
36
+ class TetrammChannels(StrictEnum):
37
37
  One = "1"
38
38
  Two = "2"
39
39
  Four = "4"
40
40
 
41
41
 
42
- class TetrammResolution(str, Enum):
42
+ class TetrammResolution(StrictEnum):
43
43
  SixteenBits = "16 bits"
44
44
  TwentyFourBits = "24 bits"
45
45
 
46
46
 
47
- class TetrammGeometry(str, Enum):
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 AsyncStatus, Device, SignalRW, StandardReadable
6
- from ophyd_async.epics.signal import epics_signal_rw
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(str, Enum):
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._control_signal = control_signal
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._control_signal.set(ThawerStates.ON)
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._control_signal.set(ThawerStates.OFF)
39
+ await self._control_signal_ref().set(ThawerStates.OFF)
34
40
 
35
41
  @AsyncStatus.wrap
36
42
  async def stop(self, *args, **kwargs):
@@ -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(str, Enum):
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(ConfigSignal):
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,
@@ -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.signal import epics_signal_r, epics_signal_rw
10
+ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
11
11
 
12
12
  from dodal.log import LOGGER
13
13