ophyd-async 0.9.0a1__py3-none-any.whl → 0.10.0a1__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 (157) hide show
  1. ophyd_async/__init__.py +5 -8
  2. ophyd_async/_docs_parser.py +12 -0
  3. ophyd_async/_version.py +9 -4
  4. ophyd_async/core/__init__.py +102 -74
  5. ophyd_async/core/_derived_signal.py +271 -0
  6. ophyd_async/core/_derived_signal_backend.py +300 -0
  7. ophyd_async/core/_detector.py +158 -153
  8. ophyd_async/core/_device.py +143 -115
  9. ophyd_async/core/_device_filler.py +82 -9
  10. ophyd_async/core/_flyer.py +16 -7
  11. ophyd_async/core/_hdf_dataset.py +29 -22
  12. ophyd_async/core/_log.py +14 -23
  13. ophyd_async/core/_mock_signal_backend.py +11 -3
  14. ophyd_async/core/_protocol.py +65 -45
  15. ophyd_async/core/_providers.py +28 -9
  16. ophyd_async/core/_readable.py +74 -58
  17. ophyd_async/core/_settings.py +113 -0
  18. ophyd_async/core/_signal.py +304 -174
  19. ophyd_async/core/_signal_backend.py +60 -14
  20. ophyd_async/core/_soft_signal_backend.py +18 -12
  21. ophyd_async/core/_status.py +72 -24
  22. ophyd_async/core/_table.py +54 -17
  23. ophyd_async/core/_utils.py +101 -52
  24. ophyd_async/core/_yaml_settings.py +66 -0
  25. ophyd_async/epics/__init__.py +1 -0
  26. ophyd_async/epics/adandor/__init__.py +9 -0
  27. ophyd_async/epics/adandor/_andor.py +45 -0
  28. ophyd_async/epics/adandor/_andor_controller.py +51 -0
  29. ophyd_async/epics/adandor/_andor_io.py +34 -0
  30. ophyd_async/epics/adaravis/__init__.py +8 -1
  31. ophyd_async/epics/adaravis/_aravis.py +23 -41
  32. ophyd_async/epics/adaravis/_aravis_controller.py +23 -55
  33. ophyd_async/epics/adaravis/_aravis_io.py +13 -28
  34. ophyd_async/epics/adcore/__init__.py +36 -14
  35. ophyd_async/epics/adcore/_core_detector.py +81 -0
  36. ophyd_async/epics/adcore/_core_io.py +145 -95
  37. ophyd_async/epics/adcore/_core_logic.py +179 -88
  38. ophyd_async/epics/adcore/_core_writer.py +223 -0
  39. ophyd_async/epics/adcore/_hdf_writer.py +51 -92
  40. ophyd_async/epics/adcore/_jpeg_writer.py +26 -0
  41. ophyd_async/epics/adcore/_single_trigger.py +6 -5
  42. ophyd_async/epics/adcore/_tiff_writer.py +26 -0
  43. ophyd_async/epics/adcore/_utils.py +3 -2
  44. ophyd_async/epics/adkinetix/__init__.py +2 -1
  45. ophyd_async/epics/adkinetix/_kinetix.py +32 -27
  46. ophyd_async/epics/adkinetix/_kinetix_controller.py +11 -21
  47. ophyd_async/epics/adkinetix/_kinetix_io.py +12 -13
  48. ophyd_async/epics/adpilatus/__init__.py +7 -2
  49. ophyd_async/epics/adpilatus/_pilatus.py +28 -40
  50. ophyd_async/epics/adpilatus/_pilatus_controller.py +25 -22
  51. ophyd_async/epics/adpilatus/_pilatus_io.py +11 -9
  52. ophyd_async/epics/adsimdetector/__init__.py +8 -1
  53. ophyd_async/epics/adsimdetector/_sim.py +22 -16
  54. ophyd_async/epics/adsimdetector/_sim_controller.py +9 -43
  55. ophyd_async/epics/adsimdetector/_sim_io.py +10 -0
  56. ophyd_async/epics/advimba/__init__.py +10 -1
  57. ophyd_async/epics/advimba/_vimba.py +26 -25
  58. ophyd_async/epics/advimba/_vimba_controller.py +12 -24
  59. ophyd_async/epics/advimba/_vimba_io.py +23 -28
  60. ophyd_async/epics/core/_aioca.py +66 -30
  61. ophyd_async/epics/core/_epics_connector.py +4 -0
  62. ophyd_async/epics/core/_epics_device.py +2 -0
  63. ophyd_async/epics/core/_p4p.py +50 -18
  64. ophyd_async/epics/core/_pvi_connector.py +65 -8
  65. ophyd_async/epics/core/_signal.py +51 -51
  66. ophyd_async/epics/core/_util.py +5 -5
  67. ophyd_async/epics/demo/__init__.py +11 -49
  68. ophyd_async/epics/demo/__main__.py +31 -0
  69. ophyd_async/epics/demo/_ioc.py +32 -0
  70. ophyd_async/epics/demo/_motor.py +82 -0
  71. ophyd_async/epics/demo/_point_detector.py +42 -0
  72. ophyd_async/epics/demo/_point_detector_channel.py +22 -0
  73. ophyd_async/epics/demo/_stage.py +15 -0
  74. ophyd_async/epics/demo/{mover.db → motor.db} +2 -1
  75. ophyd_async/epics/demo/point_detector.db +59 -0
  76. ophyd_async/epics/demo/point_detector_channel.db +21 -0
  77. ophyd_async/epics/eiger/_eiger.py +1 -3
  78. ophyd_async/epics/eiger/_eiger_controller.py +11 -4
  79. ophyd_async/epics/eiger/_eiger_io.py +2 -0
  80. ophyd_async/epics/eiger/_odin_io.py +1 -2
  81. ophyd_async/epics/motor.py +83 -38
  82. ophyd_async/epics/signal.py +4 -1
  83. ophyd_async/epics/testing/__init__.py +14 -14
  84. ophyd_async/epics/testing/_example_ioc.py +68 -73
  85. ophyd_async/epics/testing/_utils.py +19 -44
  86. ophyd_async/epics/testing/test_records.db +16 -0
  87. ophyd_async/epics/testing/test_records_pva.db +17 -16
  88. ophyd_async/fastcs/__init__.py +1 -0
  89. ophyd_async/fastcs/core.py +6 -0
  90. ophyd_async/fastcs/odin/__init__.py +1 -0
  91. ophyd_async/fastcs/panda/__init__.py +8 -8
  92. ophyd_async/fastcs/panda/_block.py +29 -9
  93. ophyd_async/fastcs/panda/_control.py +12 -2
  94. ophyd_async/fastcs/panda/_hdf_panda.py +5 -1
  95. ophyd_async/fastcs/panda/_table.py +13 -7
  96. ophyd_async/fastcs/panda/_trigger.py +23 -9
  97. ophyd_async/fastcs/panda/_writer.py +27 -30
  98. ophyd_async/plan_stubs/__init__.py +16 -0
  99. ophyd_async/plan_stubs/_ensure_connected.py +12 -17
  100. ophyd_async/plan_stubs/_fly.py +3 -5
  101. ophyd_async/plan_stubs/_nd_attributes.py +9 -5
  102. ophyd_async/plan_stubs/_panda.py +14 -0
  103. ophyd_async/plan_stubs/_settings.py +152 -0
  104. ophyd_async/plan_stubs/_utils.py +3 -0
  105. ophyd_async/plan_stubs/_wait_for_awaitable.py +13 -0
  106. ophyd_async/sim/__init__.py +29 -0
  107. ophyd_async/sim/__main__.py +43 -0
  108. ophyd_async/sim/_blob_detector.py +33 -0
  109. ophyd_async/sim/_blob_detector_controller.py +48 -0
  110. ophyd_async/sim/_blob_detector_writer.py +105 -0
  111. ophyd_async/sim/_mirror_horizontal.py +46 -0
  112. ophyd_async/sim/_mirror_vertical.py +74 -0
  113. ophyd_async/sim/_motor.py +233 -0
  114. ophyd_async/sim/_pattern_generator.py +124 -0
  115. ophyd_async/sim/_point_detector.py +86 -0
  116. ophyd_async/sim/_stage.py +19 -0
  117. ophyd_async/tango/__init__.py +1 -0
  118. ophyd_async/tango/core/__init__.py +6 -1
  119. ophyd_async/tango/core/_base_device.py +41 -33
  120. ophyd_async/tango/core/_converters.py +81 -0
  121. ophyd_async/tango/core/_signal.py +21 -33
  122. ophyd_async/tango/core/_tango_readable.py +2 -19
  123. ophyd_async/tango/core/_tango_transport.py +148 -74
  124. ophyd_async/tango/core/_utils.py +47 -0
  125. ophyd_async/tango/demo/_counter.py +2 -0
  126. ophyd_async/tango/demo/_detector.py +2 -0
  127. ophyd_async/tango/demo/_mover.py +10 -6
  128. ophyd_async/tango/demo/_tango/_servers.py +4 -0
  129. ophyd_async/tango/testing/__init__.py +6 -0
  130. ophyd_async/tango/testing/_one_of_everything.py +200 -0
  131. ophyd_async/testing/__init__.py +48 -7
  132. ophyd_async/testing/__pytest_assert_rewrite.py +4 -0
  133. ophyd_async/testing/_assert.py +200 -96
  134. ophyd_async/testing/_mock_signal_utils.py +59 -73
  135. ophyd_async/testing/_one_of_everything.py +146 -0
  136. ophyd_async/testing/_single_derived.py +87 -0
  137. ophyd_async/testing/_utils.py +3 -0
  138. {ophyd_async-0.9.0a1.dist-info → ophyd_async-0.10.0a1.dist-info}/METADATA +25 -26
  139. ophyd_async-0.10.0a1.dist-info/RECORD +149 -0
  140. {ophyd_async-0.9.0a1.dist-info → ophyd_async-0.10.0a1.dist-info}/WHEEL +1 -1
  141. ophyd_async/core/_device_save_loader.py +0 -274
  142. ophyd_async/epics/demo/_mover.py +0 -95
  143. ophyd_async/epics/demo/_sensor.py +0 -37
  144. ophyd_async/epics/demo/sensor.db +0 -19
  145. ophyd_async/fastcs/panda/_utils.py +0 -16
  146. ophyd_async/sim/demo/__init__.py +0 -19
  147. ophyd_async/sim/demo/_pattern_detector/__init__.py +0 -13
  148. ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +0 -42
  149. ophyd_async/sim/demo/_pattern_detector/_pattern_detector_controller.py +0 -62
  150. ophyd_async/sim/demo/_pattern_detector/_pattern_detector_writer.py +0 -41
  151. ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +0 -207
  152. ophyd_async/sim/demo/_sim_motor.py +0 -107
  153. ophyd_async/sim/testing/__init__.py +0 -0
  154. ophyd_async-0.9.0a1.dist-info/RECORD +0 -119
  155. ophyd_async-0.9.0a1.dist-info/entry_points.txt +0 -2
  156. {ophyd_async-0.9.0a1.dist-info → ophyd_async-0.10.0a1.dist-info/licenses}/LICENSE +0 -0
  157. {ophyd_async-0.9.0a1.dist-info → ophyd_async-0.10.0a1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,81 @@
1
+ from typing import Any, Generic
2
+
3
+ import numpy as np
4
+ from numpy.typing import NDArray
5
+
6
+ from ophyd_async.core import (
7
+ SignalDatatypeT,
8
+ )
9
+ from tango import (
10
+ DevState,
11
+ )
12
+
13
+ from ._utils import DevStateEnum
14
+
15
+
16
+ class TangoConverter(Generic[SignalDatatypeT]):
17
+ def write_value(self, value: Any) -> Any:
18
+ return value
19
+
20
+ def value(self, value: Any) -> Any:
21
+ return value
22
+
23
+
24
+ class TangoEnumConverter(TangoConverter):
25
+ def __init__(self, labels: list[str]):
26
+ self._labels = labels
27
+
28
+ def write_value(self, value: str):
29
+ if not isinstance(value, str):
30
+ raise TypeError("TangoEnumConverter expects str value")
31
+ return self._labels.index(value)
32
+
33
+ def value(self, value: int):
34
+ return self._labels[value]
35
+
36
+
37
+ class TangoEnumArrayConverter(TangoConverter):
38
+ def __init__(self, labels: list[str]):
39
+ self._labels = labels
40
+
41
+ def write_value(self, value: NDArray[np.str_]) -> NDArray[np.integer]:
42
+ vfunc = np.vectorize(self._labels.index)
43
+ new_array = vfunc(value)
44
+ return new_array
45
+
46
+ def value(self, value: NDArray[np.integer]) -> NDArray[np.str_]:
47
+ vfunc = np.vectorize(self._labels.__getitem__)
48
+ new_array = vfunc(value)
49
+ return new_array
50
+
51
+
52
+ class TangoDevStateConverter(TangoConverter):
53
+ _labels = [e.value for e in DevStateEnum]
54
+
55
+ def write_value(self, value: str) -> DevState:
56
+ idx = self._labels.index(value)
57
+ return DevState(idx)
58
+
59
+ def value(self, value: DevState) -> str:
60
+ idx = int(value)
61
+ return self._labels[idx]
62
+
63
+
64
+ class TangoDevStateArrayConverter(TangoConverter):
65
+ _labels = [e.value for e in DevStateEnum]
66
+
67
+ def _write_convert(self, value):
68
+ return DevState(self._labels.index(value))
69
+
70
+ def _convert(self, value):
71
+ return self._labels[int(value)]
72
+
73
+ def write_value(self, value: NDArray[np.str_]) -> NDArray[DevState]:
74
+ vfunc = np.vectorize(self._write_convert, otypes=[DevState])
75
+ new_array = vfunc(value)
76
+ return new_array
77
+
78
+ def value(self, value: NDArray[DevState]) -> NDArray[np.str_]:
79
+ vfunc = np.vectorize(self._convert)
80
+ new_array = vfunc(value)
81
+ return new_array
@@ -1,4 +1,4 @@
1
- """Tango Signals over Pytango"""
1
+ """Tango Signals over Pytango."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -22,31 +22,31 @@ from tango import (
22
22
  CmdArgType,
23
23
  DeviceProxy,
24
24
  DevState,
25
- NonSupportedFeature, # type: ignore
26
25
  )
27
26
  from tango.asyncio import DeviceProxy as AsyncDeviceProxy
28
27
 
29
28
  from ._tango_transport import TangoSignalBackend, get_python_type
29
+ from ._utils import get_device_trl_and_attr
30
+
31
+ logger = logging.getLogger("ophyd_async")
30
32
 
31
33
 
32
34
  def make_backend(
33
35
  datatype: type[SignalDatatypeT] | None,
34
36
  read_trl: str = "",
35
37
  write_trl: str = "",
36
- device_proxy: DeviceProxy | None = None,
37
38
  ) -> TangoSignalBackend:
38
- return TangoSignalBackend(datatype, read_trl, write_trl, device_proxy)
39
+ return TangoSignalBackend(datatype, read_trl, write_trl)
39
40
 
40
41
 
41
42
  def tango_signal_rw(
42
43
  datatype: type[SignalDatatypeT],
43
44
  read_trl: str,
44
45
  write_trl: str = "",
45
- device_proxy: DeviceProxy | None = None,
46
46
  timeout: float = DEFAULT_TIMEOUT,
47
47
  name: str = "",
48
48
  ) -> SignalRW[SignalDatatypeT]:
49
- """Create a `SignalRW` backed by 1 or 2 Tango Attribute/Command
49
+ """Create a `SignalRW` backed by 1 or 2 Tango Attribute/Command.
50
50
 
51
51
  Parameters
52
52
  ----------
@@ -56,25 +56,23 @@ def tango_signal_rw(
56
56
  The Attribute/Command to read and monitor
57
57
  write_trl:
58
58
  If given, use this Attribute/Command to write to, otherwise use read_trl
59
- device_proxy:
60
- If given, this DeviceProxy will be used
61
59
  timeout:
62
60
  The timeout for the read and write operations
63
61
  name:
64
62
  The name of the Signal
63
+
65
64
  """
66
- backend = make_backend(datatype, read_trl, write_trl or read_trl, device_proxy)
65
+ backend = make_backend(datatype, read_trl, write_trl or read_trl)
67
66
  return SignalRW(backend, timeout=timeout, name=name)
68
67
 
69
68
 
70
69
  def tango_signal_r(
71
70
  datatype: type[SignalDatatypeT],
72
71
  read_trl: str,
73
- device_proxy: DeviceProxy | None = None,
74
72
  timeout: float = DEFAULT_TIMEOUT,
75
73
  name: str = "",
76
74
  ) -> SignalR[SignalDatatypeT]:
77
- """Create a `SignalR` backed by 1 Tango Attribute/Command
75
+ """Create a `SignalR` backed by 1 Tango Attribute/Command.
78
76
 
79
77
  Parameters
80
78
  ----------
@@ -82,25 +80,23 @@ def tango_signal_r(
82
80
  Check that the Attribute/Command is of this type
83
81
  read_trl:
84
82
  The Attribute/Command to read and monitor
85
- device_proxy:
86
- If given, this DeviceProxy will be used
87
83
  timeout:
88
84
  The timeout for the read operation
89
85
  name:
90
86
  The name of the Signal
87
+
91
88
  """
92
- backend = make_backend(datatype, read_trl, read_trl, device_proxy)
89
+ backend = make_backend(datatype, read_trl, read_trl)
93
90
  return SignalR(backend, timeout=timeout, name=name)
94
91
 
95
92
 
96
93
  def tango_signal_w(
97
94
  datatype: type[SignalDatatypeT],
98
95
  write_trl: str,
99
- device_proxy: DeviceProxy | None = None,
100
96
  timeout: float = DEFAULT_TIMEOUT,
101
97
  name: str = "",
102
98
  ) -> SignalW[SignalDatatypeT]:
103
- """Create a `SignalW` backed by 1 Tango Attribute/Command
99
+ """Create a `SignalW` backed by 1 Tango Attribute/Command.
104
100
 
105
101
  Parameters
106
102
  ----------
@@ -108,45 +104,43 @@ def tango_signal_w(
108
104
  Check that the Attribute/Command is of this type
109
105
  write_trl:
110
106
  The Attribute/Command to write to
111
- device_proxy:
112
- If given, this DeviceProxy will be used
113
107
  timeout:
114
108
  The timeout for the write operation
115
109
  name:
116
110
  The name of the Signal
111
+
117
112
  """
118
- backend = make_backend(datatype, write_trl, write_trl, device_proxy)
113
+ backend = make_backend(datatype, write_trl, write_trl)
119
114
  return SignalW(backend, timeout=timeout, name=name)
120
115
 
121
116
 
122
117
  def tango_signal_x(
123
118
  write_trl: str,
124
- device_proxy: DeviceProxy | None = None,
125
119
  timeout: float = DEFAULT_TIMEOUT,
126
120
  name: str = "",
127
121
  ) -> SignalX:
128
- """Create a `SignalX` backed by 1 Tango Attribute/Command
122
+ """Create a `SignalX` backed by 1 Tango Attribute/Command.
129
123
 
130
124
  Parameters
131
125
  ----------
132
126
  write_trl:
133
127
  The Attribute/Command to write its initial value to on execute
134
- device_proxy:
135
- If given, this DeviceProxy will be used
136
128
  timeout:
137
129
  The timeout for the command operation
138
130
  name:
139
131
  The name of the Signal
132
+
140
133
  """
141
- backend = make_backend(None, write_trl, write_trl, device_proxy)
134
+ backend = make_backend(None, write_trl, write_trl)
142
135
  return SignalX(backend, timeout=timeout, name=name)
143
136
 
144
137
 
145
138
  async def infer_python_type(
146
139
  trl: str = "", proxy: DeviceProxy | None = None
147
140
  ) -> object | npt.NDArray | type[DevState] | IntEnum:
141
+ """Infers the python type from the TRL."""
148
142
  # TODO: work out if this is still needed
149
- device_trl, tr_name = trl.rsplit("/", 1)
143
+ device_trl, tr_name = get_device_trl_and_attr(trl)
150
144
  if proxy is None:
151
145
  dev_proxy = await AsyncDeviceProxy(device_trl)
152
146
  else:
@@ -175,18 +169,12 @@ async def infer_python_type(
175
169
  async def infer_signal_type(
176
170
  trl, proxy: DeviceProxy | None = None
177
171
  ) -> type[Signal] | None:
178
- device_trl, tr_name = trl.rsplit("/", 1)
172
+ device_trl, tr_name = get_device_trl_and_attr(trl)
179
173
  if proxy is None:
180
174
  dev_proxy = await AsyncDeviceProxy(device_trl)
181
175
  else:
182
176
  dev_proxy = proxy
183
177
 
184
- try:
185
- if tr_name in dev_proxy.get_pipe_list():
186
- raise NotImplementedError("Pipes are not supported")
187
- except NonSupportedFeature: # type: ignore
188
- pass
189
-
190
178
  if tr_name not in dev_proxy.get_attribute_list():
191
179
  if tr_name not in dev_proxy.get_command_list():
192
180
  raise RuntimeError(f"Cannot find {tr_name} in {device_trl}")
@@ -205,7 +193,7 @@ async def infer_signal_type(
205
193
  if config.in_type == CmdArgType.DevVoid:
206
194
  return SignalX
207
195
  elif config.in_type != config.out_type:
208
- logging.debug("Commands with different in and out dtypes are not supported")
196
+ logger.debug("Commands with different in and out dtypes are not supported")
209
197
  return None
210
198
  else:
211
199
  return SignalRW
@@ -1,32 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from ophyd_async.core import StandardReadable
4
- from tango import DeviceProxy
5
4
 
6
5
  from ._base_device import TangoDevice
7
6
 
8
7
 
9
8
  class TangoReadable(TangoDevice, StandardReadable):
10
- """
11
- General class for readable TangoDevices. Extends StandardReadable to provide
12
- attributes for Tango devices.
13
-
14
- Usage: to proper signals mount should be awaited:
15
- new_device = await TangoDevice(<tango_device>)
16
-
17
- Attributes
18
- ----------
19
- trl : str
20
- Tango resource locator, typically of the device server.
21
- proxy : AsyncDeviceProxy
22
- AsyncDeviceProxy object for the device. This is created when the
23
- device is connected.
24
- """
25
-
26
9
  def __init__(
27
10
  self,
28
11
  trl: str | None = None,
29
- device_proxy: DeviceProxy | None = None,
30
12
  name: str = "",
13
+ auto_fill_signals: bool = True,
31
14
  ) -> None:
32
- TangoDevice.__init__(self, trl, device_proxy=device_proxy, name=name)
15
+ TangoDevice.__init__(self, trl, name=name, auto_fill_signals=auto_fill_signals)