ophyd-async 0.1.0__py3-none-any.whl → 0.3.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 (94) hide show
  1. ophyd_async/__init__.py +1 -4
  2. ophyd_async/_version.py +2 -2
  3. ophyd_async/core/__init__.py +91 -19
  4. ophyd_async/core/_providers.py +68 -0
  5. ophyd_async/core/async_status.py +90 -42
  6. ophyd_async/core/detector.py +341 -0
  7. ophyd_async/core/device.py +226 -0
  8. ophyd_async/core/device_save_loader.py +286 -0
  9. ophyd_async/core/flyer.py +85 -0
  10. ophyd_async/core/mock_signal_backend.py +82 -0
  11. ophyd_async/core/mock_signal_utils.py +145 -0
  12. ophyd_async/core/{_device/_signal/signal.py → signal.py} +249 -61
  13. ophyd_async/core/{_device/_backend/signal_backend.py → signal_backend.py} +12 -5
  14. ophyd_async/core/{_device/_backend/sim_signal_backend.py → soft_signal_backend.py} +54 -48
  15. ophyd_async/core/standard_readable.py +261 -0
  16. ophyd_async/core/utils.py +127 -30
  17. ophyd_async/epics/_backend/_aioca.py +62 -43
  18. ophyd_async/epics/_backend/_p4p.py +100 -52
  19. ophyd_async/epics/_backend/common.py +25 -0
  20. ophyd_async/epics/areadetector/__init__.py +16 -15
  21. ophyd_async/epics/areadetector/aravis.py +63 -0
  22. ophyd_async/epics/areadetector/controllers/__init__.py +5 -0
  23. ophyd_async/epics/areadetector/controllers/ad_sim_controller.py +52 -0
  24. ophyd_async/epics/areadetector/controllers/aravis_controller.py +78 -0
  25. ophyd_async/epics/areadetector/controllers/kinetix_controller.py +49 -0
  26. ophyd_async/epics/areadetector/controllers/pilatus_controller.py +61 -0
  27. ophyd_async/epics/areadetector/controllers/vimba_controller.py +66 -0
  28. ophyd_async/epics/areadetector/drivers/__init__.py +21 -0
  29. ophyd_async/epics/areadetector/drivers/ad_base.py +107 -0
  30. ophyd_async/epics/areadetector/drivers/aravis_driver.py +38 -0
  31. ophyd_async/epics/areadetector/drivers/kinetix_driver.py +27 -0
  32. ophyd_async/epics/areadetector/drivers/pilatus_driver.py +21 -0
  33. ophyd_async/epics/areadetector/drivers/vimba_driver.py +63 -0
  34. ophyd_async/epics/areadetector/kinetix.py +46 -0
  35. ophyd_async/epics/areadetector/pilatus.py +45 -0
  36. ophyd_async/epics/areadetector/single_trigger_det.py +18 -10
  37. ophyd_async/epics/areadetector/utils.py +91 -13
  38. ophyd_async/epics/areadetector/vimba.py +43 -0
  39. ophyd_async/epics/areadetector/writers/__init__.py +5 -0
  40. ophyd_async/epics/areadetector/writers/_hdfdataset.py +10 -0
  41. ophyd_async/epics/areadetector/writers/_hdffile.py +54 -0
  42. ophyd_async/epics/areadetector/writers/hdf_writer.py +142 -0
  43. ophyd_async/epics/areadetector/writers/nd_file_hdf.py +40 -0
  44. ophyd_async/epics/areadetector/writers/nd_plugin.py +38 -0
  45. ophyd_async/epics/demo/__init__.py +78 -51
  46. ophyd_async/epics/demo/demo_ad_sim_detector.py +35 -0
  47. ophyd_async/epics/motion/motor.py +67 -52
  48. ophyd_async/epics/pvi/__init__.py +3 -0
  49. ophyd_async/epics/pvi/pvi.py +318 -0
  50. ophyd_async/epics/signal/__init__.py +8 -3
  51. ophyd_async/epics/signal/signal.py +27 -10
  52. ophyd_async/log.py +130 -0
  53. ophyd_async/panda/__init__.py +24 -7
  54. ophyd_async/panda/_common_blocks.py +49 -0
  55. ophyd_async/panda/_hdf_panda.py +48 -0
  56. ophyd_async/panda/_panda_controller.py +37 -0
  57. ophyd_async/panda/_table.py +158 -0
  58. ophyd_async/panda/_trigger.py +39 -0
  59. ophyd_async/panda/_utils.py +15 -0
  60. ophyd_async/panda/writers/__init__.py +3 -0
  61. ophyd_async/panda/writers/_hdf_writer.py +220 -0
  62. ophyd_async/panda/writers/_panda_hdf_file.py +58 -0
  63. ophyd_async/plan_stubs/__init__.py +13 -0
  64. ophyd_async/plan_stubs/ensure_connected.py +22 -0
  65. ophyd_async/plan_stubs/fly.py +149 -0
  66. ophyd_async/protocols.py +126 -0
  67. ophyd_async/sim/__init__.py +11 -0
  68. ophyd_async/sim/demo/__init__.py +3 -0
  69. ophyd_async/sim/demo/sim_motor.py +103 -0
  70. ophyd_async/sim/pattern_generator.py +318 -0
  71. ophyd_async/sim/sim_pattern_detector_control.py +55 -0
  72. ophyd_async/sim/sim_pattern_detector_writer.py +34 -0
  73. ophyd_async/sim/sim_pattern_generator.py +37 -0
  74. {ophyd_async-0.1.0.dist-info → ophyd_async-0.3.0.dist-info}/METADATA +35 -67
  75. ophyd_async-0.3.0.dist-info/RECORD +86 -0
  76. {ophyd_async-0.1.0.dist-info → ophyd_async-0.3.0.dist-info}/WHEEL +1 -1
  77. ophyd_async/core/_device/__init__.py +0 -0
  78. ophyd_async/core/_device/_backend/__init__.py +0 -0
  79. ophyd_async/core/_device/_signal/__init__.py +0 -0
  80. ophyd_async/core/_device/device.py +0 -60
  81. ophyd_async/core/_device/device_collector.py +0 -121
  82. ophyd_async/core/_device/device_vector.py +0 -14
  83. ophyd_async/core/_device/standard_readable.py +0 -72
  84. ophyd_async/epics/areadetector/ad_driver.py +0 -18
  85. ophyd_async/epics/areadetector/directory_provider.py +0 -18
  86. ophyd_async/epics/areadetector/hdf_streamer_det.py +0 -167
  87. ophyd_async/epics/areadetector/nd_file_hdf.py +0 -22
  88. ophyd_async/epics/areadetector/nd_plugin.py +0 -13
  89. ophyd_async/epics/signal/pvi_get.py +0 -22
  90. ophyd_async/panda/panda.py +0 -332
  91. ophyd_async-0.1.0.dist-info/RECORD +0 -45
  92. {ophyd_async-0.1.0.dist-info → ophyd_async-0.3.0.dist-info}/LICENSE +0 -0
  93. {ophyd_async-0.1.0.dist-info → ophyd_async-0.3.0.dist-info}/entry_points.txt +0 -0
  94. {ophyd_async-0.1.0.dist-info → ophyd_async-0.3.0.dist-info}/top_level.txt +0 -0
@@ -1,332 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import atexit
4
- import re
5
- from enum import Enum
6
- from typing import (
7
- Callable,
8
- Dict,
9
- FrozenSet,
10
- Optional,
11
- Sequence,
12
- Tuple,
13
- Type,
14
- TypedDict,
15
- cast,
16
- get_args,
17
- get_origin,
18
- get_type_hints,
19
- )
20
-
21
- import numpy as np
22
- import numpy.typing as npt
23
- from p4p.client.thread import Context
24
-
25
- from ophyd_async.core import (
26
- Device,
27
- DeviceVector,
28
- Signal,
29
- SignalBackend,
30
- SignalR,
31
- SignalRW,
32
- SignalX,
33
- SimSignalBackend,
34
- )
35
- from ophyd_async.epics.signal import (
36
- epics_signal_r,
37
- epics_signal_rw,
38
- epics_signal_w,
39
- epics_signal_x,
40
- pvi_get,
41
- )
42
-
43
-
44
- class PulseBlock(Device):
45
- delay: SignalRW[float]
46
- width: SignalRW[float]
47
-
48
-
49
- class SeqTrigger(Enum):
50
- IMMEDIATE = "Immediate"
51
- BITA_0 = "BITA=0"
52
- BITA_1 = "BITA=1"
53
- BITB_0 = "BITB=0"
54
- BITB_1 = "BITB=1"
55
- BITC_0 = "BITC=0"
56
- BITC_1 = "BITC=1"
57
- POSA_GT = "POSA>=POSITION"
58
- POSA_LT = "POSA<=POSITION"
59
- POSB_GT = "POSB>=POSITION"
60
- POSB_LT = "POSB<=POSITION"
61
- POSC_GT = "POSC>=POSITION"
62
- POSC_LT = "POSC<=POSITION"
63
-
64
-
65
- class SeqTable(TypedDict):
66
- repeats: npt.NDArray[np.uint16]
67
- trigger: Sequence[SeqTrigger]
68
- position: npt.NDArray[np.int32]
69
- time1: npt.NDArray[np.uint32]
70
- outa1: npt.NDArray[np.bool_]
71
- outb1: npt.NDArray[np.bool_]
72
- outc1: npt.NDArray[np.bool_]
73
- outd1: npt.NDArray[np.bool_]
74
- oute1: npt.NDArray[np.bool_]
75
- outf1: npt.NDArray[np.bool_]
76
- time2: npt.NDArray[np.uint32]
77
- outa2: npt.NDArray[np.bool_]
78
- outb2: npt.NDArray[np.bool_]
79
- outc2: npt.NDArray[np.bool_]
80
- outd2: npt.NDArray[np.bool_]
81
- oute2: npt.NDArray[np.bool_]
82
- outf2: npt.NDArray[np.bool_]
83
-
84
-
85
- class SeqBlock(Device):
86
- table: SignalRW[SeqTable]
87
-
88
-
89
- class PcapBlock(Device):
90
- active: SignalR[bool]
91
-
92
-
93
- class PVIEntry(TypedDict, total=False):
94
- d: str
95
- r: str
96
- rw: str
97
- w: str
98
- x: str
99
-
100
-
101
- def _block_name_number(block_name: str) -> Tuple[str, Optional[int]]:
102
- """Maps a panda block name to a block and number.
103
-
104
- There are exceptions to this rule; some blocks like pcap do not contain numbers.
105
- Other blocks may contain numbers and letters, but no numbers at the end.
106
-
107
- Such block names will only return the block name, and not a number.
108
-
109
- If this function returns both a block name and number, it should be instantiated
110
- into a device vector."""
111
- m = re.match("^([0-9a-z_-]*)([0-9]+)$", block_name)
112
- if m is not None:
113
- name, num = m.groups()
114
- return name, int(num or 1) # just to pass type checks.
115
-
116
- return block_name, None
117
-
118
-
119
- def _remove_inconsistent_blocks(pvi_info: Dict[str, PVIEntry]) -> None:
120
- """Remove blocks from pvi information.
121
-
122
- This is needed because some pandas have 'pcap' and 'pcap1' blocks, which are
123
- inconsistent with the assumption that pandas should only have a 'pcap' block,
124
- for example.
125
-
126
- """
127
- pvi_keys = set(pvi_info.keys())
128
- for k in pvi_keys:
129
- kn = re.sub(r"\d*$", "", k)
130
- if kn and k != kn and kn in pvi_keys:
131
- del pvi_info[k]
132
-
133
-
134
- async def pvi(pv: str, ctxt: Context, timeout: float = 5.0) -> Dict[str, PVIEntry]:
135
- result = await pvi_get(pv, ctxt, timeout=timeout)
136
- _remove_inconsistent_blocks(result)
137
- return result
138
-
139
-
140
- class PandA(Device):
141
- _ctxt: Optional[Context] = None
142
-
143
- pulse: DeviceVector[PulseBlock]
144
- seq: DeviceVector[SeqBlock]
145
- pcap: PcapBlock
146
-
147
- def __init__(self, pv: str) -> None:
148
- self._init_prefix = pv
149
- self.pvi_mapping: Dict[FrozenSet[str], Callable[..., Signal]] = {
150
- frozenset({"r", "w"}): lambda dtype, rpv, wpv: epics_signal_rw(
151
- dtype, rpv, wpv
152
- ),
153
- frozenset({"rw"}): lambda dtype, rpv, wpv: epics_signal_rw(dtype, rpv, wpv),
154
- frozenset({"r"}): lambda dtype, rpv, wpv: epics_signal_r(dtype, rpv),
155
- frozenset({"w"}): lambda dtype, rpv, wpv: epics_signal_w(dtype, wpv),
156
- frozenset({"x"}): lambda dtype, rpv, wpv: epics_signal_x(wpv),
157
- }
158
-
159
- @property
160
- def ctxt(self) -> Context:
161
- if PandA._ctxt is None:
162
- PandA._ctxt = Context("pva", nt=False)
163
-
164
- @atexit.register
165
- def _del_ctxt():
166
- # If we don't do this we get messages like this on close:
167
- # Error in sys.excepthook:
168
- # Original exception was:
169
- PandA._ctxt = None
170
-
171
- return PandA._ctxt
172
-
173
- def verify_block(self, name: str, num: Optional[int]):
174
- """Given a block name and number, return information about a block."""
175
- anno = get_type_hints(self, globalns=globals()).get(name)
176
-
177
- block: Device = Device()
178
-
179
- if anno:
180
- type_args = get_args(anno)
181
- block = type_args[0]() if type_args else anno()
182
-
183
- if not type_args:
184
- assert num is None, f"Only expected one {name} block, got {num}"
185
-
186
- return block
187
-
188
- async def _make_block(
189
- self, name: str, num: Optional[int], block_pv: str, sim: bool = False
190
- ):
191
- """Makes a block given a block name containing relevant signals.
192
-
193
- Loops through the signals in the block (found using type hints), if not in
194
- sim mode then does a pvi call, and identifies this signal from the pvi call.
195
- """
196
- block = self.verify_block(name, num)
197
-
198
- field_annos = get_type_hints(block, globalns=globals())
199
- block_pvi = await pvi(block_pv, self.ctxt) if not sim else None
200
-
201
- # finds which fields this class actually has, e.g. delay, width...
202
- for sig_name, sig_type in field_annos.items():
203
- origin = get_origin(sig_type)
204
- args = get_args(sig_type)
205
-
206
- # if not in sim mode,
207
- if block_pvi:
208
- block_pvi = cast(Dict[str, PVIEntry], block_pvi)
209
- # try to get this block in the pvi.
210
- entry: Optional[PVIEntry] = block_pvi.get(sig_name)
211
- if entry is None:
212
- raise Exception(
213
- f"{self.__class__.__name__} has a {name} block containing a/"
214
- + f"an {sig_name} signal which has not been retrieved by PVI."
215
- )
216
-
217
- signal = self._make_signal(entry, args[0] if len(args) > 0 else None)
218
-
219
- else:
220
- backend: SignalBackend = SimSignalBackend(
221
- args[0] if len(args) > 0 else None, block_pv
222
- )
223
- signal = SignalX(backend) if not origin else origin(backend)
224
-
225
- setattr(block, sig_name, signal)
226
-
227
- # checks for any extra pvi information not contained in this class
228
- if block_pvi:
229
- for attr, attr_pvi in block_pvi.items():
230
- if not hasattr(block, attr):
231
- # makes any extra signals
232
- signal = self._make_signal(attr_pvi)
233
- setattr(block, attr, signal)
234
-
235
- return block
236
-
237
- async def _make_untyped_block(self, block_pv: str):
238
- """Populates a block using PVI information.
239
-
240
- This block is not typed as part of the PandA interface but needs to be
241
- included dynamically anyway.
242
- """
243
- block = Device()
244
- block_pvi: Dict[str, PVIEntry] = await pvi(block_pv, self.ctxt)
245
-
246
- for signal_name, signal_pvi in block_pvi.items():
247
- signal = self._make_signal(signal_pvi)
248
- setattr(block, signal_name, signal)
249
-
250
- return block
251
-
252
- def _make_signal(self, signal_pvi: PVIEntry, dtype: Optional[Type] = None):
253
- """Make a signal.
254
-
255
- This assumes datatype is None so it can be used to create dynamic signals.
256
- """
257
- operations = frozenset(signal_pvi.keys())
258
- pvs = [signal_pvi[i] for i in operations] # type: ignore
259
- signal_factory = self.pvi_mapping[operations]
260
-
261
- write_pv = pvs[0]
262
- read_pv = write_pv if len(pvs) == 1 else pvs[1]
263
-
264
- return signal_factory(dtype, "pva://" + read_pv, "pva://" + write_pv)
265
-
266
- # TODO redo to set_panda_block? confusing name
267
- def set_attribute(self, name: str, num: Optional[int], block: Device):
268
- """Set a block on the panda.
269
-
270
- Need to be able to set device vectors on the panda as well, e.g. if num is not
271
- None, need to be able to make a new device vector and start populating it...
272
- """
273
- anno = get_type_hints(self, globalns=globals()).get(name)
274
-
275
- # if it's an annotated device vector, or it isn't but we've got a number then
276
- # make a DeviceVector on the class
277
- if get_origin(anno) == DeviceVector or (not anno and num is not None):
278
- self.__dict__.setdefault(name, DeviceVector())[num] = block
279
- else:
280
- setattr(self, name, block)
281
-
282
- async def connect(self, sim=False) -> None:
283
- """Initialises all blocks and connects them.
284
-
285
- First, checks for pvi information. If it exists, make all blocks from this.
286
- Then, checks that all required blocks in the PandA have been made.
287
-
288
- If there's no pvi information, that's because we're in sim mode. In that case,
289
- makes all required blocks.
290
- """
291
- pvi_info = await pvi(self._init_prefix + ":PVI", self.ctxt) if not sim else None
292
- hints = {
293
- attr_name: attr_type
294
- for attr_name, attr_type in get_type_hints(self, globalns=globals()).items()
295
- if not attr_name.startswith("_")
296
- }
297
-
298
- # create all the blocks pvi says it should have,
299
- if pvi_info:
300
- pvi_info = cast(Dict[str, PVIEntry], pvi_info)
301
- for block_name, block_pvi in pvi_info.items():
302
- name, num = _block_name_number(block_name)
303
-
304
- if name in hints:
305
- block = await self._make_block(name, num, block_pvi["d"])
306
- else:
307
- block = await self._make_untyped_block(block_pvi["d"])
308
-
309
- self.set_attribute(name, num, block)
310
-
311
- # then check if the ones defined in this class are in the pvi info
312
- # make them if there is no pvi info, i.e. sim mode.
313
- for block_name in hints.keys():
314
- if pvi_info is not None:
315
- pvi_name = block_name
316
-
317
- if get_origin(hints[block_name]) == DeviceVector:
318
- pvi_name += "1"
319
-
320
- entry: Optional[PVIEntry] = pvi_info.get(pvi_name)
321
-
322
- assert entry, f"Expected PandA to contain {block_name} block."
323
- assert list(entry) == [
324
- "d"
325
- ], f"Expected PandA to only contain blocks, got {entry}"
326
- else:
327
- num = 1 if get_origin(hints[block_name]) == DeviceVector else None
328
- block = await self._make_block(block_name, num, "sim://", sim=sim)
329
- self.set_attribute(block_name, num, block)
330
-
331
- self.set_name(self.name)
332
- await super().connect(sim)
@@ -1,45 +0,0 @@
1
- ophyd_async/__init__.py,sha256=WJoRU7gO-hRzyf7a-C952zF6-7zwPjP7qZ1Qu5GTUC8,124
2
- ophyd_async/__main__.py,sha256=G-Zcv_G9zK7Nhx6o5L5w-wyhMxdl_WgyMELu8IMFqAE,328
3
- ophyd_async/_version.py,sha256=IMl2Pr_Sy4LVRKy_Sm4CdwUl1Gryous6ncL96EMYsnM,411
4
- ophyd_async/core/__init__.py,sha256=8uqw8y6JNIjtrxo5dz1FPiFKJC_8yaY4opoGIAWNYyU,1353
5
- ophyd_async/core/async_status.py,sha256=oiqu57rti-nGNBaYn7bhXbCK3NyXgn5UNKie0jWHKxk,2735
6
- ophyd_async/core/utils.py,sha256=QxaBgmJLNGVlLYnaYq_Ia7SGWzfUHK6KISQs5BbnkUY,3086
7
- ophyd_async/core/_device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- ophyd_async/core/_device/device.py,sha256=9ikcXve_CxW45XSkvj0W1S3ZdhqrIGyeAmMV2y36xKo,1643
9
- ophyd_async/core/_device/device_collector.py,sha256=0HJrn1yRW4gP4YBHABKRiyiny749mEo_cev9KRRD4Gc,4143
10
- ophyd_async/core/_device/device_vector.py,sha256=5JUkMvYc6t477WxWzvRGCthtU2Y1ex-4sN5BOSAafqU,431
11
- ophyd_async/core/_device/standard_readable.py,sha256=CkJD5mE10Vl9JLiK2ANMLKu6YMBZ-Z_AhHoEtea3ZD4,2570
12
- ophyd_async/core/_device/_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- ophyd_async/core/_device/_backend/signal_backend.py,sha256=AK2QcROEyaMBpAQE5sRZspiZGKG0kUifjyQP1faCOlc,1190
14
- ophyd_async/core/_device/_backend/sim_signal_backend.py,sha256=R2Lcg6DrQsq49kdFY8Rd79jGS7zYZ9YlQOq66qfjDoM,5377
15
- ophyd_async/core/_device/_signal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- ophyd_async/core/_device/_signal/signal.py,sha256=2kPPeJYp-sMiC6uNzpmoQgN0Ey5bkqou8Zf0uCJRvvA,10897
17
- ophyd_async/epics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- ophyd_async/epics/_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- ophyd_async/epics/_backend/_aioca.py,sha256=cyB8G7smbF04VZJjVay69wij7x0FqXN2h4d672C4RhY,8320
20
- ophyd_async/epics/_backend/_p4p.py,sha256=ffphwOVXCFnTOUhK21l1rlqTRQP-PiwGw4dMhZJmrs8,10844
21
- ophyd_async/epics/areadetector/__init__.py,sha256=qBoVqsTArNiTSDeiKJslgFCch6dPTnjIhOKRfAWNi5A,584
22
- ophyd_async/epics/areadetector/ad_driver.py,sha256=7qaP0_T-NgFLi1ItVfMhTIhp40hKdUh7PBc0SdVChRA,776
23
- ophyd_async/epics/areadetector/directory_provider.py,sha256=61sxLihCdqGw6ppPgsgVBbXcrcSLC33A4pH-KnpzEeQ,419
24
- ophyd_async/epics/areadetector/hdf_streamer_det.py,sha256=DRDIv0fcycES-W56UAmfE82ovxzSlL2sPCnAYebmMmQ,6214
25
- ophyd_async/epics/areadetector/nd_file_hdf.py,sha256=Lo4mHnvcfYTARNNrhuXDVzq1KSAukzfb1dYPvVgwlmo,1033
26
- ophyd_async/epics/areadetector/nd_plugin.py,sha256=v3Ou4ay9FW1bW-Cwvp2W0o1nVF0jSiXP2PlFobx53S8,260
27
- ophyd_async/epics/areadetector/single_trigger_det.py,sha256=dA3GtYv36Zg1nmIZeZQptLNjSp8RTrcI4PhMoaFZCVo,1188
28
- ophyd_async/epics/areadetector/utils.py,sha256=ZsQF8f5evvpY6ubsTy1fib1hhtxbLoGS_AAsGXK5lZY,596
29
- ophyd_async/epics/demo/__init__.py,sha256=02gv5i1YyIKa6BVHUxeJdD90GZctezvjpIjsSXSJpEc,5471
30
- ophyd_async/epics/demo/mover.db,sha256=RFz0rxZue689Wh1sWTZwWeFMUrH04ttPq2u5xJH_Fp4,998
31
- ophyd_async/epics/demo/sensor.db,sha256=AVtiydrdtwAz2EFurO2Ult9SSRtre3r0akOBbL98LT0,554
32
- ophyd_async/epics/motion/__init__.py,sha256=tnmVRIwKa9PdN_xonJdAUD04UpEceh-hoD7XI62yDB0,46
33
- ophyd_async/epics/motion/motor.py,sha256=1xsVB5v1ydMReg9xuVmI-N0FbkcI26Ve4qUAurtdrpA,3368
34
- ophyd_async/epics/signal/__init__.py,sha256=M1dz74L_SM5Qf3GRuQVKn-1Pvs-CEOCkoxyg1J-etHM,232
35
- ophyd_async/epics/signal/_epics_transport.py,sha256=DEIL0iYUAWssysVEgWGu1fHSM1l-ATV2kjUgPtDN9LY,858
36
- ophyd_async/epics/signal/pvi_get.py,sha256=YTNQ9nXi1v8Rig54goc4_nFTxoH_wmF3yl75FzkdXy4,479
37
- ophyd_async/epics/signal/signal.py,sha256=XAf4LCokAVxO4caIO1fmN3EbchOcSM0jRG0ijz8ahnI,2543
38
- ophyd_async/panda/__init__.py,sha256=oP7hSaVNgFLIf3dkvJhrLxjw7yv791FBBYVxTZCRsiM,272
39
- ophyd_async/panda/panda.py,sha256=-n4nxE_-d3GXh8N4Z7Z7oX_clf0JYO_If8PbYHlQK64,10882
40
- ophyd_async-0.1.0.dist-info/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
41
- ophyd_async-0.1.0.dist-info/METADATA,sha256=lFGBmQ9p4j2iI-j2HoGLzo-SxlHrttb0C23dLb0zVdc,6989
42
- ophyd_async-0.1.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
43
- ophyd_async-0.1.0.dist-info/entry_points.txt,sha256=O0YNJTEufO0w9BozXi-JurTy2U1_o0ypeCgJLQ727Jk,58
44
- ophyd_async-0.1.0.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
45
- ophyd_async-0.1.0.dist-info/RECORD,,