ophyd-async 0.3.4a1__py3-none-any.whl → 0.5.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 (103) hide show
  1. ophyd_async/_version.py +2 -2
  2. ophyd_async/core/__init__.py +86 -63
  3. ophyd_async/core/{detector.py → _detector.py} +18 -23
  4. ophyd_async/core/{device.py → _device.py} +19 -7
  5. ophyd_async/core/{device_save_loader.py → _device_save_loader.py} +3 -3
  6. ophyd_async/core/{flyer.py → _flyer.py} +6 -8
  7. ophyd_async/core/_hdf_dataset.py +97 -0
  8. ophyd_async/{log.py → core/_log.py} +11 -3
  9. ophyd_async/core/{mock_signal_backend.py → _mock_signal_backend.py} +3 -3
  10. ophyd_async/core/{mock_signal_utils.py → _mock_signal_utils.py} +3 -4
  11. ophyd_async/{protocols.py → core/_protocol.py} +1 -1
  12. ophyd_async/core/_providers.py +186 -24
  13. ophyd_async/core/{standard_readable.py → _readable.py} +6 -16
  14. ophyd_async/core/{signal.py → _signal.py} +39 -16
  15. ophyd_async/core/{signal_backend.py → _signal_backend.py} +4 -13
  16. ophyd_async/core/{soft_signal_backend.py → _soft_signal_backend.py} +24 -18
  17. ophyd_async/core/{async_status.py → _status.py} +3 -11
  18. ophyd_async/epics/adaravis/__init__.py +9 -0
  19. ophyd_async/epics/{areadetector/aravis.py → adaravis/_aravis.py} +12 -14
  20. ophyd_async/epics/{areadetector/controllers/aravis_controller.py → adaravis/_aravis_controller.py} +8 -10
  21. ophyd_async/epics/{areadetector/drivers/aravis_driver.py → adaravis/_aravis_io.py} +6 -3
  22. ophyd_async/epics/adcore/__init__.py +36 -0
  23. ophyd_async/epics/adcore/_core_io.py +114 -0
  24. ophyd_async/epics/{areadetector/drivers/ad_base.py → adcore/_core_logic.py} +17 -52
  25. ophyd_async/epics/{areadetector/writers/hdf_writer.py → adcore/_hdf_writer.py} +36 -18
  26. ophyd_async/epics/{areadetector/single_trigger_det.py → adcore/_single_trigger.py} +5 -6
  27. ophyd_async/epics/{areadetector/utils.py → adcore/_utils.py} +29 -0
  28. ophyd_async/epics/adkinetix/__init__.py +9 -0
  29. ophyd_async/epics/{areadetector/kinetix.py → adkinetix/_kinetix.py} +12 -14
  30. ophyd_async/epics/{areadetector/controllers/kinetix_controller.py → adkinetix/_kinetix_controller.py} +6 -9
  31. ophyd_async/epics/{areadetector/drivers/kinetix_driver.py → adkinetix/_kinetix_io.py} +5 -4
  32. ophyd_async/epics/adpilatus/__init__.py +11 -0
  33. ophyd_async/epics/{areadetector/pilatus.py → adpilatus/_pilatus.py} +12 -16
  34. ophyd_async/epics/{areadetector/controllers/pilatus_controller.py → adpilatus/_pilatus_controller.py} +14 -16
  35. ophyd_async/epics/{areadetector/drivers/pilatus_driver.py → adpilatus/_pilatus_io.py} +5 -3
  36. ophyd_async/epics/adsimdetector/__init__.py +7 -0
  37. ophyd_async/epics/adsimdetector/_sim.py +34 -0
  38. ophyd_async/epics/{areadetector/controllers/ad_sim_controller.py → adsimdetector/_sim_controller.py} +8 -14
  39. ophyd_async/epics/advimba/__init__.py +9 -0
  40. ophyd_async/epics/advimba/_vimba.py +43 -0
  41. ophyd_async/epics/{areadetector/controllers/vimba_controller.py → advimba/_vimba_controller.py} +6 -14
  42. ophyd_async/epics/{areadetector/drivers/vimba_driver.py → advimba/_vimba_io.py} +5 -4
  43. ophyd_async/epics/demo/__init__.py +9 -132
  44. ophyd_async/epics/demo/_mover.py +97 -0
  45. ophyd_async/epics/demo/_sensor.py +36 -0
  46. ophyd_async/epics/motor.py +228 -0
  47. ophyd_async/epics/pvi/__init__.py +2 -2
  48. ophyd_async/epics/pvi/{pvi.py → _pvi.py} +17 -14
  49. ophyd_async/epics/signal/__init__.py +7 -1
  50. ophyd_async/epics/{_backend → signal}/_aioca.py +6 -2
  51. ophyd_async/epics/{_backend/common.py → signal/_common.py} +4 -2
  52. ophyd_async/epics/signal/_epics_transport.py +3 -3
  53. ophyd_async/epics/{_backend → signal}/_p4p.py +53 -4
  54. ophyd_async/epics/signal/{signal.py → _signal.py} +10 -9
  55. ophyd_async/fastcs/odin/__init__.py +0 -0
  56. ophyd_async/{panda → fastcs/panda}/__init__.py +28 -9
  57. ophyd_async/{panda → fastcs/panda}/_common_blocks.py +24 -3
  58. ophyd_async/{panda → fastcs/panda}/_hdf_panda.py +6 -9
  59. ophyd_async/{panda/writers → fastcs/panda}/_hdf_writer.py +24 -14
  60. ophyd_async/{panda → fastcs/panda}/_panda_controller.py +2 -1
  61. ophyd_async/{panda → fastcs/panda}/_table.py +20 -18
  62. ophyd_async/fastcs/panda/_trigger.py +90 -0
  63. ophyd_async/plan_stubs/__init__.py +2 -2
  64. ophyd_async/plan_stubs/_ensure_connected.py +26 -0
  65. ophyd_async/plan_stubs/{fly.py → _fly.py} +67 -12
  66. ophyd_async/sim/__init__.py +0 -11
  67. ophyd_async/sim/demo/__init__.py +18 -2
  68. ophyd_async/sim/demo/_pattern_detector/__init__.py +13 -0
  69. ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +42 -0
  70. ophyd_async/sim/{sim_pattern_detector_control.py → demo/_pattern_detector/_pattern_detector_controller.py} +6 -7
  71. ophyd_async/sim/{sim_pattern_detector_writer.py → demo/_pattern_detector/_pattern_detector_writer.py} +12 -8
  72. ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +211 -0
  73. ophyd_async/sim/demo/{sim_motor.py → _sim_motor.py} +7 -5
  74. ophyd_async/sim/testing/__init__.py +0 -0
  75. ophyd_async/tango/__init__.py +0 -0
  76. {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/METADATA +7 -2
  77. ophyd_async-0.5.0.dist-info/RECORD +89 -0
  78. {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/WHEEL +1 -1
  79. ophyd_async/epics/areadetector/__init__.py +0 -23
  80. ophyd_async/epics/areadetector/controllers/__init__.py +0 -5
  81. ophyd_async/epics/areadetector/drivers/__init__.py +0 -23
  82. ophyd_async/epics/areadetector/vimba.py +0 -43
  83. ophyd_async/epics/areadetector/writers/__init__.py +0 -5
  84. ophyd_async/epics/areadetector/writers/_hdfdataset.py +0 -10
  85. ophyd_async/epics/areadetector/writers/_hdffile.py +0 -54
  86. ophyd_async/epics/areadetector/writers/nd_file_hdf.py +0 -40
  87. ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -38
  88. ophyd_async/epics/demo/demo_ad_sim_detector.py +0 -35
  89. ophyd_async/epics/motion/__init__.py +0 -3
  90. ophyd_async/epics/motion/motor.py +0 -97
  91. ophyd_async/panda/_trigger.py +0 -39
  92. ophyd_async/panda/writers/__init__.py +0 -3
  93. ophyd_async/panda/writers/_panda_hdf_file.py +0 -54
  94. ophyd_async/plan_stubs/ensure_connected.py +0 -22
  95. ophyd_async/sim/pattern_generator.py +0 -318
  96. ophyd_async/sim/sim_pattern_generator.py +0 -35
  97. ophyd_async-0.3.4a1.dist-info/RECORD +0 -86
  98. /ophyd_async/core/{utils.py → _utils.py} +0 -0
  99. /ophyd_async/{epics/_backend → fastcs}/__init__.py +0 -0
  100. /ophyd_async/{panda → fastcs/panda}/_utils.py +0 -0
  101. {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/LICENSE +0 -0
  102. {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/entry_points.txt +0 -0
  103. {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/top_level.txt +0 -0
ophyd_async/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.3.4a1'
16
- __version_tuple__ = version_tuple = (0, 3, 4)
15
+ __version__ = version = '0.5.0'
16
+ __version_tuple__ = version_tuple = (0, 5, 0)
@@ -1,20 +1,13 @@
1
- from ._providers import (
2
- DirectoryInfo,
3
- DirectoryProvider,
4
- NameProvider,
5
- ShapeProvider,
6
- StaticDirectoryProvider,
7
- )
8
- from .async_status import AsyncStatus, WatchableAsyncStatus
9
- from .detector import (
1
+ from ._detector import (
10
2
  DetectorControl,
11
3
  DetectorTrigger,
12
4
  DetectorWriter,
13
5
  StandardDetector,
14
6
  TriggerInfo,
15
7
  )
16
- from .device import Device, DeviceCollector, DeviceVector
17
- from .device_save_loader import (
8
+ from ._device import Device, DeviceCollector, DeviceVector
9
+ from ._device_save_loader import (
10
+ all_at_once,
18
11
  get_signal_values,
19
12
  load_device,
20
13
  load_from_yaml,
@@ -23,9 +16,11 @@ from .device_save_loader import (
23
16
  set_signal_values,
24
17
  walk_rw_signals,
25
18
  )
26
- from .flyer import HardwareTriggeredFlyable, TriggerLogic
27
- from .mock_signal_backend import MockSignalBackend
28
- from .mock_signal_utils import (
19
+ from ._flyer import StandardFlyer, TriggerLogic
20
+ from ._hdf_dataset import HDFDataset, HDFFile
21
+ from ._log import config_ophyd_async_logging
22
+ from ._mock_signal_backend import MockSignalBackend
23
+ from ._mock_signal_utils import (
29
24
  callback_on_mock_put,
30
25
  get_mock_put,
31
26
  mock_puts_blocked,
@@ -34,7 +29,22 @@ from .mock_signal_utils import (
34
29
  set_mock_value,
35
30
  set_mock_values,
36
31
  )
37
- from .signal import (
32
+ from ._protocol import AsyncConfigurable, AsyncReadable, AsyncStageable
33
+ from ._providers import (
34
+ AutoIncrementFilenameProvider,
35
+ AutoIncrementingPathProvider,
36
+ FilenameProvider,
37
+ NameProvider,
38
+ PathInfo,
39
+ PathProvider,
40
+ ShapeProvider,
41
+ StaticFilenameProvider,
42
+ StaticPathProvider,
43
+ UUIDFilenameProvider,
44
+ YMDPathProvider,
45
+ )
46
+ from ._readable import ConfigSignal, HintedSignal, StandardReadable
47
+ from ._signal import (
38
48
  Signal,
39
49
  SignalR,
40
50
  SignalRW,
@@ -50,87 +60,100 @@ from .signal import (
50
60
  soft_signal_rw,
51
61
  wait_for_value,
52
62
  )
53
- from .signal_backend import RuntimeSubsetEnum, SignalBackend, SubsetEnum
54
- from .soft_signal_backend import SoftSignalBackend
55
- from .standard_readable import ConfigSignal, HintedSignal, StandardReadable
56
- from .utils import (
63
+ from ._signal_backend import RuntimeSubsetEnum, SignalBackend, SubsetEnum
64
+ from ._soft_signal_backend import SignalMetadata, SoftSignalBackend
65
+ from ._status import AsyncStatus, WatchableAsyncStatus
66
+ from ._utils import (
57
67
  DEFAULT_TIMEOUT,
58
68
  CalculatableTimeout,
59
69
  CalculateTimeout,
60
- Callback,
61
70
  NotConnected,
62
71
  ReadingValueCallback,
63
72
  T,
73
+ WatcherUpdate,
64
74
  get_dtype,
65
75
  get_unique,
66
- merge_gathered_dicts,
76
+ in_micros,
67
77
  wait_for_connection,
68
78
  )
69
79
 
70
80
  __all__ = [
71
- "AsyncStatus",
72
- "CalculatableTimeout",
73
- "CalculateTimeout",
74
- "Callback",
75
- "ConfigSignal",
76
- "DEFAULT_TIMEOUT",
77
81
  "DetectorControl",
78
82
  "DetectorTrigger",
79
83
  "DetectorWriter",
84
+ "StandardDetector",
85
+ "TriggerInfo",
80
86
  "Device",
81
87
  "DeviceCollector",
82
88
  "DeviceVector",
83
- "DirectoryInfo",
84
- "DirectoryProvider",
85
- "HardwareTriggeredFlyable",
86
- "HintedSignal",
89
+ "all_at_once",
90
+ "get_signal_values",
91
+ "load_device",
92
+ "load_from_yaml",
93
+ "save_device",
94
+ "save_to_yaml",
95
+ "set_signal_values",
96
+ "walk_rw_signals",
97
+ "StandardFlyer",
98
+ "TriggerLogic",
99
+ "HDFDataset",
100
+ "HDFFile",
101
+ "config_ophyd_async_logging",
87
102
  "MockSignalBackend",
103
+ "callback_on_mock_put",
104
+ "get_mock_put",
105
+ "mock_puts_blocked",
106
+ "reset_mock_put_calls",
107
+ "set_mock_put_proceeds",
108
+ "set_mock_value",
109
+ "set_mock_values",
110
+ "AsyncConfigurable",
111
+ "AsyncReadable",
112
+ "AsyncStageable",
113
+ "AutoIncrementFilenameProvider",
114
+ "AutoIncrementingPathProvider",
115
+ "FilenameProvider",
88
116
  "NameProvider",
89
- "NotConnected",
90
- "ReadingValueCallback",
91
- "RuntimeSubsetEnum",
92
- "SubsetEnum",
117
+ "PathInfo",
118
+ "PathProvider",
93
119
  "ShapeProvider",
120
+ "StaticFilenameProvider",
121
+ "StaticPathProvider",
122
+ "UUIDFilenameProvider",
123
+ "YMDPathProvider",
124
+ "ConfigSignal",
125
+ "HintedSignal",
126
+ "StandardReadable",
94
127
  "Signal",
95
- "SignalBackend",
96
128
  "SignalR",
97
129
  "SignalRW",
98
130
  "SignalW",
99
131
  "SignalX",
100
- "SoftSignalBackend",
101
- "StandardDetector",
102
- "StandardReadable",
103
- "StaticDirectoryProvider",
104
- "T",
105
- "TriggerInfo",
106
- "TriggerLogic",
107
- "WatchableAsyncStatus",
108
132
  "assert_configuration",
109
133
  "assert_emitted",
110
- "assert_mock_put_called_with",
111
134
  "assert_reading",
112
135
  "assert_value",
113
- "callback_on_mock_put",
114
- "get_dtype",
115
- "get_mock_put",
116
- "get_signal_values",
117
- "get_unique",
118
- "load_device",
119
- "load_from_yaml",
120
- "merge_gathered_dicts",
121
- "mock_puts_blocked",
122
136
  "observe_value",
123
- "reset_mock_put_calls",
124
- "save_device",
125
- "save_to_yaml",
126
137
  "set_and_wait_for_value",
127
- "set_mock_put_proceeds",
128
- "set_mock_value",
129
- "set_mock_values",
130
- "set_signal_values",
131
138
  "soft_signal_r_and_setter",
132
139
  "soft_signal_rw",
133
- "wait_for_connection",
134
140
  "wait_for_value",
135
- "walk_rw_signals",
141
+ "RuntimeSubsetEnum",
142
+ "SignalBackend",
143
+ "SubsetEnum",
144
+ "SignalMetadata",
145
+ "SoftSignalBackend",
146
+ "AsyncStatus",
147
+ "WatchableAsyncStatus",
148
+ "DEFAULT_TIMEOUT",
149
+ "CalculatableTimeout",
150
+ "CalculateTimeout",
151
+ "NotConnected",
152
+ "ReadingValueCallback",
153
+ "T",
154
+ "WatcherUpdate",
155
+ "get_dtype",
156
+ "get_unique",
157
+ "in_micros",
158
+ "wait_for_connection",
136
159
  ]
@@ -3,7 +3,6 @@
3
3
  import asyncio
4
4
  import time
5
5
  from abc import ABC, abstractmethod
6
- from dataclasses import dataclass
7
6
  from enum import Enum
8
7
  from typing import (
9
8
  AsyncGenerator,
@@ -14,7 +13,6 @@ from typing import (
14
13
  List,
15
14
  Optional,
16
15
  Sequence,
17
- TypeVar,
18
16
  )
19
17
 
20
18
  from bluesky.protocols import (
@@ -28,14 +26,12 @@ from bluesky.protocols import (
28
26
  Triggerable,
29
27
  WritesStreamAssets,
30
28
  )
29
+ from pydantic import BaseModel, Field
31
30
 
32
- from ophyd_async.protocols import AsyncConfigurable, AsyncReadable
33
-
34
- from .async_status import AsyncStatus, WatchableAsyncStatus
35
- from .device import Device
36
- from .utils import DEFAULT_TIMEOUT, WatcherUpdate, merge_gathered_dicts
37
-
38
- T = TypeVar("T")
31
+ from ._device import Device
32
+ from ._protocol import AsyncConfigurable, AsyncReadable
33
+ from ._status import AsyncStatus, WatchableAsyncStatus
34
+ from ._utils import DEFAULT_TIMEOUT, T, WatcherUpdate, merge_gathered_dicts
39
35
 
40
36
 
41
37
  class DetectorTrigger(str, Enum):
@@ -51,20 +47,19 @@ class DetectorTrigger(str, Enum):
51
47
  variable_gate = "variable_gate"
52
48
 
53
49
 
54
- @dataclass(frozen=True)
55
- class TriggerInfo:
50
+ class TriggerInfo(BaseModel):
56
51
  """Minimal set of information required to setup triggering on a detector"""
57
52
 
58
- #: Number of triggers that will be sent
59
- num: int
53
+ #: Number of triggers that will be sent, 0 means infinite
54
+ number: int = Field(gt=0)
60
55
  #: Sort of triggers that will be sent
61
- trigger: DetectorTrigger
56
+ trigger: DetectorTrigger = Field()
62
57
  #: What is the minimum deadtime between triggers
63
- deadtime: float
58
+ deadtime: float = Field(ge=0)
64
59
  #: What is the maximum high time of the triggers
65
- livetime: float
60
+ livetime: float = Field(ge=0)
66
61
  #: What is the maximum timeout on waiting for a frame
67
- frame_timeout: float | None = None
62
+ frame_timeout: float | None = Field(None, gt=0)
68
63
 
69
64
 
70
65
  class DetectorControl(ABC):
@@ -243,12 +238,12 @@ class StandardDetector(
243
238
  async def trigger(self) -> None:
244
239
  # set default trigger_info
245
240
  self._trigger_info = TriggerInfo(
246
- num=1, trigger=DetectorTrigger.internal, deadtime=0.0, livetime=0.0
241
+ number=1, trigger=DetectorTrigger.internal, deadtime=0.0, livetime=0.0
247
242
  )
248
243
  # Arm the detector and wait for it to finish.
249
244
  indices_written = await self.writer.get_indices_written()
250
245
  written_status = await self.controller.arm(
251
- num=self._trigger_info.num,
246
+ num=self._trigger_info.number,
252
247
  trigger=self._trigger_info.trigger,
253
248
  )
254
249
  await written_status
@@ -285,7 +280,7 @@ class StandardDetector(
285
280
  assert type(value) is TriggerInfo
286
281
  self._trigger_info = value
287
282
  self._initial_frame = await self.writer.get_indices_written()
288
- self._last_frame = self._initial_frame + self._trigger_info.num
283
+ self._last_frame = self._initial_frame + self._trigger_info.number
289
284
 
290
285
  required = self.controller.get_deadtime(self._trigger_info.livetime)
291
286
  assert required <= self._trigger_info.deadtime, (
@@ -293,7 +288,7 @@ class StandardDetector(
293
288
  f"but trigger logic provides only {self._trigger_info.deadtime}s"
294
289
  )
295
290
  self._arm_status = await self.controller.arm(
296
- num=self._trigger_info.num,
291
+ num=self._trigger_info.number,
297
292
  trigger=self._trigger_info.trigger,
298
293
  exposure=self._trigger_info.livetime,
299
294
  )
@@ -320,12 +315,12 @@ class StandardDetector(
320
315
  name=self.name,
321
316
  current=index,
322
317
  initial=self._initial_frame,
323
- target=self._trigger_info.num,
318
+ target=self._trigger_info.number,
324
319
  unit="",
325
320
  precision=0,
326
321
  time_elapsed=time.monotonic() - self._fly_start,
327
322
  )
328
- if index >= self._trigger_info.num:
323
+ if index >= self._trigger_info.number:
329
324
  break
330
325
 
331
326
  async def describe_collect(self) -> Dict[str, DataKey]:
@@ -19,7 +19,7 @@ from typing import (
19
19
  from bluesky.protocols import HasName
20
20
  from bluesky.run_engine import call_in_bluesky_event_loop
21
21
 
22
- from .utils import DEFAULT_TIMEOUT, NotConnected, wait_for_connection
22
+ from ._utils import DEFAULT_TIMEOUT, NotConnected, wait_for_connection
23
23
 
24
24
 
25
25
  class Device(HasName):
@@ -33,7 +33,10 @@ class Device(HasName):
33
33
  parent: Optional["Device"] = None
34
34
  # None if connect hasn't started, a Task if it has
35
35
  _connect_task: Optional[asyncio.Task] = None
36
- _connect_mock_arg: bool = False
36
+
37
+ # Used to check if the previous connect was mocked,
38
+ # if the next mock value differs then we fail
39
+ _previous_connect_was_mock = None
37
40
 
38
41
  def __init__(self, name: str = "") -> None:
39
42
  self.set_name(name)
@@ -90,11 +93,21 @@ class Device(HasName):
90
93
  timeout:
91
94
  Time to wait before failing with a TimeoutError.
92
95
  """
96
+
97
+ if (
98
+ self._previous_connect_was_mock is not None
99
+ and self._previous_connect_was_mock != mock
100
+ ):
101
+ raise RuntimeError(
102
+ f"`connect(mock={mock})` called on a `Device` where the previous "
103
+ f"connect was `mock={self._previous_connect_was_mock}`. Changing mock "
104
+ "value between connects is not permitted."
105
+ )
106
+ self._previous_connect_was_mock = mock
107
+
93
108
  # If previous connect with same args has started and not errored, can use it
94
- can_use_previous_connect = (
95
- self._connect_task
96
- and not (self._connect_task.done() and self._connect_task.exception())
97
- and self._connect_mock_arg == mock
109
+ can_use_previous_connect = self._connect_task and not (
110
+ self._connect_task.done() and self._connect_task.exception()
98
111
  )
99
112
  if force_reconnect or not can_use_previous_connect:
100
113
  # Kick off a connection
@@ -105,7 +118,6 @@ class Device(HasName):
105
118
  for name, child_device in self.children()
106
119
  }
107
120
  self._connect_task = asyncio.create_task(wait_for_connection(**coros))
108
- self._connect_mock_arg = mock
109
121
 
110
122
  assert self._connect_task, "Connect task not created, this shouldn't happen"
111
123
  # Wait for it to complete
@@ -8,8 +8,8 @@ from bluesky.plan_stubs import abs_set, wait
8
8
  from bluesky.protocols import Location
9
9
  from bluesky.utils import Msg
10
10
 
11
- from .device import Device
12
- from .signal import SignalRW
11
+ from ._device import Device
12
+ from ._signal import SignalRW
13
13
 
14
14
 
15
15
  def ndarray_representer(dumper: yaml.Dumper, array: npt.NDArray[Any]) -> yaml.Node:
@@ -241,7 +241,7 @@ def save_device(
241
241
  Therefore, users should consider the order of device loading and write their
242
242
  own sorter algorithms accordingly.
243
243
 
244
- See :func:`ophyd_async.panda.phase_sorter` for a valid implementation of the
244
+ See :func:`ophyd_async.fastcs.panda.phase_sorter` for a valid implementation of the
245
245
  sorter.
246
246
 
247
247
  Parameters
@@ -1,14 +1,12 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, Generic, Sequence, TypeVar
2
+ from typing import Dict, Generic, Sequence
3
3
 
4
4
  from bluesky.protocols import DataKey, Flyable, Preparable, Reading, Stageable
5
5
 
6
- from .async_status import AsyncStatus
7
- from .device import Device
8
- from .signal import SignalR
9
- from .utils import merge_gathered_dicts
10
-
11
- T = TypeVar("T")
6
+ from ._device import Device
7
+ from ._signal import SignalR
8
+ from ._status import AsyncStatus
9
+ from ._utils import T, merge_gathered_dicts
12
10
 
13
11
 
14
12
  class TriggerLogic(ABC, Generic[T]):
@@ -29,7 +27,7 @@ class TriggerLogic(ABC, Generic[T]):
29
27
  """Stop flying and wait everything to be stopped"""
30
28
 
31
29
 
32
- class HardwareTriggeredFlyable(
30
+ class StandardFlyer(
33
31
  Device,
34
32
  Stageable,
35
33
  Preparable,
@@ -0,0 +1,97 @@
1
+ from dataclasses import dataclass, field
2
+ from pathlib import Path
3
+ from typing import Iterator, List, Sequence
4
+ from urllib.parse import urlunparse
5
+
6
+ from event_model import (
7
+ ComposeStreamResource,
8
+ ComposeStreamResourceBundle,
9
+ StreamDatum,
10
+ StreamResource,
11
+ )
12
+
13
+ from ._providers import PathInfo
14
+
15
+
16
+ @dataclass
17
+ class HDFDataset:
18
+ data_key: str
19
+ dataset: str
20
+ shape: Sequence[int] = field(default_factory=tuple)
21
+ dtype_numpy: str = ""
22
+ multiplier: int = 1
23
+ swmr: bool = False
24
+
25
+
26
+ SLICE_NAME = "AD_HDF5_SWMR_SLICE"
27
+
28
+
29
+ class HDFFile:
30
+ """
31
+ :param directory_info: Contains information about how to construct a StreamResource
32
+ :param full_file_name: Absolute path to the file to be written
33
+ :param datasets: Datasets to write into the file
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ path_info: PathInfo,
39
+ full_file_name: Path,
40
+ datasets: List[HDFDataset],
41
+ hostname: str = "localhost",
42
+ ) -> None:
43
+ self._last_emitted = 0
44
+ self._hostname = hostname
45
+
46
+ if len(datasets) == 0:
47
+ self._bundles = []
48
+ return None
49
+
50
+ bundler_composer = ComposeStreamResource()
51
+
52
+ uri = urlunparse(
53
+ (
54
+ "file",
55
+ self._hostname,
56
+ str((path_info.root / full_file_name).absolute()),
57
+ "",
58
+ "",
59
+ None,
60
+ )
61
+ )
62
+
63
+ self._bundles: List[ComposeStreamResourceBundle] = [
64
+ bundler_composer(
65
+ mimetype="application/x-hdf5",
66
+ uri=uri,
67
+ data_key=ds.data_key,
68
+ parameters={
69
+ "dataset": ds.dataset,
70
+ "swmr": ds.swmr,
71
+ "multiplier": ds.multiplier,
72
+ },
73
+ uid=None,
74
+ validate=True,
75
+ )
76
+ for ds in datasets
77
+ ]
78
+
79
+ def stream_resources(self) -> Iterator[StreamResource]:
80
+ for bundle in self._bundles:
81
+ yield bundle.stream_resource_doc
82
+
83
+ def stream_data(self, indices_written: int) -> Iterator[StreamDatum]:
84
+ # Indices are relative to resource
85
+ if indices_written > self._last_emitted:
86
+ indices = {
87
+ "start": self._last_emitted,
88
+ "stop": indices_written,
89
+ }
90
+ self._last_emitted = indices_written
91
+ for bundle in self._bundles:
92
+ yield bundle.compose_stream_datum(indices)
93
+ return None
94
+
95
+ def close(self) -> None:
96
+ for bundle in self._bundles:
97
+ bundle.close()
@@ -34,9 +34,7 @@ class ColoredFormatterWithDeviceName(colorlog.ColoredFormatter):
34
34
 
35
35
 
36
36
  def _validate_level(level) -> int:
37
- """
38
- Return an int for level comparison
39
- """
37
+ """Return an int for level comparison."""
40
38
  if isinstance(level, int):
41
39
  levelno = level
42
40
  elif isinstance(level, str):
@@ -80,21 +78,31 @@ def config_ophyd_async_logging(
80
78
  level : str or int
81
79
  Python logging level, given as string or corresponding integer.
82
80
  Default is 'WARNING'.
81
+
83
82
  Returns
84
83
  -------
85
84
  handler : logging.Handler
86
85
  The handler, which has already been added to the 'ophyd_async' logger.
86
+
87
87
  Examples
88
88
  --------
89
89
  Log to a file.
90
+
90
91
  config_ophyd_async_logging(file='/tmp/what_is_happening.txt')
92
+
91
93
  Include the date along with the time. (The log messages will always include
92
94
  microseconds, which are configured separately, not as part of 'datefmt'.)
95
+
93
96
  config_ophyd_async_logging(datefmt="%Y-%m-%d %H:%M:%S")
97
+
94
98
  Turn off ANSI color codes.
99
+
95
100
  config_ophyd_async_logging(color=False)
101
+
96
102
  Increase verbosity: show level DEBUG or higher.
103
+
97
104
  config_ophyd_async_logging(level='DEBUG')
105
+
98
106
  """
99
107
  global current_handler
100
108
 
@@ -5,9 +5,9 @@ from unittest.mock import Mock
5
5
 
6
6
  from bluesky.protocols import Descriptor, Reading
7
7
 
8
- from ophyd_async.core.signal_backend import SignalBackend
9
- from ophyd_async.core.soft_signal_backend import SoftSignalBackend
10
- from ophyd_async.core.utils import DEFAULT_TIMEOUT, ReadingValueCallback, T
8
+ from ._signal_backend import SignalBackend
9
+ from ._soft_signal_backend import SoftSignalBackend
10
+ from ._utils import DEFAULT_TIMEOUT, ReadingValueCallback, T
11
11
 
12
12
 
13
13
  class MockSignalBackend(SignalBackend[T]):
@@ -2,10 +2,9 @@ from contextlib import asynccontextmanager, contextmanager
2
2
  from typing import Any, Callable, Iterable
3
3
  from unittest.mock import Mock
4
4
 
5
- from ophyd_async.core.signal import Signal
6
- from ophyd_async.core.utils import T
7
-
8
- from .mock_signal_backend import MockSignalBackend
5
+ from ._mock_signal_backend import MockSignalBackend
6
+ from ._signal import Signal
7
+ from ._utils import T
9
8
 
10
9
 
11
10
  def _get_mock_signal_backend(signal: Signal) -> MockSignalBackend:
@@ -14,7 +14,7 @@ from typing import (
14
14
  from bluesky.protocols import DataKey, HasName, Reading
15
15
 
16
16
  if TYPE_CHECKING:
17
- from ophyd_async.core.async_status import AsyncStatus
17
+ from ._status import AsyncStatus
18
18
 
19
19
 
20
20
  @runtime_checkable