ophyd-async 0.3a3__py3-none-any.whl → 0.3a5__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 (40) hide show
  1. ophyd_async/_version.py +1 -1
  2. ophyd_async/core/__init__.py +26 -11
  3. ophyd_async/core/async_status.py +96 -33
  4. ophyd_async/core/detector.py +22 -28
  5. ophyd_async/core/device.py +50 -14
  6. ophyd_async/core/mock_signal_backend.py +85 -0
  7. ophyd_async/core/mock_signal_utils.py +149 -0
  8. ophyd_async/core/signal.py +93 -53
  9. ophyd_async/core/{sim_signal_backend.py → soft_signal_backend.py} +23 -33
  10. ophyd_async/core/utils.py +19 -0
  11. ophyd_async/epics/_backend/_aioca.py +11 -7
  12. ophyd_async/epics/_backend/_p4p.py +11 -7
  13. ophyd_async/epics/_backend/common.py +17 -17
  14. ophyd_async/epics/areadetector/__init__.py +0 -4
  15. ophyd_async/epics/areadetector/aravis.py +1 -5
  16. ophyd_async/epics/areadetector/controllers/aravis_controller.py +6 -1
  17. ophyd_async/epics/areadetector/drivers/ad_base.py +12 -10
  18. ophyd_async/epics/areadetector/drivers/aravis_driver.py +6 -122
  19. ophyd_async/epics/areadetector/drivers/kinetix_driver.py +7 -4
  20. ophyd_async/epics/areadetector/drivers/pilatus_driver.py +5 -2
  21. ophyd_async/epics/areadetector/drivers/vimba_driver.py +12 -7
  22. ophyd_async/epics/areadetector/utils.py +2 -12
  23. ophyd_async/epics/areadetector/writers/nd_file_hdf.py +21 -19
  24. ophyd_async/epics/areadetector/writers/nd_plugin.py +6 -7
  25. ophyd_async/epics/demo/__init__.py +27 -32
  26. ophyd_async/epics/motion/motor.py +40 -37
  27. ophyd_async/epics/pvi/pvi.py +13 -13
  28. ophyd_async/epics/signal/__init__.py +8 -1
  29. ophyd_async/panda/_hdf_panda.py +3 -3
  30. ophyd_async/planstubs/__init__.py +5 -1
  31. ophyd_async/planstubs/ensure_connected.py +22 -0
  32. ophyd_async/protocols.py +32 -2
  33. ophyd_async/sim/demo/sim_motor.py +50 -35
  34. ophyd_async/sim/pattern_generator.py +5 -5
  35. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/METADATA +2 -2
  36. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/RECORD +40 -37
  37. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/LICENSE +0 -0
  38. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/WHEEL +0 -0
  39. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/entry_points.txt +0 -0
  40. {ophyd_async-0.3a3.dist-info → ophyd_async-0.3a5.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,17 @@
1
1
  import asyncio
2
- import time
3
- from typing import Callable, List, Optional
2
+ from dataclasses import replace
4
3
 
5
4
  from bluesky.protocols import Movable, Stoppable
6
5
 
7
- from ophyd_async.core import AsyncStatus, ConfigSignal, HintedSignal, StandardReadable
6
+ from ophyd_async.core import (
7
+ AsyncStatus,
8
+ ConfigSignal,
9
+ HintedSignal,
10
+ StandardReadable,
11
+ WatchableAsyncStatus,
12
+ )
13
+ from ophyd_async.core.signal import observe_value
14
+ from ophyd_async.core.utils import WatcherUpdate
8
15
 
9
16
  from ..signal.signal import epics_signal_r, epics_signal_rw, epics_signal_x
10
17
 
@@ -40,51 +47,47 @@ class Motor(StandardReadable, Movable, Stoppable):
40
47
  # Readback should be named the same as its parent in read()
41
48
  self.user_readback.set_name(name)
42
49
 
43
- async def _move(self, new_position: float, watchers: List[Callable] = []):
50
+ async def _move(
51
+ self, new_position: float
52
+ ) -> tuple[WatcherUpdate[float], AsyncStatus]:
44
53
  self._set_success = True
45
- start = time.monotonic()
46
54
  old_position, units, precision = await asyncio.gather(
47
55
  self.user_setpoint.get_value(),
48
56
  self.motor_egu.get_value(),
49
57
  self.precision.get_value(),
50
58
  )
51
-
52
- def update_watchers(current_position: float):
53
- for watcher in watchers:
54
- watcher(
55
- name=self.name,
56
- current=current_position,
57
- initial=old_position,
58
- target=new_position,
59
- unit=units,
60
- precision=precision,
61
- time_elapsed=time.monotonic() - start,
62
- )
63
-
64
- self.user_readback.subscribe_value(update_watchers)
65
- try:
66
- await self.user_setpoint.set(new_position)
67
- finally:
68
- self.user_readback.clear_sub(update_watchers)
59
+ move_status = self.user_setpoint.set(new_position, wait=True)
69
60
  if not self._set_success:
70
61
  raise RuntimeError("Motor was stopped")
62
+ return (
63
+ WatcherUpdate(
64
+ initial=old_position,
65
+ current=old_position,
66
+ target=new_position,
67
+ unit=units,
68
+ precision=precision,
69
+ ),
70
+ move_status,
71
+ )
71
72
 
72
- def move(self, new_position: float, timeout: Optional[float] = None):
73
- """Commandline only synchronous move of a Motor"""
74
- from bluesky.run_engine import call_in_bluesky_event_loop, in_bluesky_event_loop
75
-
76
- if in_bluesky_event_loop():
77
- raise RuntimeError("Will deadlock run engine if run in a plan")
78
- call_in_bluesky_event_loop(self._move(new_position), timeout) # type: ignore
79
-
80
- def set(self, new_position: float, timeout: Optional[float] = None) -> AsyncStatus:
81
- watchers: List[Callable] = []
82
- coro = asyncio.wait_for(self._move(new_position, watchers), timeout=timeout)
83
- return AsyncStatus(coro, watchers)
73
+ @WatchableAsyncStatus.wrap
74
+ async def set(self, new_position: float, timeout: float | None = None):
75
+ update, move_status = await self._move(new_position)
76
+ async for current_position in observe_value(
77
+ self.user_readback, done_status=move_status
78
+ ):
79
+ if not self._set_success:
80
+ raise RuntimeError("Motor was stopped")
81
+ yield replace(
82
+ update,
83
+ name=self.name,
84
+ current=current_position,
85
+ )
84
86
 
85
87
  async def stop(self, success=False):
86
88
  self._set_success = success
87
89
  # Put with completion will never complete as we are waiting for completion on
88
90
  # the move above, so need to pass wait=False
89
- status = self.motor_stop.trigger(wait=False)
90
- await status
91
+ await self.motor_stop.trigger(wait=False)
92
+ # Trigger any callbacks
93
+ await self.user_readback._backend.put(await self.user_readback.get_value())
@@ -17,7 +17,7 @@ from typing import (
17
17
  get_type_hints,
18
18
  )
19
19
 
20
- from ophyd_async.core import Device, DeviceVector, SimSignalBackend
20
+ from ophyd_async.core import Device, DeviceVector, SoftSignalBackend
21
21
  from ophyd_async.core.signal import Signal
22
22
  from ophyd_async.core.utils import DEFAULT_TIMEOUT
23
23
  from ophyd_async.epics._backend._p4p import PvaSignalBackend
@@ -91,7 +91,7 @@ def _verify_common_blocks(entry: PVIEntry, common_device: Type[Device]):
91
91
  return
92
92
  common_sub_devices = get_type_hints(common_device)
93
93
  for sub_name, sub_device in common_sub_devices.items():
94
- if sub_name in ("_name", "parent"):
94
+ if sub_name.startswith("_") or sub_name == "parent":
95
95
  continue
96
96
  assert entry.sub_entries
97
97
  device_t, is_optional = _strip_union(sub_device)
@@ -156,12 +156,12 @@ def _parse_type(
156
156
  return is_device_vector, is_signal, signal_dtype, device_cls
157
157
 
158
158
 
159
- def _sim_common_blocks(device: Device, stripped_type: Optional[Type] = None):
159
+ def _mock_common_blocks(device: Device, stripped_type: Optional[Type] = None):
160
160
  device_t = stripped_type or type(device)
161
161
  sub_devices = (
162
162
  (field, field_type)
163
163
  for field, field_type in get_type_hints(device_t).items()
164
- if field not in ("_name", "parent")
164
+ if not field.startswith("_") and field != "parent"
165
165
  )
166
166
 
167
167
  for device_name, device_cls in sub_devices:
@@ -175,23 +175,23 @@ def _sim_common_blocks(device: Device, stripped_type: Optional[Type] = None):
175
175
 
176
176
  if is_device_vector:
177
177
  if is_signal:
178
- sub_device_1 = device_cls(SimSignalBackend(signal_dtype))
179
- sub_device_2 = device_cls(SimSignalBackend(signal_dtype))
178
+ sub_device_1 = device_cls(SoftSignalBackend(signal_dtype))
179
+ sub_device_2 = device_cls(SoftSignalBackend(signal_dtype))
180
180
  sub_device = DeviceVector({1: sub_device_1, 2: sub_device_2})
181
181
  else:
182
182
  sub_device = DeviceVector({1: device_cls(), 2: device_cls()})
183
183
 
184
184
  for sub_device_in_vector in sub_device.values():
185
- _sim_common_blocks(sub_device_in_vector, stripped_type=device_cls)
185
+ _mock_common_blocks(sub_device_in_vector, stripped_type=device_cls)
186
186
 
187
187
  for value in sub_device.values():
188
188
  value.parent = sub_device
189
189
  else:
190
190
  if is_signal:
191
- sub_device = device_cls(SimSignalBackend(signal_dtype))
191
+ sub_device = device_cls(SoftSignalBackend(signal_dtype))
192
192
  else:
193
193
  sub_device = getattr(device, device_name, device_cls())
194
- _sim_common_blocks(sub_device, stripped_type=device_cls)
194
+ _mock_common_blocks(sub_device, stripped_type=device_cls)
195
195
 
196
196
  setattr(device, device_name, sub_device)
197
197
  sub_device.parent = device
@@ -269,16 +269,16 @@ def _set_device_attributes(entry: PVIEntry):
269
269
 
270
270
 
271
271
  async def fill_pvi_entries(
272
- device: Device, root_pv: str, timeout=DEFAULT_TIMEOUT, sim=False
272
+ device: Device, root_pv: str, timeout=DEFAULT_TIMEOUT, mock=False
273
273
  ):
274
274
  """
275
275
  Fills a ``device`` with signals from a the ``root_pvi:PVI`` table.
276
276
 
277
277
  If the device names match with parent devices of ``device`` then types are used.
278
278
  """
279
- if sim:
280
- # set up sim signals for the common annotations
281
- _sim_common_blocks(device)
279
+ if mock:
280
+ # set up mock signals for the common annotations
281
+ _mock_common_blocks(device)
282
282
  else:
283
283
  # check the pvi table for devices and fill the device with them
284
284
  root_entry = PVIEntry(
@@ -1,8 +1,15 @@
1
- from .signal import epics_signal_r, epics_signal_rw, epics_signal_w, epics_signal_x
1
+ from .signal import (
2
+ epics_signal_r,
3
+ epics_signal_rw,
4
+ epics_signal_rw_rbv,
5
+ epics_signal_w,
6
+ epics_signal_x,
7
+ )
2
8
 
3
9
  __all__ = [
4
10
  "epics_signal_r",
5
11
  "epics_signal_rw",
12
+ "epics_signal_rw_rbv",
6
13
  "epics_signal_w",
7
14
  "epics_signal_x",
8
15
  ]
@@ -42,7 +42,7 @@ class HDFPanda(CommonPandaBlocks, StandardDetector):
42
42
  )
43
43
 
44
44
  async def connect(
45
- self, sim: bool = False, timeout: float = DEFAULT_TIMEOUT
45
+ self, mock: bool = False, timeout: float = DEFAULT_TIMEOUT
46
46
  ) -> None:
47
- await fill_pvi_entries(self, self._prefix + "PVI", timeout=timeout, sim=sim)
48
- await super().connect(sim=sim, timeout=timeout)
47
+ await fill_pvi_entries(self, self._prefix + "PVI", timeout=timeout, mock=mock)
48
+ await super().connect(mock=mock, timeout=timeout)
@@ -1,5 +1,9 @@
1
+ from .ensure_connected import ensure_connected
1
2
  from .prepare_trigger_and_dets import (
2
3
  prepare_static_seq_table_flyer_and_detectors_with_same_trigger,
3
4
  )
4
5
 
5
- __all__ = ["prepare_static_seq_table_flyer_and_detectors_with_same_trigger"]
6
+ __all__ = [
7
+ "prepare_static_seq_table_flyer_and_detectors_with_same_trigger",
8
+ "ensure_connected",
9
+ ]
@@ -0,0 +1,22 @@
1
+ import bluesky.plan_stubs as bps
2
+
3
+ from ophyd_async.core.device import Device
4
+ from ophyd_async.core.utils import DEFAULT_TIMEOUT, wait_for_connection
5
+
6
+
7
+ def ensure_connected(
8
+ *devices: Device,
9
+ mock: bool = False,
10
+ timeout: float = DEFAULT_TIMEOUT,
11
+ force_reconnect=False,
12
+ ):
13
+ yield from bps.wait_for(
14
+ [
15
+ lambda: wait_for_connection(
16
+ **{
17
+ device.name: device.connect(mock, timeout, force_reconnect)
18
+ for device in devices
19
+ }
20
+ )
21
+ ]
22
+ )
ophyd_async/protocols.py CHANGED
@@ -1,9 +1,20 @@
1
+ from __future__ import annotations
2
+
1
3
  from abc import abstractmethod
2
- from typing import Dict, Protocol, runtime_checkable
4
+ from typing import (
5
+ TYPE_CHECKING,
6
+ Any,
7
+ Dict,
8
+ Generic,
9
+ Protocol,
10
+ TypeVar,
11
+ runtime_checkable,
12
+ )
3
13
 
4
14
  from bluesky.protocols import DataKey, HasName, Reading
5
15
 
6
- from ophyd_async.core.async_status import AsyncStatus
16
+ if TYPE_CHECKING:
17
+ from ophyd_async.core.async_status import AsyncStatus
7
18
 
8
19
 
9
20
  @runtime_checkable
@@ -94,3 +105,22 @@ class AsyncStageable(Protocol):
94
105
  unstaging.
95
106
  """
96
107
  ...
108
+
109
+
110
+ C = TypeVar("C", contravariant=True)
111
+
112
+
113
+ class Watcher(Protocol, Generic[C]):
114
+ @staticmethod
115
+ def __call__(
116
+ *,
117
+ current: C,
118
+ initial: C,
119
+ target: C,
120
+ name: str | None,
121
+ unit: str | None,
122
+ precision: float | None,
123
+ fraction: float | None,
124
+ time_elapsed: float | None,
125
+ time_remaining: float | None,
126
+ ) -> Any: ...
@@ -1,13 +1,18 @@
1
1
  import asyncio
2
2
  import time
3
- from typing import Callable, List, Optional
3
+ from dataclasses import replace
4
4
 
5
5
  from bluesky.protocols import Movable, Stoppable
6
6
 
7
7
  from ophyd_async.core import StandardReadable
8
- from ophyd_async.core.async_status import AsyncStatus
9
- from ophyd_async.core.signal import soft_signal_r_and_backend, soft_signal_rw
8
+ from ophyd_async.core.async_status import AsyncStatus, WatchableAsyncStatus
9
+ from ophyd_async.core.signal import (
10
+ observe_value,
11
+ soft_signal_r_and_setter,
12
+ soft_signal_rw,
13
+ )
10
14
  from ophyd_async.core.standard_readable import ConfigSignal, HintedSignal
15
+ from ophyd_async.core.utils import WatcherUpdate
11
16
 
12
17
 
13
18
  class SimMotor(StandardReadable, Movable, Stoppable):
@@ -21,16 +26,16 @@ class SimMotor(StandardReadable, Movable, Stoppable):
21
26
  - instant: bool: whether to move instantly, or with a delay
22
27
  """
23
28
  with self.add_children_as_readables(HintedSignal):
24
- self.user_readback, self._user_readback = soft_signal_r_and_backend(
29
+ self.user_readback, self._user_readback_set = soft_signal_r_and_setter(
25
30
  float, 0
26
31
  )
27
32
 
28
33
  with self.add_children_as_readables(ConfigSignal):
29
34
  self.velocity = soft_signal_rw(float, 1.0)
30
- self.egu = soft_signal_rw(float, "mm")
35
+ self.egu = soft_signal_rw(str, "mm")
31
36
 
32
37
  self._instant = instant
33
- self._move_task: Optional[asyncio.Task] = None
38
+ self._move_status: AsyncStatus | None = None
34
39
 
35
40
  # Define some signals
36
41
  self.user_setpoint = soft_signal_rw(float, 0)
@@ -44,21 +49,37 @@ class SimMotor(StandardReadable, Movable, Stoppable):
44
49
  """
45
50
  Stop the motor if it is moving
46
51
  """
47
- if self._move_task:
48
- self._move_task.cancel()
49
- self._move_task = None
52
+ if self._move_status:
53
+ self._move_status.task.cancel()
54
+ self._move_status = None
55
+
56
+ async def trigger_callbacks():
57
+ await self.user_readback._backend.put(
58
+ await self.user_readback._backend.get_value()
59
+ )
60
+
61
+ asyncio.create_task(trigger_callbacks())
50
62
 
51
63
  self._set_success = success
52
64
 
53
- def set(self, new_position: float, timeout: Optional[float] = None) -> AsyncStatus: # noqa: F821
65
+ @WatchableAsyncStatus.wrap
66
+ async def set(self, new_position: float, timeout: float | None = None):
54
67
  """
55
68
  Asynchronously move the motor to a new position.
56
69
  """
57
- watchers: List[Callable] = []
58
- coro = asyncio.wait_for(self._move(new_position, watchers), timeout=timeout)
59
- return AsyncStatus(coro, watchers)
70
+ update, move_status = await self._move(new_position, timeout)
71
+ async for current_position in observe_value(
72
+ self.user_readback, done_status=move_status
73
+ ):
74
+ if not self._set_success:
75
+ raise RuntimeError("Motor was stopped")
76
+ yield replace(
77
+ update,
78
+ name=self.name,
79
+ current=current_position,
80
+ )
60
81
 
61
- async def _move(self, new_position: float, watchers: List[Callable] = []):
82
+ async def _move(self, new_position: float, timeout: float | None = None):
62
83
  """
63
84
  Start the motor moving to a new position.
64
85
 
@@ -67,6 +88,7 @@ class SimMotor(StandardReadable, Movable, Stoppable):
67
88
  """
68
89
  self.stop()
69
90
  start = time.monotonic()
91
+ self._set_success = True
70
92
 
71
93
  current_position = await self.user_readback.get_value()
72
94
  distance = abs(new_position - current_position)
@@ -84,7 +106,7 @@ class SimMotor(StandardReadable, Movable, Stoppable):
84
106
  # update position based on time elapsed
85
107
  if time_elapsed >= travel_time:
86
108
  # successfully reached our target position
87
- await self._user_readback.put(new_position)
109
+ self._user_readback_set(new_position)
88
110
  self._set_success = True
89
111
  break
90
112
  else:
@@ -92,27 +114,20 @@ class SimMotor(StandardReadable, Movable, Stoppable):
92
114
  old_position + distance * time_elapsed / travel_time
93
115
  )
94
116
 
95
- await self._user_readback.put(current_position)
96
-
97
- # notify watchers of the new position
98
- for watcher in watchers:
99
- watcher(
100
- name=self.name,
101
- current=current_position,
102
- initial=old_position,
103
- target=new_position,
104
- unit=units,
105
- time_elapsed=time.monotonic() - start,
106
- )
117
+ self._user_readback_set(current_position)
107
118
 
108
119
  # 10hz update loop
109
120
  await asyncio.sleep(0.1)
110
121
 
111
- # set up a task that updates the motor position at 10hz
112
- self._move_task = asyncio.create_task(update_position())
113
-
114
- try:
115
- await self._move_task
116
- finally:
117
- if not self._set_success:
118
- raise RuntimeError("Motor was stopped")
122
+ # set up a task that updates the motor position at ~10hz
123
+ self._move_status = AsyncStatus(asyncio.wait_for(update_position(), timeout))
124
+
125
+ return (
126
+ WatcherUpdate(
127
+ initial=old_position,
128
+ current=old_position,
129
+ target=new_position,
130
+ unit=units,
131
+ ),
132
+ self._move_status,
133
+ )
@@ -23,8 +23,8 @@ from event_model import (
23
23
  )
24
24
 
25
25
  from ophyd_async.core import DirectoryInfo, DirectoryProvider
26
+ from ophyd_async.core.mock_signal_backend import MockSignalBackend
26
27
  from ophyd_async.core.signal import SignalR, observe_value
27
- from ophyd_async.core.sim_signal_backend import SimSignalBackend
28
28
  from ophyd_async.core.utils import DEFAULT_TIMEOUT
29
29
 
30
30
  # raw data path
@@ -158,8 +158,8 @@ class PatternGenerator:
158
158
  self.written_images_counter: int = 0
159
159
 
160
160
  # it automatically initializes to 0
161
- self.signal_backend = SimSignalBackend(int)
162
- self.sim_signal = SignalR(self.signal_backend)
161
+ self.signal_backend = MockSignalBackend(int)
162
+ self.mock_signal = SignalR(self.signal_backend)
163
163
  blob = np.array(
164
164
  generate_gaussian_blob(width=detector_width, height=detector_height)
165
165
  * MAX_UINT8_VALUE
@@ -220,7 +220,7 @@ class PatternGenerator:
220
220
  async def open_file(
221
221
  self, directory: DirectoryProvider, multiplier: int = 1
222
222
  ) -> Dict[str, DataKey]:
223
- await self.sim_signal.connect()
223
+ await self.mock_signal.connect()
224
224
 
225
225
  self.target_path = self._get_new_path(directory)
226
226
 
@@ -314,5 +314,5 @@ class PatternGenerator:
314
314
  async def observe_indices_written(
315
315
  self, timeout=DEFAULT_TIMEOUT
316
316
  ) -> AsyncGenerator[int, None]:
317
- async for num_captured in observe_value(self.sim_signal, timeout=timeout):
317
+ async for num_captured in observe_value(self.mock_signal, timeout=timeout):
318
318
  yield num_captured // self.multiplier
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ophyd-async
3
- Version: 0.3a3
3
+ Version: 0.3a5
4
4
  Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
5
5
  Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -48,6 +48,7 @@ Requires-Dist: bluesky >=1.13.0a3
48
48
  Requires-Dist: event-model <1.21.0
49
49
  Requires-Dist: p4p
50
50
  Requires-Dist: pyyaml
51
+ Requires-Dist: colorlog
51
52
  Provides-Extra: ca
52
53
  Requires-Dist: aioca >=1.6 ; extra == 'ca'
53
54
  Provides-Extra: dev
@@ -85,7 +86,6 @@ Requires-Dist: sphinx-design ; extra == 'dev'
85
86
  Requires-Dist: tox-direct ; extra == 'dev'
86
87
  Requires-Dist: types-mock ; extra == 'dev'
87
88
  Requires-Dist: types-pyyaml ; extra == 'dev'
88
- Requires-Dist: colorlog ; extra == 'dev'
89
89
  Provides-Extra: pva
90
90
  Requires-Dist: p4p ; extra == 'pva'
91
91
 
@@ -1,64 +1,66 @@
1
1
  ophyd_async/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
2
2
  ophyd_async/__main__.py,sha256=G-Zcv_G9zK7Nhx6o5L5w-wyhMxdl_WgyMELu8IMFqAE,328
3
- ophyd_async/_version.py,sha256=hJ-uDF6qfItINzjClbnbKB7a1O2myzhQQHmhtpj1sL0,408
3
+ ophyd_async/_version.py,sha256=U12czQTgzf6ojb0_kN2Mdxwd3eohytfYDRR6gcj6mEw,408
4
4
  ophyd_async/log.py,sha256=DbMjt0bkfUOLHIinZYt0Q0FHZmCXXi5x8y0uFiEmqoQ,3587
5
- ophyd_async/protocols.py,sha256=48jqS78KAMvy6LmenL21ARoTAD8oOL9YdVmIlI0E0VA,2890
6
- ophyd_async/core/__init__.py,sha256=3GBJlwSkAH_zv4KhKLsxFxGPUuyOoJj2fTSbG6vOd6w,2496
5
+ ophyd_async/protocols.py,sha256=EF2W9nfElV-0QNMYrX1zusL1PqDJR3kNsjlalR29j0I,3412
6
+ ophyd_async/core/__init__.py,sha256=YMFc7rJhfq6waLMmHTCD6BVqUM_jM7joPGEoxUued7g,2893
7
7
  ophyd_async/core/_providers.py,sha256=LrlTMPHKXWOPVkpAOw-pqBq0kip-c3C9ZZPoFfiaV4M,2212
8
- ophyd_async/core/async_status.py,sha256=-sfIf7VhwAP25kSVwKZjAIYOTROpfnh2jgkDw5_afSU,2801
9
- ophyd_async/core/detector.py,sha256=OkdaaJnj2v8DKF4k7VsTo8ReAvIzyFjBqbqdiYf7FBE,11179
10
- ophyd_async/core/device.py,sha256=Bm8u1wEN6PuJgCgis_msVRvfrO1_RumxAIMPag8k-cI,5813
8
+ ophyd_async/core/async_status.py,sha256=h6IZUoSeGfuiMT_CAIR-nzHeTJH0srvSpiqOQtxHMnw,5229
9
+ ophyd_async/core/detector.py,sha256=j4MRENoe3En4a-3gNpfQXvBgFC4besfcczoP98QOclc,11003
10
+ ophyd_async/core/device.py,sha256=_0COEm9x35hmnBb-X5z_q8xnGwfzOgunAovtPWR5yik,7118
11
11
  ophyd_async/core/device_save_loader.py,sha256=RXA3dPUPihAR2ZGDStlGiA-TAsr_xqL0snsCjMsMnfA,9138
12
12
  ophyd_async/core/flyer.py,sha256=LfO3EQTW2zMeNqZh8TLXvE92E30Duds2RXskRYAdJ_4,2299
13
- ophyd_async/core/signal.py,sha256=S91oRS6E9zNNMV-Mpa7wqTt24IfFI22Vui9MhDQdxys,14523
13
+ ophyd_async/core/mock_signal_backend.py,sha256=13BAbQG1OPC3o_fOFFQH4x1mPYLQ8Zf53WviRPXWDTM,2938
14
+ ophyd_async/core/mock_signal_utils.py,sha256=umWf42HHWyUCYLVYnj5weh4pNBMpN1ElRTsxKsc4q_k,4287
15
+ ophyd_async/core/signal.py,sha256=57z_-B9BDTCX0BwL63VnyBsBlBqWb6ltFLP9bPiYISE,16081
14
16
  ophyd_async/core/signal_backend.py,sha256=qDdWz8X4CWStuYknxcj4G76BLq4TzrAIyZO1NOEq9ao,1519
15
- ophyd_async/core/sim_signal_backend.py,sha256=jpCIp-93HraG_rbL1C2CYbZqyQMUpT1fnT4WX24Ihno,6057
17
+ ophyd_async/core/soft_signal_backend.py,sha256=56zvcEi4c8n1yYbafTbp7X0VhSkhoehm3L8RBhu2fik,5596
16
18
  ophyd_async/core/standard_readable.py,sha256=uVG3vs3s7-Kzg5dRCtT4I2mhZPqwVGYy2dxNmaOpDVU,8980
17
- ophyd_async/core/utils.py,sha256=AVF5e42CVG_GaLoHJSI82iC4KAO60fb9fEJMISHBCNM,5043
19
+ ophyd_async/core/utils.py,sha256=OMOpa-5QMAGQbbb0tFD4lRnyk0Fykq4aD2EOQbPt39c,5516
18
20
  ophyd_async/epics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
21
  ophyd_async/epics/_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- ophyd_async/epics/_backend/_aioca.py,sha256=91BynQ2sXgK6WvjzgOmaxH7oHBNBHFVfpX3dOt4jo8o,8775
21
- ophyd_async/epics/_backend/_p4p.py,sha256=9TEDa1VzDwuOgPKl3jYOXQ9ysd60_Ri2ymepwdgZjNk,12202
22
- ophyd_async/epics/_backend/common.py,sha256=o0heeQEM7aP-QYCicwOEtNHs5c5OD6raR-5cTs9yRX0,840
23
- ophyd_async/epics/areadetector/__init__.py,sha256=zz6T9nLSBExYjllJGUVFWGsS7m3C680UHbWIjBl9Fn8,556
24
- ophyd_async/epics/areadetector/aravis.py,sha256=ujO82hYZ5D5GIaBhz0JNC2G5uVSgowY8xxsY2tunzi4,2277
22
+ ophyd_async/epics/_backend/_aioca.py,sha256=cpPNZmRMi7FnAh2-3ec5uklLVFOqsmEmpI1nh5Ud1Ls,8794
23
+ ophyd_async/epics/_backend/_p4p.py,sha256=lIKx7kQ2o8h3M4wPwrq8JBo8xuDnasJxpDH2ATVBY78,12257
24
+ ophyd_async/epics/_backend/common.py,sha256=16mAuxDwA3eZFjUW8DHMabaW3CtEI0Qe8DLpP2xlW7Y,814
25
+ ophyd_async/epics/areadetector/__init__.py,sha256=ViKzx-wUxkRyNR33wfpL11QB97o0J47_KMyI2C_NphI,510
26
+ ophyd_async/epics/areadetector/aravis.py,sha256=YklN4V0loqUQBs4swVX304N49JIGPvrNOk8iA5EWofg,2127
25
27
  ophyd_async/epics/areadetector/kinetix.py,sha256=7rE2MLnz9DEmeiN9pCekDfpXuZ2DErnMajRp_9eoLZY,1359
26
28
  ophyd_async/epics/areadetector/pilatus.py,sha256=ki-BOBCEIiUD2wAtmujBIB1eX-nbXB4yMLJK_Q3opRM,1398
27
29
  ophyd_async/epics/areadetector/single_trigger_det.py,sha256=U92dqhioIfnve3jtCThq9gXBCdEzzqzY4ezk6rZV19g,1182
28
- ophyd_async/epics/areadetector/utils.py,sha256=dez54oElIkGMnhSM9qghToUB1opSqjdWTV2vhHCgRMA,3133
30
+ ophyd_async/epics/areadetector/utils.py,sha256=p66UbVdKRFj6Sm1Qvm23kmlVyBMMqIvXFxA3x17YnSk,2824
29
31
  ophyd_async/epics/areadetector/vimba.py,sha256=IxG8KLzfb84iLtzf6ZoX9JikqZLP49lwkWu33bkDV9Y,1291
30
32
  ophyd_async/epics/areadetector/controllers/__init__.py,sha256=af58ci7X2z2s_FyUwR3IGQrws8q4TKcBw7vFyIS5FoI,217
31
33
  ophyd_async/epics/areadetector/controllers/ad_sim_controller.py,sha256=mthZ6WxajMEgUKptq3bnkIctbLhjzTagV66i1auB8cg,1587
32
- ophyd_async/epics/areadetector/controllers/aravis_controller.py,sha256=vRiSexnFzijG8eEwowMAFIe730xFNMmgjjbXQVi4zrc,2394
34
+ ophyd_async/epics/areadetector/controllers/aravis_controller.py,sha256=CIfnZdq_NobO_UMC2TJoAfUEP9GlzZg5z5bz6Dn1DxY,2669
33
35
  ophyd_async/epics/areadetector/controllers/kinetix_controller.py,sha256=9QmydX85QOXfQL_UX49M9EQ2b2hUZPVzLxgGQn-A9Oc,1611
34
36
  ophyd_async/epics/areadetector/controllers/pilatus_controller.py,sha256=cd1CKkaXlwkpQ0I1VL7nN0U8R4VweTsa08WhvHYI4nY,2243
35
37
  ophyd_async/epics/areadetector/controllers/vimba_controller.py,sha256=Eh4Hr9rWgq1mKvE93JzgixntjPHxF3_07GTFqiOdZqE,2123
36
38
  ophyd_async/epics/areadetector/drivers/__init__.py,sha256=-Ib0Lz4fFQQmB7K0uFxMDvAerkLxadMQERH7lNAvrs4,495
37
- ophyd_async/epics/areadetector/drivers/ad_base.py,sha256=ikfyNcZwJa5ah52DckjrBzkMMT_eDY1smM4XWfb6A6E,3689
38
- ophyd_async/epics/areadetector/drivers/aravis_driver.py,sha256=Z96xXKfGJbLYehyy0wmP3mCW5lVRmdypmX-9U8cYbD8,5607
39
- ophyd_async/epics/areadetector/drivers/kinetix_driver.py,sha256=OPl42jZcUPs0l3iUr8Cgr3yswWcZ5MJEqhNS9LKv8Jg,640
40
- ophyd_async/epics/areadetector/drivers/pilatus_driver.py,sha256=fc3vNHqop9oLg-fvaU-diQNEV5U1qzA9vX2T8Hwy_E8,478
41
- ophyd_async/epics/areadetector/drivers/vimba_driver.py,sha256=jAoQJQV1fOwF-hwi-Y9YLYUuE00bhQ-tc8t7-K5-8VI,1546
39
+ ophyd_async/epics/areadetector/drivers/ad_base.py,sha256=cE7I-IsfQz3UR9yqghy4czAxHeHERTTKe080GB9sCFQ,3847
40
+ ophyd_async/epics/areadetector/drivers/aravis_driver.py,sha256=PmIygsVNoxxYHvZZzFAbAm2DXmXFc13nAzL_DJB6YSU,1464
41
+ ophyd_async/epics/areadetector/drivers/kinetix_driver.py,sha256=yIV23BkGBJ4i0VskLiLL7AFbadCCR6Ch1UwUDJ9r2YM,743
42
+ ophyd_async/epics/areadetector/drivers/pilatus_driver.py,sha256=0DsUu9vAPXDa2v8_V0f_kPjBtLu3y4_EkmFfFjYO4Gk,553
43
+ ophyd_async/epics/areadetector/drivers/vimba_driver.py,sha256=J54VtWkOklfbSqZYxGWH1e6Uzm9_Gph_ZbCf9Zax0LU,1713
42
44
  ophyd_async/epics/areadetector/writers/__init__.py,sha256=tpPcrYd1hs8WS7C0gmCnR2EBwjE5RzCljI7WwZ2V_LM,191
43
45
  ophyd_async/epics/areadetector/writers/_hdfdataset.py,sha256=E0C9VgsPyY35h7k0mvcIhjsIVNavApLxizqNWlM388w,167
44
46
  ophyd_async/epics/areadetector/writers/_hdffile.py,sha256=YtUgOKX53m0TaFEGBW671qXqNuuEKxEyLV5Ein1fjvo,1799
45
47
  ophyd_async/epics/areadetector/writers/hdf_writer.py,sha256=e7EbusP3Ell-2npdLtDWcZ_kDIRidUwHeqcbeMx4mlU,5427
46
- ophyd_async/epics/areadetector/writers/nd_file_hdf.py,sha256=-wfaAJf7pPVHWJ5fEYX8ZR0tIq9-MjZAn_2MjXClL9I,1626
47
- ophyd_async/epics/areadetector/writers/nd_plugin.py,sha256=l0yBBEazviyFsWJv_4_sfGn_YM_Iyd0_SlMdAmUlXDU,871
48
- ophyd_async/epics/demo/__init__.py,sha256=D-jYrorqa5C3gLzIi2Hkn8f8uaE9wb5S-WX3YYuHV48,6052
48
+ ophyd_async/epics/areadetector/writers/nd_file_hdf.py,sha256=whKDkvKnU1qiDym4xQq4Fd1jHEhtDu552xhhGSnB--w,1910
49
+ ophyd_async/epics/areadetector/writers/nd_plugin.py,sha256=sG4XZAS_k065g88n9U3IJGtYI4PPHfyJMcVqh9hVAa4,979
50
+ ophyd_async/epics/demo/__init__.py,sha256=8NetaM610KGlVa5QeM47c9KoWkG7GvXoepd8txf6MGU,5598
49
51
  ophyd_async/epics/demo/demo_ad_sim_detector.py,sha256=06y65yvaqXvL2rDocjYyLz9kTVzuwV-LeuPhEfExdOA,944
50
52
  ophyd_async/epics/demo/mover.db,sha256=RFz0rxZue689Wh1sWTZwWeFMUrH04ttPq2u5xJH_Fp4,998
51
53
  ophyd_async/epics/demo/sensor.db,sha256=AVtiydrdtwAz2EFurO2Ult9SSRtre3r0akOBbL98LT0,554
52
54
  ophyd_async/epics/motion/__init__.py,sha256=tnmVRIwKa9PdN_xonJdAUD04UpEceh-hoD7XI62yDB0,46
53
- ophyd_async/epics/motion/motor.py,sha256=_670QAtrD4ZJI41inTOPEBEPxWviJH1iflI1-KLHz30,3745
55
+ ophyd_async/epics/motion/motor.py,sha256=ZiyC0WvO9AAsv_FmYBaCmOYQ86yZIS3QnSxfyPUg5jE,3504
54
56
  ophyd_async/epics/pvi/__init__.py,sha256=TbOQNY4enQWgtr1T7x129vpo2p7FIFlr8cyZqqv5Lk4,158
55
- ophyd_async/epics/pvi/pvi.py,sha256=hpn7GeO0xk_-UDoy42LIsi0adER9IZO3HPP2iu6Nmu4,11320
56
- ophyd_async/epics/signal/__init__.py,sha256=wb93RTqvSbGKVFQj8OHykbVLGLmwKHU72oi5xYu2UaY,188
57
+ ophyd_async/epics/pvi/pvi.py,sha256=PJdY3rCRyIQbsbHDru-TJ-IVOItyaQwCQKAC0Widu6A,11363
58
+ ophyd_async/epics/signal/__init__.py,sha256=JXKBSGpRL9y3auh27JRxsqDn_rBOXpJjtd4nCuDOX2g,261
57
59
  ophyd_async/epics/signal/_epics_transport.py,sha256=DEIL0iYUAWssysVEgWGu1fHSM1l-ATV2kjUgPtDN9LY,858
58
60
  ophyd_async/epics/signal/signal.py,sha256=M8ZVG_zLdYJfroCRX-u_w8c3yIhswSRw8e3RkW2szio,3166
59
61
  ophyd_async/panda/__init__.py,sha256=ZaD1nRgGKAGFGdpP1WWF-FnX3wcGuYqqq0QRZbaSBYQ,692
60
62
  ophyd_async/panda/_common_blocks.py,sha256=n0PPc1rar43oDSIA-yNubTc8fR5YCW1tyjQU58whsg0,1038
61
- ophyd_async/panda/_hdf_panda.py,sha256=zZxIdNIXHwjlZA-HTezQNfcCh98P2Pst6Pcld92rPLM,1414
63
+ ophyd_async/panda/_hdf_panda.py,sha256=QjfZyYos0ZBlIqBiZ5UbyEd_wuh_cGzwV8QE9jvLiIY,1419
62
64
  ophyd_async/panda/_panda_controller.py,sha256=dIqcjmaIHVrki8UXSoDx46kk6I2Lhpe2o3sXNg5f-RQ,1238
63
65
  ophyd_async/panda/_table.py,sha256=dLoRP4zYNOkD_s0Vkp2wVYAwkjVG8nNdf8-FaXOTfPo,5655
64
66
  ophyd_async/panda/_trigger.py,sha256=tBH8uq_4o1ASG9yofVxq3tjf5v8LPzniDTRL4yjramI,1195
@@ -66,18 +68,19 @@ ophyd_async/panda/_utils.py,sha256=VHW5kPVISyEkmse_qQcyisBkkEwMO6GG2Ago-CH1AFA,4
66
68
  ophyd_async/panda/writers/__init__.py,sha256=xy7BguVQG4HNIDBfKPjMj0KQo1tptC9LbCpEuMcVGaM,70
67
69
  ophyd_async/panda/writers/_hdf_writer.py,sha256=_KlawqQHuWXLCvhGg1N6S4dQ8LhM88NbHsbXryxPvPA,7617
68
70
  ophyd_async/panda/writers/_panda_hdf_file.py,sha256=42iHaTax4JjOBpNC7d4nkNL9SM14OTnFPTIcXv2jg-4,1759
69
- ophyd_async/planstubs/__init__.py,sha256=G9B80_d87lnOThUsGbAYPqzMw9xDelq2TbS7dkB692o,188
71
+ ophyd_async/planstubs/__init__.py,sha256=T2ICLREJv0uUgGRQbxk2w57TZ7jf7wYWB6TBY22cqnc,266
72
+ ophyd_async/planstubs/ensure_connected.py,sha256=1MkDu8UqVRPHLnW9IXRn-QvKiG8-rCV8T4KDbjf9K6w,557
70
73
  ophyd_async/planstubs/prepare_trigger_and_dets.py,sha256=0c4XDAxVkSanyDKtaMda0VgPEbk2jM0geVzAx707DhI,1772
71
74
  ophyd_async/sim/__init__.py,sha256=ScjH1g7FMo5yPACfJRZE6xGBWCHU4bKDzNQk1tqObnA,366
72
- ophyd_async/sim/pattern_generator.py,sha256=cnHL9PEDrN1BTomLhGgPTWTnQIswNuYpU8AE9I1wi3g,10634
75
+ ophyd_async/sim/pattern_generator.py,sha256=pvSk2zb82D08j2jiKAMqMAfRohGnYd_rpjUraLrCD6c,10640
73
76
  ophyd_async/sim/sim_pattern_detector_control.py,sha256=Ypz8IuRYAY2J243IhVbNyGr_Z-XtpJZ1qxma6NR3TgM,1838
74
77
  ophyd_async/sim/sim_pattern_detector_writer.py,sha256=ESpcVyHd1TP7Cojznv2hJAwLinu3XbgAiVKfX12FCII,1237
75
78
  ophyd_async/sim/sim_pattern_generator.py,sha256=fbcwWxTPYKLK33OzIY15vGylnonOO8HIudz1y_56GZU,1336
76
79
  ophyd_async/sim/demo/__init__.py,sha256=9mxKpslrL89cfSj4g3og8Br3O--pMj3hhWZS-Xu6kyA,56
77
- ophyd_async/sim/demo/sim_motor.py,sha256=uiMPV76JkFEVJkejECdpUNBygauaoPp11Ynb0N1TrD0,4075
78
- ophyd_async-0.3a3.dist-info/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
79
- ophyd_async-0.3a3.dist-info/METADATA,sha256=Iw5ewVCui6t0KJzvVsbZbiMKu8V4WOwoNAFQ4fQtd1w,6301
80
- ophyd_async-0.3a3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
81
- ophyd_async-0.3a3.dist-info/entry_points.txt,sha256=O0YNJTEufO0w9BozXi-JurTy2U1_o0ypeCgJLQ727Jk,58
82
- ophyd_async-0.3a3.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
83
- ophyd_async-0.3a3.dist-info/RECORD,,
80
+ ophyd_async/sim/demo/sim_motor.py,sha256=gtWYn_zs43XahpzNey0or2PDhoB78fZIVl767HnE-kU,4352
81
+ ophyd_async-0.3a5.dist-info/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
82
+ ophyd_async-0.3a5.dist-info/METADATA,sha256=39ilqICk5TpmGcGnsJcpXzJjl0NV87VvpOPf2vUez80,6284
83
+ ophyd_async-0.3a5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
84
+ ophyd_async-0.3a5.dist-info/entry_points.txt,sha256=O0YNJTEufO0w9BozXi-JurTy2U1_o0ypeCgJLQ727Jk,58
85
+ ophyd_async-0.3a5.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
86
+ ophyd_async-0.3a5.dist-info/RECORD,,