ophyd-async 0.4.0__py3-none-any.whl → 0.5.1__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 (95) hide show
  1. ophyd_async/_version.py +2 -2
  2. ophyd_async/core/__init__.py +86 -73
  3. ophyd_async/core/{detector.py → _detector.py} +42 -36
  4. ophyd_async/core/{device.py → _device.py} +1 -1
  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/{epics/areadetector/writers/general_hdffile.py → core/_hdf_dataset.py} +4 -8
  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} +7 -7
  11. ophyd_async/{protocols.py → core/_protocol.py} +1 -1
  12. ophyd_async/core/_providers.py +24 -37
  13. ophyd_async/core/{standard_readable.py → _readable.py} +6 -16
  14. ophyd_async/core/{signal.py → _signal.py} +79 -35
  15. ophyd_async/core/{signal_backend.py → _signal_backend.py} +4 -13
  16. ophyd_async/core/{soft_signal_backend.py → _soft_signal_backend.py} +3 -12
  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} +9 -11
  20. ophyd_async/epics/{areadetector/controllers/aravis_controller.py → adaravis/_aravis_controller.py} +7 -10
  21. ophyd_async/epics/{areadetector/drivers/aravis_driver.py → adaravis/_aravis_io.py} +6 -3
  22. ophyd_async/epics/adcore/__init__.py +47 -0
  23. ophyd_async/epics/adcore/_core_io.py +138 -0
  24. ophyd_async/epics/{areadetector/drivers/ad_base.py → adcore/_core_logic.py} +16 -52
  25. ophyd_async/epics/{areadetector/writers/hdf_writer.py → adcore/_hdf_writer.py} +54 -29
  26. ophyd_async/epics/{areadetector/single_trigger_det.py → adcore/_single_trigger.py} +5 -6
  27. ophyd_async/epics/adcore/_utils.py +132 -0
  28. ophyd_async/epics/adkinetix/__init__.py +9 -0
  29. ophyd_async/epics/{areadetector/kinetix.py → adkinetix/_kinetix.py} +9 -11
  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} +9 -5
  32. ophyd_async/epics/adpilatus/__init__.py +11 -0
  33. ophyd_async/epics/{areadetector/pilatus.py → adpilatus/_pilatus.py} +10 -14
  34. ophyd_async/epics/{areadetector/controllers/pilatus_controller.py → adpilatus/_pilatus_controller.py} +15 -17
  35. ophyd_async/epics/{areadetector/drivers/pilatus_driver.py → adpilatus/_pilatus_io.py} +6 -4
  36. ophyd_async/epics/adsimdetector/__init__.py +7 -0
  37. ophyd_async/epics/{demo/demo_ad_sim_detector.py → adsimdetector/_sim.py} +10 -11
  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/{areadetector/vimba.py → advimba/_vimba.py} +9 -9
  41. ophyd_async/epics/{areadetector/controllers/vimba_controller.py → advimba/_vimba_controller.py} +9 -17
  42. ophyd_async/epics/{areadetector/drivers/vimba_driver.py → advimba/_vimba_io.py} +11 -8
  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/{motion/motor.py → motor.py} +28 -14
  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 +15 -7
  51. ophyd_async/epics/{_backend/common.py → signal/_common.py} +2 -2
  52. ophyd_async/epics/signal/_epics_transport.py +3 -3
  53. ophyd_async/epics/{_backend → signal}/_p4p.py +18 -14
  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 +20 -15
  57. ophyd_async/{panda/_common_blocks.py → fastcs/panda/_block.py} +5 -3
  58. ophyd_async/{panda/_panda_controller.py → fastcs/panda/_control.py} +2 -1
  59. ophyd_async/{panda → fastcs/panda}/_hdf_panda.py +5 -10
  60. ophyd_async/{panda → fastcs/panda}/_trigger.py +3 -7
  61. ophyd_async/{panda/writers/_hdf_writer.py → fastcs/panda/_writer.py} +36 -28
  62. ophyd_async/plan_stubs/__init__.py +5 -2
  63. ophyd_async/plan_stubs/{ensure_connected.py → _ensure_connected.py} +1 -2
  64. ophyd_async/plan_stubs/{fly.py → _fly.py} +13 -9
  65. ophyd_async/plan_stubs/_nd_attributes.py +63 -0
  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/{sim_pattern_generator.py → demo/_pattern_detector/_pattern_detector.py} +8 -8
  70. ophyd_async/sim/{sim_pattern_detector_control.py → demo/_pattern_detector/_pattern_detector_controller.py} +9 -7
  71. ophyd_async/sim/{sim_pattern_detector_writer.py → demo/_pattern_detector/_pattern_detector_writer.py} +4 -4
  72. ophyd_async/sim/{pattern_generator.py → demo/_pattern_detector/_pattern_generator.py} +13 -11
  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.4.0.dist-info → ophyd_async-0.5.1.dist-info}/METADATA +46 -44
  77. ophyd_async-0.5.1.dist-info/RECORD +90 -0
  78. {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.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/utils.py +0 -104
  83. ophyd_async/epics/areadetector/writers/__init__.py +0 -5
  84. ophyd_async/epics/areadetector/writers/nd_file_hdf.py +0 -43
  85. ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -68
  86. ophyd_async/epics/motion/__init__.py +0 -3
  87. ophyd_async/panda/writers/__init__.py +0 -3
  88. ophyd_async-0.4.0.dist-info/RECORD +0 -84
  89. /ophyd_async/core/{utils.py → _utils.py} +0 -0
  90. /ophyd_async/{epics/_backend → fastcs}/__init__.py +0 -0
  91. /ophyd_async/{panda → fastcs/panda}/_table.py +0 -0
  92. /ophyd_async/{panda → fastcs/panda}/_utils.py +0 -0
  93. {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/LICENSE +0 -0
  94. {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/entry_points.txt +0 -0
  95. {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,8 @@ from ophyd_async.core import (
7
7
  DetectorTrigger,
8
8
  wait_for_value,
9
9
  )
10
- from ophyd_async.panda import PcapBlock
10
+
11
+ from ._block import PcapBlock
11
12
 
12
13
 
13
14
  class PandaPcapController(DetectorControl):
@@ -2,17 +2,12 @@ from __future__ import annotations
2
2
 
3
3
  from typing import Sequence
4
4
 
5
- from ophyd_async.core import (
6
- DEFAULT_TIMEOUT,
7
- PathProvider,
8
- SignalR,
9
- StandardDetector,
10
- )
5
+ from ophyd_async.core import DEFAULT_TIMEOUT, PathProvider, SignalR, StandardDetector
11
6
  from ophyd_async.epics.pvi import create_children_from_annotations, fill_pvi_entries
12
7
 
13
- from ._common_blocks import CommonPandaBlocks
14
- from ._panda_controller import PandaPcapController
15
- from .writers._hdf_writer import PandaHDFWriter
8
+ from ._block import CommonPandaBlocks
9
+ from ._control import PandaPcapController
10
+ from ._writer import PandaHDFWriter
16
11
 
17
12
 
18
13
  class HDFPanda(CommonPandaBlocks, StandardDetector):
@@ -31,7 +26,7 @@ class HDFPanda(CommonPandaBlocks, StandardDetector):
31
26
  prefix=prefix,
32
27
  path_provider=path_provider,
33
28
  name_provider=lambda: name,
34
- panda_device=self,
29
+ panda_data_block=self.data,
35
30
  )
36
31
  super().__init__(
37
32
  controller=controller,
@@ -4,13 +4,9 @@ from typing import Optional
4
4
  from pydantic import BaseModel, Field
5
5
 
6
6
  from ophyd_async.core import TriggerLogic, wait_for_value
7
- from ophyd_async.panda import (
8
- PcompBlock,
9
- PcompDirectionOptions,
10
- SeqBlock,
11
- SeqTable,
12
- TimeUnits,
13
- )
7
+
8
+ from ._block import PcompBlock, PcompDirectionOptions, SeqBlock, TimeUnits
9
+ from ._table import SeqTable
14
10
 
15
11
 
16
12
  class SeqTableInfo(BaseModel):
@@ -8,14 +8,15 @@ from p4p.client.thread import Context
8
8
  from ophyd_async.core import (
9
9
  DEFAULT_TIMEOUT,
10
10
  DetectorWriter,
11
+ HDFDataset,
12
+ HDFFile,
11
13
  NameProvider,
12
14
  PathProvider,
15
+ observe_value,
13
16
  wait_for_value,
14
17
  )
15
- from ophyd_async.core.signal import observe_value
16
- from ophyd_async.epics.areadetector.writers.general_hdffile import _HDFDataset, _HDFFile
17
18
 
18
- from .._common_blocks import CommonPandaBlocks
19
+ from ._block import DataBlock
19
20
 
20
21
 
21
22
  class PandaHDFWriter(DetectorWriter):
@@ -26,14 +27,14 @@ class PandaHDFWriter(DetectorWriter):
26
27
  prefix: str,
27
28
  path_provider: PathProvider,
28
29
  name_provider: NameProvider,
29
- panda_device: CommonPandaBlocks,
30
+ panda_data_block: DataBlock,
30
31
  ) -> None:
31
- self.panda_device = panda_device
32
+ self.panda_data_block = panda_data_block
32
33
  self._prefix = prefix
33
34
  self._path_provider = path_provider
34
35
  self._name_provider = name_provider
35
- self._datasets: List[_HDFDataset] = []
36
- self._file: Optional[_HDFFile] = None
36
+ self._datasets: List[HDFDataset] = []
37
+ self._file: Optional[HDFFile] = None
37
38
  self._multiplier = 1
38
39
 
39
40
  # Triggered on PCAP arm
@@ -41,25 +42,33 @@ class PandaHDFWriter(DetectorWriter):
41
42
  """Retrieve and get descriptor of all PandA signals marked for capture"""
42
43
 
43
44
  # Ensure flushes are immediate
44
- await self.panda_device.data.flush_period.set(0)
45
+ await self.panda_data_block.flush_period.set(0)
45
46
 
46
47
  self._file = None
47
- info = self._path_provider(device_name=self.panda_device.name)
48
+ info = self._path_provider(device_name=self._name_provider())
49
+
50
+ # Set create dir depth first to guarantee that callback when setting
51
+ # directory path has correct value
52
+ await self.panda_data_block.create_directory.set(info.create_dir_depth)
53
+
48
54
  # Set the initial values
49
55
  await asyncio.gather(
50
- self.panda_device.data.hdf_directory.set(
51
- str(info.root / info.resource_dir)
52
- ),
53
- self.panda_device.data.hdf_file_name.set(
56
+ self.panda_data_block.hdf_directory.set(str(info.directory_path)),
57
+ self.panda_data_block.hdf_file_name.set(
54
58
  f"{info.filename}.h5",
55
59
  ),
56
- self.panda_device.data.num_capture.set(0),
57
- # TODO: Set create_dir_depth once available
58
- # https://github.com/bluesky/ophyd-async/issues/317
60
+ self.panda_data_block.num_capture.set(0),
59
61
  )
60
62
 
63
+ # Make sure that directory exists or has been created.
64
+ if not await self.panda_data_block.directory_exists.get_value() == 1:
65
+ raise OSError(
66
+ f"Directory {info.directory_path} does not exist or "
67
+ "is not writable by the PandABlocks-ioc!"
68
+ )
69
+
61
70
  # Wait for it to start, stashing the status that tells us when it finishes
62
- await self.panda_device.data.capture.set(True)
71
+ await self.panda_data_block.capture.set(True)
63
72
  if multiplier > 1:
64
73
  raise ValueError(
65
74
  "All PandA datasets should be scalar, multiplier should be 1"
@@ -75,7 +84,7 @@ class PandaHDFWriter(DetectorWriter):
75
84
  await self._update_datasets()
76
85
  describe = {
77
86
  ds.data_key: DataKey(
78
- source=self.panda_device.data.hdf_directory.source,
87
+ source=self.panda_data_block.hdf_directory.source,
79
88
  shape=ds.shape,
80
89
  dtype="array" if ds.shape != [1] else "number",
81
90
  dtype_numpy="<f8", # PandA data should always be written as Float64
@@ -91,9 +100,9 @@ class PandaHDFWriter(DetectorWriter):
91
100
  representation of datasets that the panda will write.
92
101
  """
93
102
 
94
- capture_table = await self.panda_device.data.datasets.get_value()
103
+ capture_table = await self.panda_data_block.datasets.get_value()
95
104
  self._datasets = [
96
- _HDFDataset(dataset_name, "/" + dataset_name, [1], multiplier=1)
105
+ HDFDataset(dataset_name, "/" + dataset_name, [1], multiplier=1)
97
106
  for dataset_name in capture_table["name"]
98
107
  ]
99
108
 
@@ -107,18 +116,18 @@ class PandaHDFWriter(DetectorWriter):
107
116
 
108
117
  matcher.__name__ = f"index_at_least_{index}"
109
118
  await wait_for_value(
110
- self.panda_device.data.num_captured, matcher, timeout=timeout
119
+ self.panda_data_block.num_captured, matcher, timeout=timeout
111
120
  )
112
121
 
113
122
  async def get_indices_written(self) -> int:
114
- return await self.panda_device.data.num_captured.get_value()
123
+ return await self.panda_data_block.num_captured.get_value()
115
124
 
116
125
  async def observe_indices_written(
117
126
  self, timeout=DEFAULT_TIMEOUT
118
127
  ) -> AsyncGenerator[int, None]:
119
128
  """Wait until a specific index is ready to be collected"""
120
129
  async for num_captured in observe_value(
121
- self.panda_device.data.num_captured, timeout
130
+ self.panda_data_block.num_captured, timeout
122
131
  ):
123
132
  yield num_captured // self._multiplier
124
133
 
@@ -128,10 +137,9 @@ class PandaHDFWriter(DetectorWriter):
128
137
  # TODO: fail if we get dropped frames
129
138
  if indices_written:
130
139
  if not self._file:
131
- self._file = _HDFFile(
132
- self._path_provider(),
133
- Path(await self.panda_device.data.hdf_directory.get_value())
134
- / Path(await self.panda_device.data.hdf_file_name.get_value()),
140
+ self._file = HDFFile(
141
+ Path(await self.panda_data_block.hdf_directory.get_value())
142
+ / Path(await self.panda_data_block.hdf_file_name.get_value()),
135
143
  self._datasets,
136
144
  )
137
145
  for doc in self._file.stream_resources():
@@ -141,6 +149,6 @@ class PandaHDFWriter(DetectorWriter):
141
149
 
142
150
  # Could put this function as default for StandardDetector
143
151
  async def close(self):
144
- await self.panda_device.data.capture.set(
152
+ await self.panda_data_block.capture.set(
145
153
  False, wait=True, timeout=DEFAULT_TIMEOUT
146
154
  )
@@ -1,13 +1,16 @@
1
- from .ensure_connected import ensure_connected
2
- from .fly import (
1
+ from ._ensure_connected import ensure_connected
2
+ from ._fly import (
3
3
  fly_and_collect,
4
4
  prepare_static_seq_table_flyer_and_detectors_with_same_trigger,
5
5
  time_resolved_fly_and_collect_with_static_seq_table,
6
6
  )
7
+ from ._nd_attributes import setup_ndattributes, setup_ndstats_sum
7
8
 
8
9
  __all__ = [
9
10
  "fly_and_collect",
10
11
  "prepare_static_seq_table_flyer_and_detectors_with_same_trigger",
11
12
  "time_resolved_fly_and_collect_with_static_seq_table",
12
13
  "ensure_connected",
14
+ "setup_ndattributes",
15
+ "setup_ndstats_sum",
13
16
  ]
@@ -1,7 +1,6 @@
1
1
  import bluesky.plan_stubs as bps
2
2
 
3
- from ophyd_async.core.device import Device
4
- from ophyd_async.core.utils import DEFAULT_TIMEOUT, wait_for_connection
3
+ from ophyd_async.core import DEFAULT_TIMEOUT, Device, wait_for_connection
5
4
 
6
5
 
7
6
  def ensure_connected(
@@ -3,10 +3,14 @@ from typing import List, Optional
3
3
  import bluesky.plan_stubs as bps
4
4
  from bluesky.utils import short_uid
5
5
 
6
- from ophyd_async.core.detector import DetectorTrigger, StandardDetector, TriggerInfo
7
- from ophyd_async.core.flyer import HardwareTriggeredFlyable
8
- from ophyd_async.core.utils import in_micros
9
- from ophyd_async.panda import (
6
+ from ophyd_async.core import (
7
+ DetectorTrigger,
8
+ StandardDetector,
9
+ StandardFlyer,
10
+ TriggerInfo,
11
+ in_micros,
12
+ )
13
+ from ophyd_async.fastcs.panda import (
10
14
  PcompDirectionOptions,
11
15
  PcompInfo,
12
16
  SeqTable,
@@ -17,7 +21,7 @@ from ophyd_async.panda import (
17
21
 
18
22
 
19
23
  def prepare_static_pcomp_flyer_and_detectors(
20
- flyer: HardwareTriggeredFlyable[PcompInfo],
24
+ flyer: StandardFlyer[PcompInfo],
21
25
  detectors: List[StandardDetector],
22
26
  pcomp_info: PcompInfo,
23
27
  trigger_info: TriggerInfo,
@@ -36,7 +40,7 @@ def prepare_static_pcomp_flyer_and_detectors(
36
40
 
37
41
 
38
42
  def prepare_static_seq_table_flyer_and_detectors_with_same_trigger(
39
- flyer: HardwareTriggeredFlyable[SeqTableInfo],
43
+ flyer: StandardFlyer[SeqTableInfo],
40
44
  detectors: List[StandardDetector],
41
45
  number_of_frames: int,
42
46
  exposure: float,
@@ -100,7 +104,7 @@ def prepare_static_seq_table_flyer_and_detectors_with_same_trigger(
100
104
 
101
105
  def fly_and_collect(
102
106
  stream_name: str,
103
- flyer: HardwareTriggeredFlyable[SeqTableInfo] | HardwareTriggeredFlyable[PcompInfo],
107
+ flyer: StandardFlyer[SeqTableInfo] | StandardFlyer[PcompInfo],
104
108
  detectors: List[StandardDetector],
105
109
  ):
106
110
  """Kickoff, complete and collect with a flyer and multiple detectors.
@@ -140,7 +144,7 @@ def fly_and_collect(
140
144
 
141
145
  def fly_and_collect_with_static_pcomp(
142
146
  stream_name: str,
143
- flyer: HardwareTriggeredFlyable[PcompInfo],
147
+ flyer: StandardFlyer[PcompInfo],
144
148
  detectors: List[StandardDetector],
145
149
  number_of_pulses: int,
146
150
  pulse_width: int,
@@ -166,7 +170,7 @@ def fly_and_collect_with_static_pcomp(
166
170
 
167
171
  def time_resolved_fly_and_collect_with_static_seq_table(
168
172
  stream_name: str,
169
- flyer: HardwareTriggeredFlyable[SeqTableInfo],
173
+ flyer: StandardFlyer[SeqTableInfo],
170
174
  detectors: List[StandardDetector],
171
175
  number_of_frames: int,
172
176
  exposure: float,
@@ -0,0 +1,63 @@
1
+ from typing import Sequence
2
+ from xml.etree import cElementTree as ET
3
+
4
+ import bluesky.plan_stubs as bps
5
+
6
+ from ophyd_async.core._device import Device
7
+ from ophyd_async.epics.adcore._core_io import NDArrayBaseIO
8
+ from ophyd_async.epics.adcore._utils import (
9
+ NDAttributeDataType,
10
+ NDAttributeParam,
11
+ NDAttributePv,
12
+ )
13
+
14
+
15
+ def setup_ndattributes(
16
+ device: NDArrayBaseIO, ndattributes: Sequence[NDAttributePv | NDAttributeParam]
17
+ ):
18
+ xml_text = ET.Element("Attributes")
19
+
20
+ for ndattribute in ndattributes:
21
+ if isinstance(ndattribute, NDAttributeParam):
22
+ ET.SubElement(
23
+ xml_text,
24
+ "Attribute",
25
+ name=ndattribute.name,
26
+ type="PARAM",
27
+ source=ndattribute.param,
28
+ addr=str(ndattribute.addr),
29
+ datatype=ndattribute.datatype.value,
30
+ description=ndattribute.description,
31
+ )
32
+ elif isinstance(ndattribute, NDAttributePv):
33
+ ET.SubElement(
34
+ xml_text,
35
+ "Attribute",
36
+ name=ndattribute.name,
37
+ type="EPICS_PV",
38
+ source=ndattribute.signal.source.split("ca://")[-1],
39
+ dbrtype=ndattribute.dbrtype.value,
40
+ description=ndattribute.description,
41
+ )
42
+ else:
43
+ raise ValueError(
44
+ f"Invalid type for ndattributes: {type(ndattribute)}. "
45
+ "Expected NDAttributePv or NDAttributeParam."
46
+ )
47
+ yield from bps.mv(device.nd_attributes_file, xml_text)
48
+
49
+
50
+ def setup_ndstats_sum(detector: Device):
51
+ yield from (
52
+ setup_ndattributes(
53
+ detector.hdf,
54
+ [
55
+ NDAttributeParam(
56
+ name=f"{detector.name}-sum",
57
+ param="NDPluginStatsTotal",
58
+ datatype=NDAttributeDataType.DOUBLE,
59
+ description="Sum of the array",
60
+ )
61
+ ],
62
+ )
63
+ )
@@ -1,11 +0,0 @@
1
- from .pattern_generator import PatternGenerator
2
- from .sim_pattern_detector_control import SimPatternDetectorControl
3
- from .sim_pattern_detector_writer import SimPatternDetectorWriter
4
- from .sim_pattern_generator import SimPatternDetector
5
-
6
- __all__ = [
7
- "PatternGenerator",
8
- "SimPatternDetectorControl",
9
- "SimPatternDetectorWriter",
10
- "SimPatternDetector",
11
- ]
@@ -1,3 +1,19 @@
1
- from .sim_motor import SimMotor
1
+ from ._pattern_detector import (
2
+ DATA_PATH,
3
+ SUM_PATH,
4
+ PatternDetector,
5
+ PatternDetectorController,
6
+ PatternDetectorWriter,
7
+ PatternGenerator,
8
+ )
9
+ from ._sim_motor import SimMotor
2
10
 
3
- __all__ = ["SimMotor"]
11
+ __all__ = [
12
+ "DATA_PATH",
13
+ "SUM_PATH",
14
+ "PatternGenerator",
15
+ "PatternDetector",
16
+ "PatternDetectorController",
17
+ "PatternDetectorWriter",
18
+ "SimMotor",
19
+ ]
@@ -0,0 +1,13 @@
1
+ from ._pattern_detector import PatternDetector
2
+ from ._pattern_detector_controller import PatternDetectorController
3
+ from ._pattern_detector_writer import PatternDetectorWriter
4
+ from ._pattern_generator import DATA_PATH, SUM_PATH, PatternGenerator
5
+
6
+ __all__ = [
7
+ "PatternDetector",
8
+ "PatternDetectorController",
9
+ "PatternDetectorWriter",
10
+ "DATA_PATH",
11
+ "SUM_PATH",
12
+ "PatternGenerator",
13
+ ]
@@ -2,20 +2,20 @@ from pathlib import Path
2
2
  from typing import Sequence
3
3
 
4
4
  from ophyd_async.core import (
5
+ AsyncReadable,
5
6
  FilenameProvider,
6
7
  PathProvider,
8
+ StandardDetector,
7
9
  StaticFilenameProvider,
8
10
  StaticPathProvider,
9
11
  )
10
- from ophyd_async.core.detector import StandardDetector
11
- from ophyd_async.protocols import AsyncReadable
12
- from ophyd_async.sim.pattern_generator import PatternGenerator
13
12
 
14
- from .sim_pattern_detector_control import SimPatternDetectorControl
15
- from .sim_pattern_detector_writer import SimPatternDetectorWriter
13
+ from ._pattern_detector_controller import PatternDetectorController
14
+ from ._pattern_detector_writer import PatternDetectorWriter
15
+ from ._pattern_generator import PatternGenerator
16
16
 
17
17
 
18
- class SimPatternDetector(StandardDetector):
18
+ class PatternDetector(StandardDetector):
19
19
  def __init__(
20
20
  self,
21
21
  path: Path,
@@ -25,12 +25,12 @@ class SimPatternDetector(StandardDetector):
25
25
  fp: FilenameProvider = StaticFilenameProvider(name)
26
26
  self.path_provider: PathProvider = StaticPathProvider(fp, path)
27
27
  self.pattern_generator = PatternGenerator()
28
- writer = SimPatternDetectorWriter(
28
+ writer = PatternDetectorWriter(
29
29
  pattern_generator=self.pattern_generator,
30
30
  path_provider=self.path_provider,
31
31
  name_provider=lambda: self.name,
32
32
  )
33
- controller = SimPatternDetectorControl(
33
+ controller = PatternDetectorController(
34
34
  pattern_generator=self.pattern_generator,
35
35
  path_provider=self.path_provider,
36
36
  )
@@ -1,13 +1,12 @@
1
1
  import asyncio
2
2
  from typing import Optional
3
3
 
4
- from ophyd_async.core import PathProvider
5
- from ophyd_async.core.async_status import AsyncStatus
6
- from ophyd_async.core.detector import DetectorControl, DetectorTrigger
7
- from ophyd_async.sim.pattern_generator import PatternGenerator
4
+ from ophyd_async.core import AsyncStatus, DetectorControl, DetectorTrigger, PathProvider
8
5
 
6
+ from ._pattern_generator import PatternGenerator
9
7
 
10
- class SimPatternDetectorControl(DetectorControl):
8
+
9
+ class PatternDetectorController(DetectorControl):
11
10
  def __init__(
12
11
  self,
13
12
  pattern_generator: PatternGenerator,
@@ -15,6 +14,8 @@ class SimPatternDetectorControl(DetectorControl):
15
14
  exposure: float = 0.1,
16
15
  ) -> None:
17
16
  self.pattern_generator: PatternGenerator = pattern_generator
17
+ if exposure is None:
18
+ exposure = 0.1
18
19
  self.pattern_generator.set_exposure(exposure)
19
20
  self.path_provider: PathProvider = path_provider
20
21
  self.task: Optional[asyncio.Task] = None
@@ -26,7 +27,8 @@ class SimPatternDetectorControl(DetectorControl):
26
27
  trigger: DetectorTrigger = DetectorTrigger.internal,
27
28
  exposure: Optional[float] = 0.01,
28
29
  ) -> AsyncStatus:
29
- assert exposure is not None
30
+ if exposure is None:
31
+ exposure = 0.1
30
32
  period: float = exposure + self.get_deadtime(exposure)
31
33
  task = asyncio.create_task(
32
34
  self._coroutine_for_image_writing(exposure, period, num)
@@ -43,7 +45,7 @@ class SimPatternDetectorControl(DetectorControl):
43
45
  pass
44
46
  self.task = None
45
47
 
46
- def get_deadtime(self, exposure: float) -> float:
48
+ def get_deadtime(self, exposure: float | None) -> float:
47
49
  return 0.001
48
50
 
49
51
  async def _coroutine_for_image_writing(
@@ -2,12 +2,12 @@ from typing import AsyncGenerator, AsyncIterator, Dict
2
2
 
3
3
  from bluesky.protocols import DataKey
4
4
 
5
- from ophyd_async.core import NameProvider, PathProvider
6
- from ophyd_async.core.detector import DetectorWriter
7
- from ophyd_async.sim.pattern_generator import PatternGenerator
5
+ from ophyd_async.core import DetectorWriter, NameProvider, PathProvider
8
6
 
7
+ from ._pattern_generator import PatternGenerator
9
8
 
10
- class SimPatternDetectorWriter(DetectorWriter):
9
+
10
+ class PatternDetectorWriter(DetectorWriter):
11
11
  pattern_generator: PatternGenerator
12
12
 
13
13
  def __init__(
@@ -5,10 +5,14 @@ import h5py
5
5
  import numpy as np
6
6
  from bluesky.protocols import DataKey, StreamAsset
7
7
 
8
- from ophyd_async.core import PathProvider
9
- from ophyd_async.core.signal import observe_value, soft_signal_r_and_setter
10
- from ophyd_async.core.utils import DEFAULT_TIMEOUT
11
- from ophyd_async.epics.areadetector.writers.general_hdffile import _HDFDataset, _HDFFile
8
+ from ophyd_async.core import (
9
+ DEFAULT_TIMEOUT,
10
+ HDFDataset,
11
+ HDFFile,
12
+ PathProvider,
13
+ observe_value,
14
+ soft_signal_r_and_setter,
15
+ )
12
16
 
13
17
  # raw data path
14
18
  DATA_PATH = "/entry/data/data"
@@ -56,7 +60,7 @@ class PatternGenerator:
56
60
  generate_gaussian_blob(width=detector_width, height=detector_height)
57
61
  * MAX_UINT8_VALUE
58
62
  )
59
- self._hdf_stream_provider: Optional[_HDFFile] = None
63
+ self._hdf_stream_provider: Optional[HDFFile] = None
60
64
  self._handle_for_h5_file: Optional[h5py.File] = None
61
65
  self.target_path: Optional[Path] = None
62
66
 
@@ -135,13 +139,13 @@ class PatternGenerator:
135
139
  # cache state to self
136
140
  # Add the main data
137
141
  self._datasets = [
138
- _HDFDataset(
142
+ HDFDataset(
139
143
  data_key=name,
140
144
  dataset=DATA_PATH,
141
145
  shape=(self.height, self.width),
142
146
  multiplier=multiplier,
143
147
  ),
144
- _HDFDataset(
148
+ HDFDataset(
145
149
  f"{name}-sum",
146
150
  dataset=SUM_PATH,
147
151
  shape=(),
@@ -162,8 +166,7 @@ class PatternGenerator:
162
166
 
163
167
  def _get_new_path(self, path_provider: PathProvider) -> Path:
164
168
  info = path_provider(device_name="pattern")
165
- filename = info.filename
166
- new_path: Path = info.root / info.resource_dir / filename
169
+ new_path: Path = info.directory_path / info.filename
167
170
  return new_path
168
171
 
169
172
  async def collect_stream_docs(
@@ -183,8 +186,7 @@ class PatternGenerator:
183
186
  # until the first frame comes in
184
187
  if not self._hdf_stream_provider:
185
188
  assert self.target_path, "open file has not been called"
186
- self._hdf_stream_provider = _HDFFile(
187
- self._path_provider(),
189
+ self._hdf_stream_provider = HDFFile(
188
190
  self.target_path,
189
191
  self._datasets,
190
192
  )
@@ -4,15 +4,17 @@ import time
4
4
 
5
5
  from bluesky.protocols import Movable, Stoppable
6
6
 
7
- from ophyd_async.core import StandardReadable
8
- from ophyd_async.core.async_status import AsyncStatus, WatchableAsyncStatus
9
- from ophyd_async.core.signal import (
7
+ from ophyd_async.core import (
8
+ AsyncStatus,
9
+ ConfigSignal,
10
+ HintedSignal,
11
+ StandardReadable,
12
+ WatchableAsyncStatus,
13
+ WatcherUpdate,
10
14
  observe_value,
11
15
  soft_signal_r_and_setter,
12
16
  soft_signal_rw,
13
17
  )
14
- from ophyd_async.core.standard_readable import ConfigSignal, HintedSignal
15
- from ophyd_async.core.utils import WatcherUpdate
16
18
 
17
19
 
18
20
  class SimMotor(StandardReadable, Movable, Stoppable):
File without changes
File without changes