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.
- ophyd_async/_version.py +2 -2
- ophyd_async/core/__init__.py +86 -63
- ophyd_async/core/{detector.py → _detector.py} +18 -23
- ophyd_async/core/{device.py → _device.py} +19 -7
- ophyd_async/core/{device_save_loader.py → _device_save_loader.py} +3 -3
- ophyd_async/core/{flyer.py → _flyer.py} +6 -8
- ophyd_async/core/_hdf_dataset.py +97 -0
- ophyd_async/{log.py → core/_log.py} +11 -3
- ophyd_async/core/{mock_signal_backend.py → _mock_signal_backend.py} +3 -3
- ophyd_async/core/{mock_signal_utils.py → _mock_signal_utils.py} +3 -4
- ophyd_async/{protocols.py → core/_protocol.py} +1 -1
- ophyd_async/core/_providers.py +186 -24
- ophyd_async/core/{standard_readable.py → _readable.py} +6 -16
- ophyd_async/core/{signal.py → _signal.py} +39 -16
- ophyd_async/core/{signal_backend.py → _signal_backend.py} +4 -13
- ophyd_async/core/{soft_signal_backend.py → _soft_signal_backend.py} +24 -18
- ophyd_async/core/{async_status.py → _status.py} +3 -11
- ophyd_async/epics/adaravis/__init__.py +9 -0
- ophyd_async/epics/{areadetector/aravis.py → adaravis/_aravis.py} +12 -14
- ophyd_async/epics/{areadetector/controllers/aravis_controller.py → adaravis/_aravis_controller.py} +8 -10
- ophyd_async/epics/{areadetector/drivers/aravis_driver.py → adaravis/_aravis_io.py} +6 -3
- ophyd_async/epics/adcore/__init__.py +36 -0
- ophyd_async/epics/adcore/_core_io.py +114 -0
- ophyd_async/epics/{areadetector/drivers/ad_base.py → adcore/_core_logic.py} +17 -52
- ophyd_async/epics/{areadetector/writers/hdf_writer.py → adcore/_hdf_writer.py} +36 -18
- ophyd_async/epics/{areadetector/single_trigger_det.py → adcore/_single_trigger.py} +5 -6
- ophyd_async/epics/{areadetector/utils.py → adcore/_utils.py} +29 -0
- ophyd_async/epics/adkinetix/__init__.py +9 -0
- ophyd_async/epics/{areadetector/kinetix.py → adkinetix/_kinetix.py} +12 -14
- ophyd_async/epics/{areadetector/controllers/kinetix_controller.py → adkinetix/_kinetix_controller.py} +6 -9
- ophyd_async/epics/{areadetector/drivers/kinetix_driver.py → adkinetix/_kinetix_io.py} +5 -4
- ophyd_async/epics/adpilatus/__init__.py +11 -0
- ophyd_async/epics/{areadetector/pilatus.py → adpilatus/_pilatus.py} +12 -16
- ophyd_async/epics/{areadetector/controllers/pilatus_controller.py → adpilatus/_pilatus_controller.py} +14 -16
- ophyd_async/epics/{areadetector/drivers/pilatus_driver.py → adpilatus/_pilatus_io.py} +5 -3
- ophyd_async/epics/adsimdetector/__init__.py +7 -0
- ophyd_async/epics/adsimdetector/_sim.py +34 -0
- ophyd_async/epics/{areadetector/controllers/ad_sim_controller.py → adsimdetector/_sim_controller.py} +8 -14
- ophyd_async/epics/advimba/__init__.py +9 -0
- ophyd_async/epics/advimba/_vimba.py +43 -0
- ophyd_async/epics/{areadetector/controllers/vimba_controller.py → advimba/_vimba_controller.py} +6 -14
- ophyd_async/epics/{areadetector/drivers/vimba_driver.py → advimba/_vimba_io.py} +5 -4
- ophyd_async/epics/demo/__init__.py +9 -132
- ophyd_async/epics/demo/_mover.py +97 -0
- ophyd_async/epics/demo/_sensor.py +36 -0
- ophyd_async/epics/motor.py +228 -0
- ophyd_async/epics/pvi/__init__.py +2 -2
- ophyd_async/epics/pvi/{pvi.py → _pvi.py} +17 -14
- ophyd_async/epics/signal/__init__.py +7 -1
- ophyd_async/epics/{_backend → signal}/_aioca.py +6 -2
- ophyd_async/epics/{_backend/common.py → signal/_common.py} +4 -2
- ophyd_async/epics/signal/_epics_transport.py +3 -3
- ophyd_async/epics/{_backend → signal}/_p4p.py +53 -4
- ophyd_async/epics/signal/{signal.py → _signal.py} +10 -9
- ophyd_async/fastcs/odin/__init__.py +0 -0
- ophyd_async/{panda → fastcs/panda}/__init__.py +28 -9
- ophyd_async/{panda → fastcs/panda}/_common_blocks.py +24 -3
- ophyd_async/{panda → fastcs/panda}/_hdf_panda.py +6 -9
- ophyd_async/{panda/writers → fastcs/panda}/_hdf_writer.py +24 -14
- ophyd_async/{panda → fastcs/panda}/_panda_controller.py +2 -1
- ophyd_async/{panda → fastcs/panda}/_table.py +20 -18
- ophyd_async/fastcs/panda/_trigger.py +90 -0
- ophyd_async/plan_stubs/__init__.py +2 -2
- ophyd_async/plan_stubs/_ensure_connected.py +26 -0
- ophyd_async/plan_stubs/{fly.py → _fly.py} +67 -12
- ophyd_async/sim/__init__.py +0 -11
- ophyd_async/sim/demo/__init__.py +18 -2
- ophyd_async/sim/demo/_pattern_detector/__init__.py +13 -0
- ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +42 -0
- ophyd_async/sim/{sim_pattern_detector_control.py → demo/_pattern_detector/_pattern_detector_controller.py} +6 -7
- ophyd_async/sim/{sim_pattern_detector_writer.py → demo/_pattern_detector/_pattern_detector_writer.py} +12 -8
- ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +211 -0
- ophyd_async/sim/demo/{sim_motor.py → _sim_motor.py} +7 -5
- ophyd_async/sim/testing/__init__.py +0 -0
- ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/METADATA +7 -2
- ophyd_async-0.5.0.dist-info/RECORD +89 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/WHEEL +1 -1
- ophyd_async/epics/areadetector/__init__.py +0 -23
- ophyd_async/epics/areadetector/controllers/__init__.py +0 -5
- ophyd_async/epics/areadetector/drivers/__init__.py +0 -23
- ophyd_async/epics/areadetector/vimba.py +0 -43
- ophyd_async/epics/areadetector/writers/__init__.py +0 -5
- ophyd_async/epics/areadetector/writers/_hdfdataset.py +0 -10
- ophyd_async/epics/areadetector/writers/_hdffile.py +0 -54
- ophyd_async/epics/areadetector/writers/nd_file_hdf.py +0 -40
- ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -38
- ophyd_async/epics/demo/demo_ad_sim_detector.py +0 -35
- ophyd_async/epics/motion/__init__.py +0 -3
- ophyd_async/epics/motion/motor.py +0 -97
- ophyd_async/panda/_trigger.py +0 -39
- ophyd_async/panda/writers/__init__.py +0 -3
- ophyd_async/panda/writers/_panda_hdf_file.py +0 -54
- ophyd_async/plan_stubs/ensure_connected.py +0 -22
- ophyd_async/sim/pattern_generator.py +0 -318
- ophyd_async/sim/sim_pattern_generator.py +0 -35
- ophyd_async-0.3.4a1.dist-info/RECORD +0 -86
- /ophyd_async/core/{utils.py → _utils.py} +0 -0
- /ophyd_async/{epics/_backend → fastcs}/__init__.py +0 -0
- /ophyd_async/{panda → fastcs/panda}/_utils.py +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/LICENSE +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
|
-
from bluesky.protocols import Movable, Stoppable
|
|
4
|
-
|
|
5
|
-
from ophyd_async.core import (
|
|
6
|
-
ConfigSignal,
|
|
7
|
-
HintedSignal,
|
|
8
|
-
StandardReadable,
|
|
9
|
-
WatchableAsyncStatus,
|
|
10
|
-
)
|
|
11
|
-
from ophyd_async.core.signal import observe_value
|
|
12
|
-
from ophyd_async.core.utils import (
|
|
13
|
-
DEFAULT_TIMEOUT,
|
|
14
|
-
CalculatableTimeout,
|
|
15
|
-
CalculateTimeout,
|
|
16
|
-
WatcherUpdate,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
from ..signal.signal import epics_signal_r, epics_signal_rw, epics_signal_x
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class Motor(StandardReadable, Movable, Stoppable):
|
|
23
|
-
"""Device that moves a motor record"""
|
|
24
|
-
|
|
25
|
-
def __init__(self, prefix: str, name="") -> None:
|
|
26
|
-
# Define some signals
|
|
27
|
-
with self.add_children_as_readables(ConfigSignal):
|
|
28
|
-
self.motor_egu = epics_signal_r(str, prefix + ".EGU")
|
|
29
|
-
self.velocity = epics_signal_rw(float, prefix + ".VELO")
|
|
30
|
-
|
|
31
|
-
with self.add_children_as_readables(HintedSignal):
|
|
32
|
-
self.user_readback = epics_signal_r(float, prefix + ".RBV")
|
|
33
|
-
|
|
34
|
-
self.user_setpoint = epics_signal_rw(float, prefix + ".VAL")
|
|
35
|
-
self.max_velocity = epics_signal_r(float, prefix + ".VMAX")
|
|
36
|
-
self.acceleration_time = epics_signal_rw(float, prefix + ".ACCL")
|
|
37
|
-
self.precision = epics_signal_r(int, prefix + ".PREC")
|
|
38
|
-
self.deadband = epics_signal_r(float, prefix + ".RDBD")
|
|
39
|
-
self.motor_done_move = epics_signal_r(int, prefix + ".DMOV")
|
|
40
|
-
self.low_limit_travel = epics_signal_rw(float, prefix + ".LLM")
|
|
41
|
-
self.high_limit_travel = epics_signal_rw(float, prefix + ".HLM")
|
|
42
|
-
|
|
43
|
-
self.motor_stop = epics_signal_x(prefix + ".STOP")
|
|
44
|
-
# Whether set() should complete successfully or not
|
|
45
|
-
self._set_success = True
|
|
46
|
-
super().__init__(name=name)
|
|
47
|
-
|
|
48
|
-
def set_name(self, name: str):
|
|
49
|
-
super().set_name(name)
|
|
50
|
-
# Readback should be named the same as its parent in read()
|
|
51
|
-
self.user_readback.set_name(name)
|
|
52
|
-
|
|
53
|
-
@WatchableAsyncStatus.wrap
|
|
54
|
-
async def set(
|
|
55
|
-
self, new_position: float, timeout: CalculatableTimeout = CalculateTimeout
|
|
56
|
-
):
|
|
57
|
-
self._set_success = True
|
|
58
|
-
(
|
|
59
|
-
old_position,
|
|
60
|
-
units,
|
|
61
|
-
precision,
|
|
62
|
-
velocity,
|
|
63
|
-
acceleration_time,
|
|
64
|
-
) = await asyncio.gather(
|
|
65
|
-
self.user_setpoint.get_value(),
|
|
66
|
-
self.motor_egu.get_value(),
|
|
67
|
-
self.precision.get_value(),
|
|
68
|
-
self.velocity.get_value(),
|
|
69
|
-
self.acceleration_time.get_value(),
|
|
70
|
-
)
|
|
71
|
-
if timeout is CalculateTimeout:
|
|
72
|
-
assert velocity > 0, "Motor has zero velocity"
|
|
73
|
-
timeout = (
|
|
74
|
-
abs(new_position - old_position) / velocity
|
|
75
|
-
+ 2 * acceleration_time
|
|
76
|
-
+ DEFAULT_TIMEOUT
|
|
77
|
-
)
|
|
78
|
-
move_status = self.user_setpoint.set(new_position, wait=True, timeout=timeout)
|
|
79
|
-
async for current_position in observe_value(
|
|
80
|
-
self.user_readback, done_status=move_status
|
|
81
|
-
):
|
|
82
|
-
yield WatcherUpdate(
|
|
83
|
-
current=current_position,
|
|
84
|
-
initial=old_position,
|
|
85
|
-
target=new_position,
|
|
86
|
-
name=self.name,
|
|
87
|
-
unit=units,
|
|
88
|
-
precision=precision,
|
|
89
|
-
)
|
|
90
|
-
if not self._set_success:
|
|
91
|
-
raise RuntimeError("Motor was stopped")
|
|
92
|
-
|
|
93
|
-
async def stop(self, success=False):
|
|
94
|
-
self._set_success = success
|
|
95
|
-
# Put with completion will never complete as we are waiting for completion on
|
|
96
|
-
# the move above, so need to pass wait=False
|
|
97
|
-
await self.motor_stop.trigger(wait=False)
|
ophyd_async/panda/_trigger.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from dataclasses import dataclass
|
|
3
|
-
|
|
4
|
-
from ophyd_async.core import TriggerLogic, wait_for_value
|
|
5
|
-
from ophyd_async.panda import SeqBlock, SeqTable, TimeUnits
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@dataclass
|
|
9
|
-
class SeqTableInfo:
|
|
10
|
-
sequence_table: SeqTable
|
|
11
|
-
repeats: int
|
|
12
|
-
prescale_as_us: float = 1 # microseconds
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class StaticSeqTableTriggerLogic(TriggerLogic[SeqTableInfo]):
|
|
16
|
-
def __init__(self, seq: SeqBlock) -> None:
|
|
17
|
-
self.seq = seq
|
|
18
|
-
|
|
19
|
-
async def prepare(self, value: SeqTableInfo):
|
|
20
|
-
await asyncio.gather(
|
|
21
|
-
self.seq.prescale_units.set(TimeUnits.us),
|
|
22
|
-
self.seq.enable.set("ZERO"),
|
|
23
|
-
)
|
|
24
|
-
await asyncio.gather(
|
|
25
|
-
self.seq.prescale.set(value.prescale_as_us),
|
|
26
|
-
self.seq.repeats.set(value.repeats),
|
|
27
|
-
self.seq.table.set(value.sequence_table),
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
async def kickoff(self) -> None:
|
|
31
|
-
await self.seq.enable.set("ONE")
|
|
32
|
-
await wait_for_value(self.seq.active, True, timeout=1)
|
|
33
|
-
|
|
34
|
-
async def complete(self) -> None:
|
|
35
|
-
await wait_for_value(self.seq.active, False, timeout=None)
|
|
36
|
-
|
|
37
|
-
async def stop(self):
|
|
38
|
-
await self.seq.enable.set("ZERO")
|
|
39
|
-
await wait_for_value(self.seq.active, False, timeout=1)
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Iterator, List
|
|
4
|
-
|
|
5
|
-
from event_model import StreamDatum, StreamResource, compose_stream_resource
|
|
6
|
-
|
|
7
|
-
from ophyd_async.core import DirectoryInfo
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@dataclass
|
|
11
|
-
class _HDFDataset:
|
|
12
|
-
data_key: str
|
|
13
|
-
internal_path: str
|
|
14
|
-
shape: List[int]
|
|
15
|
-
multiplier: int
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class _HDFFile:
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
directory_info: DirectoryInfo,
|
|
22
|
-
full_file_name: Path,
|
|
23
|
-
datasets: List[_HDFDataset],
|
|
24
|
-
) -> None:
|
|
25
|
-
self._last_emitted = 0
|
|
26
|
-
self._bundles = [
|
|
27
|
-
compose_stream_resource(
|
|
28
|
-
spec="AD_HDF5_SWMR_SLICE",
|
|
29
|
-
root=str(directory_info.root),
|
|
30
|
-
data_key=ds.data_key,
|
|
31
|
-
resource_path=(f"{str(directory_info.root)}/{full_file_name}"),
|
|
32
|
-
resource_kwargs={
|
|
33
|
-
"path": ds.internal_path,
|
|
34
|
-
"multiplier": ds.multiplier,
|
|
35
|
-
"timestamps": "/entry/instrument/NDAttributes/NDArrayTimeStamp",
|
|
36
|
-
},
|
|
37
|
-
)
|
|
38
|
-
for ds in datasets
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
def stream_resources(self) -> Iterator[StreamResource]:
|
|
42
|
-
for bundle in self._bundles:
|
|
43
|
-
yield bundle.stream_resource_doc
|
|
44
|
-
|
|
45
|
-
def stream_data(self, indices_written: int) -> Iterator[StreamDatum]:
|
|
46
|
-
# Indices are relative to resource
|
|
47
|
-
if indices_written > self._last_emitted:
|
|
48
|
-
indices = {
|
|
49
|
-
"start": self._last_emitted,
|
|
50
|
-
"stop": indices_written,
|
|
51
|
-
}
|
|
52
|
-
self._last_emitted = indices_written
|
|
53
|
-
for bundle in self._bundles:
|
|
54
|
-
yield bundle.compose_stream_datum(indices)
|
|
@@ -1,22 +0,0 @@
|
|
|
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
|
-
)
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import (
|
|
4
|
-
Any,
|
|
5
|
-
AsyncGenerator,
|
|
6
|
-
AsyncIterator,
|
|
7
|
-
Dict,
|
|
8
|
-
Iterator,
|
|
9
|
-
List,
|
|
10
|
-
Optional,
|
|
11
|
-
Sequence,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
import h5py
|
|
15
|
-
import numpy as np
|
|
16
|
-
from bluesky.protocols import DataKey, StreamAsset
|
|
17
|
-
from event_model import (
|
|
18
|
-
ComposeStreamResource,
|
|
19
|
-
ComposeStreamResourceBundle,
|
|
20
|
-
StreamDatum,
|
|
21
|
-
StreamRange,
|
|
22
|
-
StreamResource,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
from ophyd_async.core import DirectoryInfo, DirectoryProvider
|
|
26
|
-
from ophyd_async.core.mock_signal_backend import MockSignalBackend
|
|
27
|
-
from ophyd_async.core.signal import SignalR, observe_value
|
|
28
|
-
from ophyd_async.core.utils import DEFAULT_TIMEOUT
|
|
29
|
-
|
|
30
|
-
# raw data path
|
|
31
|
-
DATA_PATH = "/entry/data/data"
|
|
32
|
-
|
|
33
|
-
# pixel sum path
|
|
34
|
-
SUM_PATH = "/entry/sum"
|
|
35
|
-
|
|
36
|
-
MAX_UINT8_VALUE = np.iinfo(np.uint8).max
|
|
37
|
-
|
|
38
|
-
SLICE_NAME = "AD_HDF5_SWMR_SLICE"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@dataclass
|
|
42
|
-
class DatasetConfig:
|
|
43
|
-
name: str
|
|
44
|
-
shape: Sequence[int]
|
|
45
|
-
maxshape: tuple[Any, ...] = (None,)
|
|
46
|
-
path: Optional[str] = None
|
|
47
|
-
multiplier: Optional[int] = 1
|
|
48
|
-
dtype: Optional[Any] = None
|
|
49
|
-
fillvalue: Optional[int] = None
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def get_full_file_description(
|
|
53
|
-
datasets: List[DatasetConfig], outer_shape: tuple[int, ...]
|
|
54
|
-
):
|
|
55
|
-
full_file_description: Dict[str, DataKey] = {}
|
|
56
|
-
for d in datasets:
|
|
57
|
-
source = f"soft://{d.name}"
|
|
58
|
-
shape = outer_shape + tuple(d.shape)
|
|
59
|
-
dtype = "number" if d.shape == [1] else "array"
|
|
60
|
-
descriptor = DataKey(
|
|
61
|
-
source=source, shape=shape, dtype=dtype, external="STREAM:"
|
|
62
|
-
)
|
|
63
|
-
key = d.name.replace("/", "_")
|
|
64
|
-
full_file_description[key] = descriptor
|
|
65
|
-
return full_file_description
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def generate_gaussian_blob(height: int, width: int) -> np.ndarray:
|
|
69
|
-
"""Make a Gaussian Blob with float values in range 0..1"""
|
|
70
|
-
x, y = np.meshgrid(np.linspace(-1, 1, width), np.linspace(-1, 1, height))
|
|
71
|
-
d = np.sqrt(x * x + y * y)
|
|
72
|
-
blob = np.exp(-(d**2))
|
|
73
|
-
return blob
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def generate_interesting_pattern(x: float, y: float) -> float:
|
|
77
|
-
"""This function is interesting in x and y in range -10..10, returning
|
|
78
|
-
a float value in range 0..1
|
|
79
|
-
"""
|
|
80
|
-
z = 0.5 + (np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)) / 2
|
|
81
|
-
return z
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class HdfStreamProvider:
|
|
85
|
-
def __init__(
|
|
86
|
-
self,
|
|
87
|
-
directory_info: DirectoryInfo,
|
|
88
|
-
full_file_name: Path,
|
|
89
|
-
datasets: List[DatasetConfig],
|
|
90
|
-
) -> None:
|
|
91
|
-
self._last_emitted = 0
|
|
92
|
-
self._bundles: List[ComposeStreamResourceBundle] = self._compose_bundles(
|
|
93
|
-
directory_info, full_file_name, datasets
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
def _compose_bundles(
|
|
97
|
-
self,
|
|
98
|
-
directory_info: DirectoryInfo,
|
|
99
|
-
full_file_name: Path,
|
|
100
|
-
datasets: List[DatasetConfig],
|
|
101
|
-
) -> List[StreamAsset]:
|
|
102
|
-
path = str(full_file_name.relative_to(directory_info.root))
|
|
103
|
-
root = str(directory_info.root)
|
|
104
|
-
bundler_composer = ComposeStreamResource()
|
|
105
|
-
|
|
106
|
-
bundles: List[ComposeStreamResourceBundle] = []
|
|
107
|
-
|
|
108
|
-
bundles = [
|
|
109
|
-
bundler_composer(
|
|
110
|
-
spec=SLICE_NAME,
|
|
111
|
-
root=root,
|
|
112
|
-
resource_path=path,
|
|
113
|
-
data_key=d.name.replace("/", "_"),
|
|
114
|
-
resource_kwargs={
|
|
115
|
-
"path": d.path,
|
|
116
|
-
"multiplier": d.multiplier,
|
|
117
|
-
"timestamps": "/entry/instrument/NDAttributes/NDArrayTimeStamp",
|
|
118
|
-
},
|
|
119
|
-
)
|
|
120
|
-
for d in datasets
|
|
121
|
-
]
|
|
122
|
-
return bundles
|
|
123
|
-
|
|
124
|
-
def stream_resources(self) -> Iterator[StreamResource]:
|
|
125
|
-
for bundle in self._bundles:
|
|
126
|
-
yield bundle.stream_resource_doc
|
|
127
|
-
|
|
128
|
-
def stream_data(self, indices_written: int) -> Iterator[StreamDatum]:
|
|
129
|
-
# Indices are relative to resource
|
|
130
|
-
if indices_written > self._last_emitted:
|
|
131
|
-
updated_stream_range = StreamRange(
|
|
132
|
-
start=self._last_emitted,
|
|
133
|
-
stop=indices_written,
|
|
134
|
-
)
|
|
135
|
-
self._last_emitted = indices_written
|
|
136
|
-
for bundle in self._bundles:
|
|
137
|
-
yield bundle.compose_stream_datum(indices=updated_stream_range)
|
|
138
|
-
return None
|
|
139
|
-
|
|
140
|
-
def close(self) -> None:
|
|
141
|
-
for bundle in self._bundles:
|
|
142
|
-
bundle.close()
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
class PatternGenerator:
|
|
146
|
-
def __init__(
|
|
147
|
-
self,
|
|
148
|
-
saturation_exposure_time: float = 1,
|
|
149
|
-
detector_width: int = 320,
|
|
150
|
-
detector_height: int = 240,
|
|
151
|
-
) -> None:
|
|
152
|
-
self.saturation_exposure_time = saturation_exposure_time
|
|
153
|
-
self.exposure = saturation_exposure_time
|
|
154
|
-
self.x = 0.0
|
|
155
|
-
self.y = 0.0
|
|
156
|
-
self.height = detector_height
|
|
157
|
-
self.width = detector_width
|
|
158
|
-
self.written_images_counter: int = 0
|
|
159
|
-
|
|
160
|
-
# it automatically initializes to 0
|
|
161
|
-
self.signal_backend = MockSignalBackend(int)
|
|
162
|
-
self.mock_signal = SignalR(self.signal_backend)
|
|
163
|
-
blob = np.array(
|
|
164
|
-
generate_gaussian_blob(width=detector_width, height=detector_height)
|
|
165
|
-
* MAX_UINT8_VALUE
|
|
166
|
-
)
|
|
167
|
-
self.STARTING_BLOB = blob
|
|
168
|
-
self._hdf_stream_provider: Optional[HdfStreamProvider] = None
|
|
169
|
-
self._handle_for_h5_file: Optional[h5py.File] = None
|
|
170
|
-
self.target_path: Optional[Path] = None
|
|
171
|
-
|
|
172
|
-
async def write_image_to_file(self) -> None:
|
|
173
|
-
assert self._handle_for_h5_file, "no file has been opened!"
|
|
174
|
-
# prepare - resize the fixed hdf5 data structure
|
|
175
|
-
# so that the new image can be written
|
|
176
|
-
new_layer = self.written_images_counter + 1
|
|
177
|
-
target_dimensions = (new_layer, self.height, self.width)
|
|
178
|
-
|
|
179
|
-
# generate the simulated data
|
|
180
|
-
intensity: float = generate_interesting_pattern(self.x, self.y)
|
|
181
|
-
detector_data: np.uint8 = np.uint8(
|
|
182
|
-
self.STARTING_BLOB
|
|
183
|
-
* intensity
|
|
184
|
-
* self.exposure
|
|
185
|
-
/ self.saturation_exposure_time
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
self._handle_for_h5_file[DATA_PATH].resize(target_dimensions)
|
|
189
|
-
|
|
190
|
-
print(f"writing image {new_layer}")
|
|
191
|
-
assert self._handle_for_h5_file, "no file has been opened!"
|
|
192
|
-
self._handle_for_h5_file[DATA_PATH].resize(target_dimensions)
|
|
193
|
-
|
|
194
|
-
self._handle_for_h5_file[SUM_PATH].resize((new_layer,))
|
|
195
|
-
|
|
196
|
-
# write data to disc (intermediate step)
|
|
197
|
-
self._handle_for_h5_file[DATA_PATH][self.written_images_counter] = detector_data
|
|
198
|
-
self._handle_for_h5_file[SUM_PATH][self.written_images_counter] = np.sum(
|
|
199
|
-
detector_data
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
# save metadata - so that it's discoverable
|
|
203
|
-
self._handle_for_h5_file[DATA_PATH].flush()
|
|
204
|
-
self._handle_for_h5_file[SUM_PATH].flush()
|
|
205
|
-
|
|
206
|
-
# counter increment is last
|
|
207
|
-
# as only at this point the new data is visible from the outside
|
|
208
|
-
self.written_images_counter += 1
|
|
209
|
-
await self.signal_backend.put(self.written_images_counter)
|
|
210
|
-
|
|
211
|
-
def set_exposure(self, value: float) -> None:
|
|
212
|
-
self.exposure = value
|
|
213
|
-
|
|
214
|
-
def set_x(self, value: float) -> None:
|
|
215
|
-
self.x = value
|
|
216
|
-
|
|
217
|
-
def set_y(self, value: float) -> None:
|
|
218
|
-
self.y = value
|
|
219
|
-
|
|
220
|
-
async def open_file(
|
|
221
|
-
self, directory: DirectoryProvider, multiplier: int = 1
|
|
222
|
-
) -> Dict[str, DataKey]:
|
|
223
|
-
await self.mock_signal.connect()
|
|
224
|
-
|
|
225
|
-
self.target_path = self._get_new_path(directory)
|
|
226
|
-
|
|
227
|
-
self._handle_for_h5_file = h5py.File(self.target_path, "w", libver="latest")
|
|
228
|
-
|
|
229
|
-
assert self._handle_for_h5_file, "not loaded the file right"
|
|
230
|
-
|
|
231
|
-
datasets = self._get_datasets()
|
|
232
|
-
for d in datasets:
|
|
233
|
-
self._handle_for_h5_file.create_dataset(
|
|
234
|
-
name=d.name,
|
|
235
|
-
shape=d.shape,
|
|
236
|
-
dtype=d.dtype,
|
|
237
|
-
maxshape=d.maxshape,
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
# once datasets written, can switch the model to single writer multiple reader
|
|
241
|
-
self._handle_for_h5_file.swmr_mode = True
|
|
242
|
-
|
|
243
|
-
outer_shape = (multiplier,) if multiplier > 1 else ()
|
|
244
|
-
full_file_description = get_full_file_description(datasets, outer_shape)
|
|
245
|
-
|
|
246
|
-
# cache state to self
|
|
247
|
-
self._datasets = datasets
|
|
248
|
-
self.multiplier = multiplier
|
|
249
|
-
self._directory_provider = directory
|
|
250
|
-
return full_file_description
|
|
251
|
-
|
|
252
|
-
def _get_new_path(self, directory: DirectoryProvider) -> Path:
|
|
253
|
-
info = directory()
|
|
254
|
-
filename = f"{info.prefix}pattern{info.suffix}.h5"
|
|
255
|
-
new_path: Path = info.root / info.resource_dir / filename
|
|
256
|
-
return new_path
|
|
257
|
-
|
|
258
|
-
def _get_datasets(self) -> List[DatasetConfig]:
|
|
259
|
-
raw_dataset = DatasetConfig(
|
|
260
|
-
# name=data_name,
|
|
261
|
-
name=DATA_PATH,
|
|
262
|
-
dtype=np.uint8,
|
|
263
|
-
shape=(1, self.height, self.width),
|
|
264
|
-
maxshape=(None, self.height, self.width),
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
sum_dataset = DatasetConfig(
|
|
268
|
-
name=SUM_PATH,
|
|
269
|
-
dtype=np.float64,
|
|
270
|
-
shape=(1,),
|
|
271
|
-
maxshape=(None,),
|
|
272
|
-
fillvalue=-1,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
datasets: List[DatasetConfig] = [raw_dataset, sum_dataset]
|
|
276
|
-
return datasets
|
|
277
|
-
|
|
278
|
-
async def collect_stream_docs(
|
|
279
|
-
self, indices_written: int
|
|
280
|
-
) -> AsyncIterator[StreamAsset]:
|
|
281
|
-
"""
|
|
282
|
-
stream resource says "here is a dataset",
|
|
283
|
-
stream datum says "here are N frames in that stream resource",
|
|
284
|
-
you get one stream resource and many stream datums per scan
|
|
285
|
-
"""
|
|
286
|
-
if self._handle_for_h5_file:
|
|
287
|
-
self._handle_for_h5_file.flush()
|
|
288
|
-
# when already something was written to the file
|
|
289
|
-
if indices_written:
|
|
290
|
-
# if no frames arrived yet, there's no file to speak of
|
|
291
|
-
# cannot get the full filename the HDF writer will write
|
|
292
|
-
# until the first frame comes in
|
|
293
|
-
if not self._hdf_stream_provider:
|
|
294
|
-
assert self.target_path, "open file has not been called"
|
|
295
|
-
datasets = self._get_datasets()
|
|
296
|
-
self._datasets = datasets
|
|
297
|
-
self._hdf_stream_provider = HdfStreamProvider(
|
|
298
|
-
self._directory_provider(),
|
|
299
|
-
self.target_path,
|
|
300
|
-
self._datasets,
|
|
301
|
-
)
|
|
302
|
-
for doc in self._hdf_stream_provider.stream_resources():
|
|
303
|
-
yield "stream_resource", doc
|
|
304
|
-
if self._hdf_stream_provider:
|
|
305
|
-
for doc in self._hdf_stream_provider.stream_data(indices_written):
|
|
306
|
-
yield "stream_datum", doc
|
|
307
|
-
|
|
308
|
-
def close(self) -> None:
|
|
309
|
-
if self._handle_for_h5_file:
|
|
310
|
-
self._handle_for_h5_file.close()
|
|
311
|
-
print("file closed")
|
|
312
|
-
self._handle_for_h5_file = None
|
|
313
|
-
|
|
314
|
-
async def observe_indices_written(
|
|
315
|
-
self, timeout=DEFAULT_TIMEOUT
|
|
316
|
-
) -> AsyncGenerator[int, None]:
|
|
317
|
-
async for num_captured in observe_value(self.mock_signal, timeout=timeout):
|
|
318
|
-
yield num_captured // self.multiplier
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Sequence
|
|
3
|
-
|
|
4
|
-
from ophyd_async.core import DirectoryProvider, StaticDirectoryProvider
|
|
5
|
-
from ophyd_async.core.detector import StandardDetector
|
|
6
|
-
from ophyd_async.protocols import AsyncReadable
|
|
7
|
-
from ophyd_async.sim.pattern_generator import PatternGenerator
|
|
8
|
-
|
|
9
|
-
from .sim_pattern_detector_control import SimPatternDetectorControl
|
|
10
|
-
from .sim_pattern_detector_writer import SimPatternDetectorWriter
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class SimPatternDetector(StandardDetector):
|
|
14
|
-
def __init__(
|
|
15
|
-
self,
|
|
16
|
-
path: Path,
|
|
17
|
-
config_sigs: Sequence[AsyncReadable] = [],
|
|
18
|
-
name: str = "sim_pattern_detector",
|
|
19
|
-
) -> None:
|
|
20
|
-
self.directory_provider: DirectoryProvider = StaticDirectoryProvider(path)
|
|
21
|
-
self.pattern_generator = PatternGenerator()
|
|
22
|
-
writer = SimPatternDetectorWriter(
|
|
23
|
-
pattern_generator=self.pattern_generator,
|
|
24
|
-
directoryProvider=self.directory_provider,
|
|
25
|
-
)
|
|
26
|
-
controller = SimPatternDetectorControl(
|
|
27
|
-
pattern_generator=self.pattern_generator,
|
|
28
|
-
directory_provider=self.directory_provider,
|
|
29
|
-
)
|
|
30
|
-
super().__init__(
|
|
31
|
-
controller=controller,
|
|
32
|
-
writer=writer,
|
|
33
|
-
config_sigs=config_sigs,
|
|
34
|
-
name=name,
|
|
35
|
-
)
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
ophyd_async/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
|
|
2
|
-
ophyd_async/__main__.py,sha256=G-Zcv_G9zK7Nhx6o5L5w-wyhMxdl_WgyMELu8IMFqAE,328
|
|
3
|
-
ophyd_async/_version.py,sha256=GeD2BgjHboEmcr7_O2gtjDoE83JU6uGSFLE7dAp8RDQ,413
|
|
4
|
-
ophyd_async/log.py,sha256=DbMjt0bkfUOLHIinZYt0Q0FHZmCXXi5x8y0uFiEmqoQ,3587
|
|
5
|
-
ophyd_async/protocols.py,sha256=EF2W9nfElV-0QNMYrX1zusL1PqDJR3kNsjlalR29j0I,3412
|
|
6
|
-
ophyd_async/core/__init__.py,sha256=xqO9riU_uKqGAOi0ty0cbcI4Oawi_J3XTYLtwNSXGOE,3061
|
|
7
|
-
ophyd_async/core/_providers.py,sha256=LrlTMPHKXWOPVkpAOw-pqBq0kip-c3C9ZZPoFfiaV4M,2212
|
|
8
|
-
ophyd_async/core/async_status.py,sha256=9TOgOXIAuH62RDo5t-Y5GdjrJ76d_6TFlBxYv-5_a88,4367
|
|
9
|
-
ophyd_async/core/detector.py,sha256=NMX8y_yiViHbv3CaJ7LxzXYkH6tCWI3LocpQ3w4lGEQ,11176
|
|
10
|
-
ophyd_async/core/device.py,sha256=280zFnLCoiMZAA-Dh1_AjUSnhxUfKYGgj4H_2S1njOA,7086
|
|
11
|
-
ophyd_async/core/device_save_loader.py,sha256=EK7FB5oWiLI_s2KZ1BNDQ2AUKVbFLlimMl0vXfsjcgo,8223
|
|
12
|
-
ophyd_async/core/flyer.py,sha256=bIjzBkrl8HVAlKgsZ_FF0WL69Qvksyzp9ZWmTLl8Yrw,2304
|
|
13
|
-
ophyd_async/core/mock_signal_backend.py,sha256=Ug6jK72wm9vM6EueoUrYgcXtiFzdPUEISRe86LdyYKc,2844
|
|
14
|
-
ophyd_async/core/mock_signal_utils.py,sha256=LE8VxNq3jfaTePnHHpZpKCi1vwKi8EIg-g1jfw-Q5bQ,4726
|
|
15
|
-
ophyd_async/core/signal.py,sha256=hPpMcdq7zx6HOkyQCJrMD5F3uLBEJJTfwL6DsbcTELo,17601
|
|
16
|
-
ophyd_async/core/signal_backend.py,sha256=U9J6jzHXRNIrdtGiZBVxXTRtzeejXiXEEIOGRIQhiS8,2678
|
|
17
|
-
ophyd_async/core/soft_signal_backend.py,sha256=6ve1NWuEZFW4oFkAdSfTKFg06fv7rDLgr5IAEr_axeo,6262
|
|
18
|
-
ophyd_async/core/standard_readable.py,sha256=fhq_WAZtLYWrw6DvvrFRYRAPOUP2_IcX4qLucoEEeOg,9049
|
|
19
|
-
ophyd_async/core/utils.py,sha256=3oZcXNqAUHX4ZWMBH5gSuK6cFWEhSkZ9GSDYv0pf8jc,5783
|
|
20
|
-
ophyd_async/epics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
-
ophyd_async/epics/_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
ophyd_async/epics/_backend/_aioca.py,sha256=YsKHGaHtYjBte5Tz-AftTENaeV6UGRnonX-1UmAQGqg,11319
|
|
23
|
-
ophyd_async/epics/_backend/_p4p.py,sha256=oCT8MeVWlhmsxZ8YRSrelrY8W3NvfpXcMlfAKL_AUNY,14331
|
|
24
|
-
ophyd_async/epics/_backend/common.py,sha256=ffdcKhtUc8Mmm0AsV0K7cUoOttF6avcN6Kdd4QHjrSw,1833
|
|
25
|
-
ophyd_async/epics/areadetector/__init__.py,sha256=ViKzx-wUxkRyNR33wfpL11QB97o0J47_KMyI2C_NphI,510
|
|
26
|
-
ophyd_async/epics/areadetector/aravis.py,sha256=YklN4V0loqUQBs4swVX304N49JIGPvrNOk8iA5EWofg,2127
|
|
27
|
-
ophyd_async/epics/areadetector/kinetix.py,sha256=7rE2MLnz9DEmeiN9pCekDfpXuZ2DErnMajRp_9eoLZY,1359
|
|
28
|
-
ophyd_async/epics/areadetector/pilatus.py,sha256=hs3v8QUIwTHNg7i1mRSg9SbIIsoUZg90OxJ740gEKpo,2044
|
|
29
|
-
ophyd_async/epics/areadetector/single_trigger_det.py,sha256=U92dqhioIfnve3jtCThq9gXBCdEzzqzY4ezk6rZV19g,1182
|
|
30
|
-
ophyd_async/epics/areadetector/utils.py,sha256=p66UbVdKRFj6Sm1Qvm23kmlVyBMMqIvXFxA3x17YnSk,2824
|
|
31
|
-
ophyd_async/epics/areadetector/vimba.py,sha256=IxG8KLzfb84iLtzf6ZoX9JikqZLP49lwkWu33bkDV9Y,1291
|
|
32
|
-
ophyd_async/epics/areadetector/controllers/__init__.py,sha256=af58ci7X2z2s_FyUwR3IGQrws8q4TKcBw7vFyIS5FoI,217
|
|
33
|
-
ophyd_async/epics/areadetector/controllers/ad_sim_controller.py,sha256=mthZ6WxajMEgUKptq3bnkIctbLhjzTagV66i1auB8cg,1587
|
|
34
|
-
ophyd_async/epics/areadetector/controllers/aravis_controller.py,sha256=CIfnZdq_NobO_UMC2TJoAfUEP9GlzZg5z5bz6Dn1DxY,2669
|
|
35
|
-
ophyd_async/epics/areadetector/controllers/kinetix_controller.py,sha256=9QmydX85QOXfQL_UX49M9EQ2b2hUZPVzLxgGQn-A9Oc,1611
|
|
36
|
-
ophyd_async/epics/areadetector/controllers/pilatus_controller.py,sha256=6AiMz2yBA9xig-BrAIAc9CDxwM4Cjfebc4dd7QRutB0,2740
|
|
37
|
-
ophyd_async/epics/areadetector/controllers/vimba_controller.py,sha256=Eh4Hr9rWgq1mKvE93JzgixntjPHxF3_07GTFqiOdZqE,2123
|
|
38
|
-
ophyd_async/epics/areadetector/drivers/__init__.py,sha256=X-KdXw7YWNXpaUCXby2Spqvho2x2n72OavR-3mRlxzk,605
|
|
39
|
-
ophyd_async/epics/areadetector/drivers/ad_base.py,sha256=OMySyCE9dcFRcVLC5Q0wUkri3QtRljIbn4KFdkumI4M,4553
|
|
40
|
-
ophyd_async/epics/areadetector/drivers/aravis_driver.py,sha256=K1if0Nv1ZNEvcOha6NVYA9t9VqsBNxKCmbajlysGF2Q,1491
|
|
41
|
-
ophyd_async/epics/areadetector/drivers/kinetix_driver.py,sha256=yIV23BkGBJ4i0VskLiLL7AFbadCCR6Ch1UwUDJ9r2YM,743
|
|
42
|
-
ophyd_async/epics/areadetector/drivers/pilatus_driver.py,sha256=0DBBuiR_FtwzVVdDW0ifdSrdKZtnprWuy87g66o8RlQ,619
|
|
43
|
-
ophyd_async/epics/areadetector/drivers/vimba_driver.py,sha256=J54VtWkOklfbSqZYxGWH1e6Uzm9_Gph_ZbCf9Zax0LU,1713
|
|
44
|
-
ophyd_async/epics/areadetector/writers/__init__.py,sha256=tpPcrYd1hs8WS7C0gmCnR2EBwjE5RzCljI7WwZ2V_LM,191
|
|
45
|
-
ophyd_async/epics/areadetector/writers/_hdfdataset.py,sha256=E0C9VgsPyY35h7k0mvcIhjsIVNavApLxizqNWlM388w,167
|
|
46
|
-
ophyd_async/epics/areadetector/writers/_hdffile.py,sha256=YtUgOKX53m0TaFEGBW671qXqNuuEKxEyLV5Ein1fjvo,1799
|
|
47
|
-
ophyd_async/epics/areadetector/writers/hdf_writer.py,sha256=ZpbVilNVv81OpbCrqaeZUoHLarrjzRWEGe-zI1Wxyyw,5436
|
|
48
|
-
ophyd_async/epics/areadetector/writers/nd_file_hdf.py,sha256=EkiaEh_0U6Iz17jFi2IIsRPsVQTQIJRG8EPNCiAHkkU,1762
|
|
49
|
-
ophyd_async/epics/areadetector/writers/nd_plugin.py,sha256=GUzaeTMdG07Rb1x0WzBBxMEltBhr10jb5dL29tEWXEQ,1547
|
|
50
|
-
ophyd_async/epics/demo/__init__.py,sha256=ZcuZ66aIQ58WSydLOSKnk-h_W-aWjhDRZkWQA6f3sig,5790
|
|
51
|
-
ophyd_async/epics/demo/demo_ad_sim_detector.py,sha256=06y65yvaqXvL2rDocjYyLz9kTVzuwV-LeuPhEfExdOA,944
|
|
52
|
-
ophyd_async/epics/demo/mover.db,sha256=RFz0rxZue689Wh1sWTZwWeFMUrH04ttPq2u5xJH_Fp4,998
|
|
53
|
-
ophyd_async/epics/demo/sensor.db,sha256=AVtiydrdtwAz2EFurO2Ult9SSRtre3r0akOBbL98LT0,554
|
|
54
|
-
ophyd_async/epics/motion/__init__.py,sha256=tnmVRIwKa9PdN_xonJdAUD04UpEceh-hoD7XI62yDB0,46
|
|
55
|
-
ophyd_async/epics/motion/motor.py,sha256=tqLV4TaW2MIapZsmx4wxnGOdKfkhxKLUPbTHA4YLdYE,3514
|
|
56
|
-
ophyd_async/epics/pvi/__init__.py,sha256=TbOQNY4enQWgtr1T7x129vpo2p7FIFlr8cyZqqv5Lk4,158
|
|
57
|
-
ophyd_async/epics/pvi/pvi.py,sha256=Kc3klnA9F82h_p2atFYXe-wFO9OzN5TV69Tc56tD2do,12204
|
|
58
|
-
ophyd_async/epics/signal/__init__.py,sha256=JXKBSGpRL9y3auh27JRxsqDn_rBOXpJjtd4nCuDOX2g,261
|
|
59
|
-
ophyd_async/epics/signal/_epics_transport.py,sha256=DEIL0iYUAWssysVEgWGu1fHSM1l-ATV2kjUgPtDN9LY,858
|
|
60
|
-
ophyd_async/epics/signal/signal.py,sha256=M8ZVG_zLdYJfroCRX-u_w8c3yIhswSRw8e3RkW2szio,3166
|
|
61
|
-
ophyd_async/panda/__init__.py,sha256=FuSnvp-RtdA0X4RcHEF0nTiXymRts2MNdFmF_1_i41w,775
|
|
62
|
-
ophyd_async/panda/_common_blocks.py,sha256=OrA_mSJslxuhjIAD8Liye1-1yTl3DihqFDBXvJGlPFs,1088
|
|
63
|
-
ophyd_async/panda/_hdf_panda.py,sha256=LWWQErG_cxM7zWqKG8c40O55ZpfTu3F70d4jVvRaeMo,1308
|
|
64
|
-
ophyd_async/panda/_panda_controller.py,sha256=dIqcjmaIHVrki8UXSoDx46kk6I2Lhpe2o3sXNg5f-RQ,1238
|
|
65
|
-
ophyd_async/panda/_table.py,sha256=keCGT66y91feO_MD3a6aMsgx27JuLYWLrAkl0lRXUKY,5854
|
|
66
|
-
ophyd_async/panda/_trigger.py,sha256=tBH8uq_4o1ASG9yofVxq3tjf5v8LPzniDTRL4yjramI,1195
|
|
67
|
-
ophyd_async/panda/_utils.py,sha256=VHW5kPVISyEkmse_qQcyisBkkEwMO6GG2Ago-CH1AFA,487
|
|
68
|
-
ophyd_async/panda/writers/__init__.py,sha256=xy7BguVQG4HNIDBfKPjMj0KQo1tptC9LbCpEuMcVGaM,70
|
|
69
|
-
ophyd_async/panda/writers/_hdf_writer.py,sha256=SP71y2-LTKhlNIFxLIddmtjmrg6MDwGvuwQ7X-5OP98,4698
|
|
70
|
-
ophyd_async/panda/writers/_panda_hdf_file.py,sha256=WnGvNWuLe4KljhlmBLM4Y0HKSJCIBNWOwXxioPkGu6Y,1673
|
|
71
|
-
ophyd_async/plan_stubs/__init__.py,sha256=nO9ELG9J7fYwfVTVRWVorz4kffeszYpwk1ROh6Ha--w,405
|
|
72
|
-
ophyd_async/plan_stubs/ensure_connected.py,sha256=1MkDu8UqVRPHLnW9IXRn-QvKiG8-rCV8T4KDbjf9K6w,557
|
|
73
|
-
ophyd_async/plan_stubs/fly.py,sha256=fQwBeLw57-NeBsroVxKDa8kpuu6fgTWYWimbsatCL28,4999
|
|
74
|
-
ophyd_async/sim/__init__.py,sha256=ScjH1g7FMo5yPACfJRZE6xGBWCHU4bKDzNQk1tqObnA,366
|
|
75
|
-
ophyd_async/sim/pattern_generator.py,sha256=pvSk2zb82D08j2jiKAMqMAfRohGnYd_rpjUraLrCD6c,10640
|
|
76
|
-
ophyd_async/sim/sim_pattern_detector_control.py,sha256=Ypz8IuRYAY2J243IhVbNyGr_Z-XtpJZ1qxma6NR3TgM,1838
|
|
77
|
-
ophyd_async/sim/sim_pattern_detector_writer.py,sha256=ESpcVyHd1TP7Cojznv2hJAwLinu3XbgAiVKfX12FCII,1237
|
|
78
|
-
ophyd_async/sim/sim_pattern_generator.py,sha256=L4jTnEVUFBRXIWq_UMHqx00YDdbGO2pjo_IuuVwpzXE,1258
|
|
79
|
-
ophyd_async/sim/demo/__init__.py,sha256=9mxKpslrL89cfSj4g3og8Br3O--pMj3hhWZS-Xu6kyA,56
|
|
80
|
-
ophyd_async/sim/demo/sim_motor.py,sha256=a2p5wnHXjF-V5zOFai7jnszk4kbGmrZRnUqBtkOgEfQ,3733
|
|
81
|
-
ophyd_async-0.3.4a1.dist-info/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
|
|
82
|
-
ophyd_async-0.3.4a1.dist-info/METADATA,sha256=JNwQkJEsOunynK3sUNPtQMHoTBBf8M7kfrl7HDTJYHM,6294
|
|
83
|
-
ophyd_async-0.3.4a1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
|
84
|
-
ophyd_async-0.3.4a1.dist-info/entry_points.txt,sha256=O0YNJTEufO0w9BozXi-JurTy2U1_o0ypeCgJLQ727Jk,58
|
|
85
|
-
ophyd_async-0.3.4a1.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
|
|
86
|
-
ophyd_async-0.3.4a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|