ophyd-async 0.1.0__tar.gz → 0.3a1__tar.gz
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-0.1.0 → ophyd-async-0.3a1}/.codecov.yml +1 -1
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/actions/install_requirements/action.yml +1 -1
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/code.yml +5 -3
- {ophyd-async-0.1.0/src/ophyd_async.egg-info → ophyd-async-0.3a1}/PKG-INFO +49 -42
- ophyd-async-0.3a1/README.rst +72 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/conf.py +1 -0
- ophyd-async-0.3a1/docs/user/explanations/event-loop-choice.rst +52 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/index.rst +1 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/pyproject.toml +5 -9
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/_version.py +2 -2
- ophyd-async-0.3a1/src/ophyd_async/core/__init__.py +96 -0
- ophyd-async-0.3a1/src/ophyd_async/core/_providers.py +66 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/core/async_status.py +7 -5
- ophyd-async-0.3a1/src/ophyd_async/core/detector.py +321 -0
- ophyd-async-0.3a1/src/ophyd_async/core/device.py +184 -0
- ophyd-async-0.3a1/src/ophyd_async/core/device_save_loader.py +286 -0
- ophyd-async-0.3a1/src/ophyd_async/core/flyer.py +94 -0
- {ophyd-async-0.1.0/src/ophyd_async/core/_device/_signal → ophyd-async-0.3a1/src/ophyd_async/core}/signal.py +46 -18
- {ophyd-async-0.1.0/src/ophyd_async/core/_device/_backend → ophyd-async-0.3a1/src/ophyd_async/core}/signal_backend.py +6 -2
- {ophyd-async-0.1.0/src/ophyd_async/core/_device/_backend → ophyd-async-0.3a1/src/ophyd_async/core}/sim_signal_backend.py +6 -2
- {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/core}/standard_readable.py +3 -3
- ophyd-async-0.3a1/src/ophyd_async/core/utils.py +150 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/_backend/_aioca.py +38 -25
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/_backend/_p4p.py +62 -27
- ophyd-async-0.3a1/src/ophyd_async/epics/_backend/common.py +20 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/__init__.py +19 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/__init__.py +4 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/ad_sim_controller.py +52 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/pilatus_controller.py +49 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/__init__.py +15 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/ad_base.py +111 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/pilatus_driver.py +18 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/areadetector/single_trigger_det.py +4 -4
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/utils.py +114 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/__init__.py +5 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/_hdfdataset.py +10 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/_hdffile.py +54 -0
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/hdf_writer.py +133 -0
- {ophyd-async-0.1.0/src/ophyd_async/epics/areadetector → ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers}/nd_file_hdf.py +22 -5
- ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/nd_plugin.py +30 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/__init__.py +3 -2
- ophyd-async-0.3a1/src/ophyd_async/epics/demo/demo_ad_sim_detector.py +35 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/motion/motor.py +2 -1
- ophyd-async-0.3a1/src/ophyd_async/epics/pvi.py +70 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/__init__.py +0 -2
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/signal.py +1 -1
- ophyd-async-0.3a1/src/ophyd_async/panda/__init__.py +25 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/panda/panda.py +43 -134
- ophyd-async-0.3a1/src/ophyd_async/panda/panda_controller.py +41 -0
- ophyd-async-0.3a1/src/ophyd_async/panda/table.py +158 -0
- ophyd-async-0.3a1/src/ophyd_async/panda/utils.py +15 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1/src/ophyd_async.egg-info}/PKG-INFO +49 -42
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/SOURCES.txt +45 -23
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/requires.txt +4 -8
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/conftest.py +4 -1
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/core/test_async_status.py +13 -4
- {ophyd-async-0.1.0/tests/core/_device → ophyd-async-0.3a1/tests/core}/test_device.py +11 -4
- ophyd-async-0.3a1/tests/core/test_device_collector.py +153 -0
- ophyd-async-0.3a1/tests/core/test_device_save_loader.py +212 -0
- ophyd-async-0.3a1/tests/core/test_flyer.py +248 -0
- {ophyd-async-0.1.0/tests/core/_device/_signal → ophyd-async-0.3a1/tests/core}/test_signal.py +2 -1
- ophyd-async-0.3a1/tests/core/test_utils.py +249 -0
- ophyd-async-0.3a1/tests/epics/areadetector/test_controllers.py +67 -0
- ophyd-async-0.3a1/tests/epics/areadetector/test_drivers.py +47 -0
- ophyd-async-0.3a1/tests/epics/areadetector/test_scans.py +129 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/areadetector/test_single_trigger_det.py +14 -28
- ophyd-async-0.3a1/tests/epics/areadetector/test_utils.py +19 -0
- ophyd-async-0.3a1/tests/epics/areadetector/test_writers.py +57 -0
- {ophyd-async-0.1.0/tests/epics → ophyd-async-0.3a1/tests/epics/demo}/test_demo.py +32 -22
- ophyd-async-0.3a1/tests/epics/demo/test_demo_ad_sim_detector.py +296 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/test_records.db +29 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/test_signals.py +152 -20
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/panda/db/panda.db +27 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/panda/test_panda.py +26 -9
- ophyd-async-0.3a1/tests/panda/test_panda_controller.py +28 -0
- ophyd-async-0.3a1/tests/panda/test_panda_utils.py +38 -0
- ophyd-async-0.3a1/tests/panda/test_table.py +31 -0
- ophyd-async-0.1.0/README.rst +0 -61
- ophyd-async-0.1.0/docs/examples/ad_demo.py +0 -43
- ophyd-async-0.1.0/src/ophyd_async/core/__init__.py +0 -61
- ophyd-async-0.1.0/src/ophyd_async/core/_device/device.py +0 -60
- ophyd-async-0.1.0/src/ophyd_async/core/_device/device_collector.py +0 -121
- ophyd-async-0.1.0/src/ophyd_async/core/_device/device_vector.py +0 -14
- ophyd-async-0.1.0/src/ophyd_async/core/utils.py +0 -100
- ophyd-async-0.1.0/src/ophyd_async/epics/_backend/__init__.py +0 -0
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/__init__.py +0 -22
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/ad_driver.py +0 -18
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/directory_provider.py +0 -18
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/hdf_streamer_det.py +0 -167
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/nd_plugin.py +0 -13
- ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/utils.py +0 -26
- ophyd-async-0.1.0/src/ophyd_async/epics/signal/pvi_get.py +0 -22
- ophyd-async-0.1.0/src/ophyd_async/panda/__init__.py +0 -21
- ophyd-async-0.1.0/tests/core/_device/test_device_collector.py +0 -14
- ophyd-async-0.1.0/tests/epics/areadetector/__init__.py +0 -0
- ophyd-async-0.1.0/tests/epics/areadetector/test_hdf_streamer_det.py +0 -188
- ophyd-async-0.1.0/tests/epics/motion/__init__.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.devcontainer/Dockerfile +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.devcontainer/devcontainer.json +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.git-blame-ignore-revs +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/CONTRIBUTING.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/dependabot.yml +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/pages/index.html +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/pages/make_switcher.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/docs.yml +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/docs_clean.yml +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/linkcheck.yml +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.gitignore +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.mailmap +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.pre-commit-config.yaml +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/LICENSE +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/README +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/custom-class-template.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/custom-module-template.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/build-docs.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/contribute.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/lint.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/make-release.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/pin-requirements.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/run-tests.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/static-analysis.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/test-container.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/update-tools.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/index.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/reference/standards.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/tutorials/dev-install.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/genindex.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/bluesky_ophyd_logo.svg +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/ophyd_favicon.svg +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/index.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/examples/epics_demo.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/explanations/docs-structure.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/how-to/make-a-simple-device.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/how-to/run-container.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/reference/api.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/tutorials/installation.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/tutorials/using-existing-devices.rst +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/setup.cfg +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/__init__.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/__main__.py +0 -0
- {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/epics}/__init__.py +0 -0
- {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/epics}/_backend/__init__.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/mover.db +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/sensor.db +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/motion/__init__.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/_epics_transport.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/entry_points.txt +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd-async-0.1.0/tests/core/_device/_backend → ophyd-async-0.3a1/tests/core}/test_sim.py +0 -0
- {ophyd-async-0.1.0/src/ophyd_async/core/_device/_signal → ophyd-async-0.3a1/tests/epics/areadetector}/__init__.py +0 -0
- {ophyd-async-0.1.0/src/ophyd_async/epics → ophyd-async-0.3a1/tests/epics/motion}/__init__.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/motion/test_motor.py +0 -0
- {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/test_cli.py +0 -0
|
@@ -109,6 +109,9 @@ jobs:
|
|
|
109
109
|
needs: [lint, dist, test]
|
|
110
110
|
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags') }}
|
|
111
111
|
runs-on: ubuntu-latest
|
|
112
|
+
permissions:
|
|
113
|
+
id-token: write
|
|
114
|
+
contents: write
|
|
112
115
|
env:
|
|
113
116
|
HAS_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN != '' }}
|
|
114
117
|
|
|
@@ -132,8 +135,7 @@ jobs:
|
|
|
132
135
|
env:
|
|
133
136
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
134
137
|
|
|
135
|
-
- name: Publish to PyPI
|
|
136
|
-
if: ${{ env.HAS_PYPI_TOKEN }}
|
|
138
|
+
- name: Publish wheels to PyPI
|
|
137
139
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
138
140
|
with:
|
|
139
|
-
|
|
141
|
+
packages-dir: ./dist/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3a1
|
|
4
4
|
Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
|
|
5
5
|
Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -46,9 +46,10 @@ Requires-Dist: networkx>=2.0
|
|
|
46
46
|
Requires-Dist: numpy
|
|
47
47
|
Requires-Dist: packaging
|
|
48
48
|
Requires-Dist: pint
|
|
49
|
-
Requires-Dist: bluesky
|
|
49
|
+
Requires-Dist: bluesky>=1.13.0a3
|
|
50
50
|
Requires-Dist: event-model
|
|
51
51
|
Requires-Dist: p4p
|
|
52
|
+
Requires-Dist: pyyaml
|
|
52
53
|
Provides-Extra: ca
|
|
53
54
|
Requires-Dist: aioca>=1.6; extra == "ca"
|
|
54
55
|
Provides-Extra: pva
|
|
@@ -56,14 +57,7 @@ Requires-Dist: p4p; extra == "pva"
|
|
|
56
57
|
Provides-Extra: dev
|
|
57
58
|
Requires-Dist: ophyd_async[pva]; extra == "dev"
|
|
58
59
|
Requires-Dist: ophyd_async[ca]; extra == "dev"
|
|
59
|
-
Requires-Dist: attrs>=19.3.0; extra == "dev"
|
|
60
60
|
Requires-Dist: black; extra == "dev"
|
|
61
|
-
Requires-Dist: bluesky>=1.11.0; extra == "dev"
|
|
62
|
-
Requires-Dist: caproto[standard]>=0.4.2rc1; extra == "dev"
|
|
63
|
-
Requires-Dist: pytest-codecov; extra == "dev"
|
|
64
|
-
Requires-Dist: databroker>=1.0.0b1; extra == "dev"
|
|
65
|
-
Requires-Dist: doctr; extra == "dev"
|
|
66
|
-
Requires-Dist: epics-pypdb; extra == "dev"
|
|
67
61
|
Requires-Dist: flake8; extra == "dev"
|
|
68
62
|
Requires-Dist: flake8-isort; extra == "dev"
|
|
69
63
|
Requires-Dist: Flake8-pyproject; extra == "dev"
|
|
@@ -76,6 +70,7 @@ Requires-Dist: mypy; extra == "dev"
|
|
|
76
70
|
Requires-Dist: myst-parser; extra == "dev"
|
|
77
71
|
Requires-Dist: numpydoc; extra == "dev"
|
|
78
72
|
Requires-Dist: ophyd; extra == "dev"
|
|
73
|
+
Requires-Dist: pickleshare; extra == "dev"
|
|
79
74
|
Requires-Dist: pipdeptree; extra == "dev"
|
|
80
75
|
Requires-Dist: pre-commit; extra == "dev"
|
|
81
76
|
Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
|
|
@@ -92,53 +87,59 @@ Requires-Dist: sphinx-copybutton; extra == "dev"
|
|
|
92
87
|
Requires-Dist: sphinx-design; extra == "dev"
|
|
93
88
|
Requires-Dist: tox-direct; extra == "dev"
|
|
94
89
|
Requires-Dist: types-mock; extra == "dev"
|
|
90
|
+
Requires-Dist: types-pyyaml; extra == "dev"
|
|
95
91
|
|
|
96
|
-
***********
|
|
97
92
|
Ophyd Async
|
|
98
|
-
|
|
93
|
+
===========
|
|
99
94
|
|
|
100
|
-
|
|
|
95
|
+
|code_ci| |docs_ci| |coverage| |pypi_version| |license|
|
|
101
96
|
|
|
102
|
-
|
|
103
|
-
abstraction layer that enables experiment orchestration and data acquisition
|
|
104
|
-
code to operate above the specifics of particular devices and control systems.
|
|
97
|
+
Asynchronous device abstraction framework, building on `Ophyd`_.
|
|
105
98
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
============== ==============================================================
|
|
100
|
+
PyPI ``pip install ophyd-async``
|
|
101
|
+
Source code https://github.com/bluesky/ophyd-async
|
|
102
|
+
Documentation https://blueskyproject.io/ophyd-async
|
|
103
|
+
============== ==============================================================
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
Python library for asynchronously interfacing with hardware, intended to
|
|
106
|
+
be used as an abstraction layer that enables experiment orchestration and data
|
|
107
|
+
acquisition code to operate above the specifics of particular devices and control
|
|
108
|
+
systems.
|
|
113
109
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
propagate into metadata.
|
|
120
|
-
* **Categorize** readings by "kind" (primary reading, configuration,
|
|
121
|
-
engineering/debugging) which can be read selectively.
|
|
110
|
+
Both ophyd and ophyd-async are typically used with the `Bluesky Run Engine`_ for
|
|
111
|
+
experiment orchestration and data acquisition. However, these libraries are
|
|
112
|
+
able to be used in a stand-alone fashion. For an example of how a facility defines
|
|
113
|
+
and uses ophyd-async devices, see `dls-dodal`_, which is currently using a
|
|
114
|
+
mixture of ophyd and ophyd-async devices.
|
|
122
115
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
While `EPICS`_ is the most common control system layer that ophyd-async can
|
|
117
|
+
interface with, other control systems like `Tango`_ are used by some facilities
|
|
118
|
+
also. In addition to the abstractions provided by ophyd, ophyd-async allows:
|
|
119
|
+
|
|
120
|
+
* Asynchronous signal access, opening the possibility for hardware-triggered
|
|
121
|
+
scanning (also known as fly-scanning)
|
|
122
|
+
* Simpler instantiation of devices (groupings of signals) with less reliance
|
|
123
|
+
upon complex class hierarchies
|
|
124
|
+
|
|
125
|
+
NOTE: ophyd-async is included on a provisional basis until the v1.0 release.
|
|
129
126
|
|
|
130
127
|
See the tutorials for usage examples.
|
|
131
128
|
|
|
132
|
-
.. |
|
|
133
|
-
:target: https://github.com/bluesky/ophyd/actions
|
|
134
|
-
:alt:
|
|
129
|
+
.. |code_ci| image:: https://github.com/bluesky/ophyd-async/actions/workflows/code.yml/badge.svg?branch=main
|
|
130
|
+
:target: https://github.com/bluesky/ophyd-async/actions/workflows/code.yml
|
|
131
|
+
:alt: Code CI
|
|
132
|
+
|
|
133
|
+
.. |docs_ci| image:: https://github.com/bluesky/ophyd-async/actions/workflows/docs.yml/badge.svg?branch=main
|
|
134
|
+
:target: https://github.com/bluesky/ophyd-async/actions/workflows/docs.yml
|
|
135
|
+
:alt: Docs CI
|
|
135
136
|
|
|
136
|
-
.. |coverage| image:: https://codecov.io/gh/bluesky/ophyd/branch/master/graph/badge.svg
|
|
137
|
-
:target: https://codecov.io/gh/bluesky/ophyd
|
|
137
|
+
.. |coverage| image:: https://codecov.io/gh/bluesky/ophyd-async/branch/master/graph/badge.svg
|
|
138
|
+
:target: https://codecov.io/gh/bluesky/ophyd-async
|
|
138
139
|
:alt: Test Coverage
|
|
139
140
|
|
|
140
|
-
.. |pypi_version| image:: https://img.shields.io/pypi/v/ophyd.svg
|
|
141
|
-
:target: https://pypi.org/project/ophyd
|
|
141
|
+
.. |pypi_version| image:: https://img.shields.io/pypi/v/ophyd-async.svg
|
|
142
|
+
:target: https://pypi.org/project/ophyd-async
|
|
142
143
|
:alt: Latest PyPI version
|
|
143
144
|
|
|
144
145
|
.. |license| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
|
|
@@ -147,8 +148,14 @@ See the tutorials for usage examples.
|
|
|
147
148
|
|
|
148
149
|
.. _Bluesky Run Engine: http://blueskyproject.io/bluesky
|
|
149
150
|
|
|
151
|
+
.. _Ophyd: http://blueskyproject.io/ophyd
|
|
152
|
+
|
|
153
|
+
.. _dls-dodal: https://github.com/DiamondLightSource/dodal
|
|
154
|
+
|
|
150
155
|
.. _EPICS: http://www.aps.anl.gov/epics/
|
|
151
156
|
|
|
157
|
+
.. _Tango: https://www.tango-controls.org/
|
|
158
|
+
|
|
152
159
|
..
|
|
153
160
|
Anything below this line is used when viewing README.rst and will be replaced
|
|
154
161
|
when included in index.rst
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Ophyd Async
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
|code_ci| |docs_ci| |coverage| |pypi_version| |license|
|
|
5
|
+
|
|
6
|
+
Asynchronous device abstraction framework, building on `Ophyd`_.
|
|
7
|
+
|
|
8
|
+
============== ==============================================================
|
|
9
|
+
PyPI ``pip install ophyd-async``
|
|
10
|
+
Source code https://github.com/bluesky/ophyd-async
|
|
11
|
+
Documentation https://blueskyproject.io/ophyd-async
|
|
12
|
+
============== ==============================================================
|
|
13
|
+
|
|
14
|
+
Python library for asynchronously interfacing with hardware, intended to
|
|
15
|
+
be used as an abstraction layer that enables experiment orchestration and data
|
|
16
|
+
acquisition code to operate above the specifics of particular devices and control
|
|
17
|
+
systems.
|
|
18
|
+
|
|
19
|
+
Both ophyd and ophyd-async are typically used with the `Bluesky Run Engine`_ for
|
|
20
|
+
experiment orchestration and data acquisition. However, these libraries are
|
|
21
|
+
able to be used in a stand-alone fashion. For an example of how a facility defines
|
|
22
|
+
and uses ophyd-async devices, see `dls-dodal`_, which is currently using a
|
|
23
|
+
mixture of ophyd and ophyd-async devices.
|
|
24
|
+
|
|
25
|
+
While `EPICS`_ is the most common control system layer that ophyd-async can
|
|
26
|
+
interface with, other control systems like `Tango`_ are used by some facilities
|
|
27
|
+
also. In addition to the abstractions provided by ophyd, ophyd-async allows:
|
|
28
|
+
|
|
29
|
+
* Asynchronous signal access, opening the possibility for hardware-triggered
|
|
30
|
+
scanning (also known as fly-scanning)
|
|
31
|
+
* Simpler instantiation of devices (groupings of signals) with less reliance
|
|
32
|
+
upon complex class hierarchies
|
|
33
|
+
|
|
34
|
+
NOTE: ophyd-async is included on a provisional basis until the v1.0 release.
|
|
35
|
+
|
|
36
|
+
See the tutorials for usage examples.
|
|
37
|
+
|
|
38
|
+
.. |code_ci| image:: https://github.com/bluesky/ophyd-async/actions/workflows/code.yml/badge.svg?branch=main
|
|
39
|
+
:target: https://github.com/bluesky/ophyd-async/actions/workflows/code.yml
|
|
40
|
+
:alt: Code CI
|
|
41
|
+
|
|
42
|
+
.. |docs_ci| image:: https://github.com/bluesky/ophyd-async/actions/workflows/docs.yml/badge.svg?branch=main
|
|
43
|
+
:target: https://github.com/bluesky/ophyd-async/actions/workflows/docs.yml
|
|
44
|
+
:alt: Docs CI
|
|
45
|
+
|
|
46
|
+
.. |coverage| image:: https://codecov.io/gh/bluesky/ophyd-async/branch/master/graph/badge.svg
|
|
47
|
+
:target: https://codecov.io/gh/bluesky/ophyd-async
|
|
48
|
+
:alt: Test Coverage
|
|
49
|
+
|
|
50
|
+
.. |pypi_version| image:: https://img.shields.io/pypi/v/ophyd-async.svg
|
|
51
|
+
:target: https://pypi.org/project/ophyd-async
|
|
52
|
+
:alt: Latest PyPI version
|
|
53
|
+
|
|
54
|
+
.. |license| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
|
|
55
|
+
:target: https://opensource.org/licenses/BSD-3-Clause
|
|
56
|
+
:alt: BSD 3-Clause License
|
|
57
|
+
|
|
58
|
+
.. _Bluesky Run Engine: http://blueskyproject.io/bluesky
|
|
59
|
+
|
|
60
|
+
.. _Ophyd: http://blueskyproject.io/ophyd
|
|
61
|
+
|
|
62
|
+
.. _dls-dodal: https://github.com/DiamondLightSource/dodal
|
|
63
|
+
|
|
64
|
+
.. _EPICS: http://www.aps.anl.gov/epics/
|
|
65
|
+
|
|
66
|
+
.. _Tango: https://www.tango-controls.org/
|
|
67
|
+
|
|
68
|
+
..
|
|
69
|
+
Anything below this line is used when viewing README.rst and will be replaced
|
|
70
|
+
when included in index.rst
|
|
71
|
+
|
|
72
|
+
See https://blueskyproject.io/ophyd-async for more detailed documentation.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Device Collector Event-Loop Choice
|
|
2
|
+
----------------------------------
|
|
3
|
+
|
|
4
|
+
In a sync context, the ophyd-async :python:`DeviceCollector` requires the bluesky event-loop
|
|
5
|
+
to connect to devices. In an async context, it does not.
|
|
6
|
+
|
|
7
|
+
Sync Context
|
|
8
|
+
============
|
|
9
|
+
|
|
10
|
+
In a sync context the run-engine must be initialized prior to connecting to devices.
|
|
11
|
+
We enfore usage of the bluesky event-loop in this context.
|
|
12
|
+
|
|
13
|
+
The following will fail if :python:`RE = RunEngine()` has not been called already:
|
|
14
|
+
|
|
15
|
+
.. code:: python
|
|
16
|
+
|
|
17
|
+
with DeviceCollector():
|
|
18
|
+
device1 = Device1(prefix)
|
|
19
|
+
device2 = Device2(prefix)
|
|
20
|
+
device3 = Device3(prefix)
|
|
21
|
+
|
|
22
|
+
The :python:`DeviceCollector` connects to devices in the event-loop created in the run-engine.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Async Context
|
|
26
|
+
=============
|
|
27
|
+
|
|
28
|
+
In an async context device connection is decoupled from the run-engine.
|
|
29
|
+
The following attempts connection to all the devices in the :python:`DeviceCollector`
|
|
30
|
+
before or after run-engine initialization.
|
|
31
|
+
|
|
32
|
+
.. code:: python
|
|
33
|
+
|
|
34
|
+
async def connection_function() :
|
|
35
|
+
async with DeviceCollector():
|
|
36
|
+
device1 = Device1(prefix)
|
|
37
|
+
device2 = Device2(prefix)
|
|
38
|
+
device3 = Device3(prefix)
|
|
39
|
+
|
|
40
|
+
asyncio.run(connection_function())
|
|
41
|
+
|
|
42
|
+
The devices will be unable to be used in the run-engine unless they share the same event-loop.
|
|
43
|
+
When the run-engine is initialised it will create a new background event-loop to use if one
|
|
44
|
+
is not passed in with :python:`RunEngine(loop=loop)`.
|
|
45
|
+
|
|
46
|
+
If the user wants to use devices in the async :python:`DeviceCollector` within the run-engine
|
|
47
|
+
they can either:
|
|
48
|
+
|
|
49
|
+
* Run the :python:`DeviceCollector` first and pass the event-loop into the run-engine.
|
|
50
|
+
* Initialize the run-engine first and run the :python:`DeviceCollector` using the bluesky event-loop.
|
|
51
|
+
|
|
52
|
+
|
|
@@ -18,10 +18,11 @@ dependencies = [
|
|
|
18
18
|
"numpy",
|
|
19
19
|
"packaging",
|
|
20
20
|
"pint",
|
|
21
|
-
"bluesky",
|
|
21
|
+
"bluesky>=1.13.0a3",
|
|
22
22
|
"event-model",
|
|
23
23
|
"p4p",
|
|
24
|
-
|
|
24
|
+
"pyyaml",
|
|
25
|
+
]
|
|
25
26
|
|
|
26
27
|
dynamic = ["version"]
|
|
27
28
|
license.file = "LICENSE"
|
|
@@ -34,14 +35,7 @@ pva = ["p4p"]
|
|
|
34
35
|
dev = [
|
|
35
36
|
"ophyd_async[pva]",
|
|
36
37
|
"ophyd_async[ca]",
|
|
37
|
-
"attrs>=19.3.0",
|
|
38
38
|
"black",
|
|
39
|
-
"bluesky>=1.11.0",
|
|
40
|
-
"caproto[standard] >=0.4.2rc1",
|
|
41
|
-
"pytest-codecov",
|
|
42
|
-
"databroker>=1.0.0b1",
|
|
43
|
-
"doctr",
|
|
44
|
-
"epics-pypdb",
|
|
45
39
|
"flake8",
|
|
46
40
|
"flake8-isort",
|
|
47
41
|
"Flake8-pyproject",
|
|
@@ -54,6 +48,7 @@ dev = [
|
|
|
54
48
|
"myst-parser",
|
|
55
49
|
"numpydoc",
|
|
56
50
|
"ophyd",
|
|
51
|
+
"pickleshare",
|
|
57
52
|
"pipdeptree",
|
|
58
53
|
"pre-commit",
|
|
59
54
|
"pydata-sphinx-theme>=0.12",
|
|
@@ -70,6 +65,7 @@ dev = [
|
|
|
70
65
|
"sphinx-design",
|
|
71
66
|
"tox-direct",
|
|
72
67
|
"types-mock",
|
|
68
|
+
"types-pyyaml",
|
|
73
69
|
]
|
|
74
70
|
|
|
75
71
|
[project.scripts]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from ._providers import (
|
|
2
|
+
DirectoryInfo,
|
|
3
|
+
DirectoryProvider,
|
|
4
|
+
NameProvider,
|
|
5
|
+
ShapeProvider,
|
|
6
|
+
StaticDirectoryProvider,
|
|
7
|
+
)
|
|
8
|
+
from .async_status import AsyncStatus
|
|
9
|
+
from .detector import DetectorControl, DetectorTrigger, DetectorWriter, StandardDetector
|
|
10
|
+
from .device import Device, DeviceCollector, DeviceVector
|
|
11
|
+
from .device_save_loader import (
|
|
12
|
+
get_signal_values,
|
|
13
|
+
load_device,
|
|
14
|
+
load_from_yaml,
|
|
15
|
+
save_device,
|
|
16
|
+
save_to_yaml,
|
|
17
|
+
set_signal_values,
|
|
18
|
+
walk_rw_signals,
|
|
19
|
+
)
|
|
20
|
+
from .flyer import HardwareTriggeredFlyable, TriggerInfo, TriggerLogic
|
|
21
|
+
from .signal import (
|
|
22
|
+
Signal,
|
|
23
|
+
SignalR,
|
|
24
|
+
SignalRW,
|
|
25
|
+
SignalW,
|
|
26
|
+
SignalX,
|
|
27
|
+
observe_value,
|
|
28
|
+
set_and_wait_for_value,
|
|
29
|
+
set_sim_callback,
|
|
30
|
+
set_sim_put_proceeds,
|
|
31
|
+
set_sim_value,
|
|
32
|
+
wait_for_value,
|
|
33
|
+
)
|
|
34
|
+
from .signal_backend import SignalBackend
|
|
35
|
+
from .sim_signal_backend import SimSignalBackend
|
|
36
|
+
from .standard_readable import StandardReadable
|
|
37
|
+
from .utils import (
|
|
38
|
+
DEFAULT_TIMEOUT,
|
|
39
|
+
Callback,
|
|
40
|
+
NotConnected,
|
|
41
|
+
ReadingValueCallback,
|
|
42
|
+
T,
|
|
43
|
+
get_dtype,
|
|
44
|
+
get_unique,
|
|
45
|
+
merge_gathered_dicts,
|
|
46
|
+
wait_for_connection,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
__all__ = [
|
|
50
|
+
"SignalBackend",
|
|
51
|
+
"SimSignalBackend",
|
|
52
|
+
"DetectorControl",
|
|
53
|
+
"DetectorTrigger",
|
|
54
|
+
"DetectorWriter",
|
|
55
|
+
"StandardDetector",
|
|
56
|
+
"Device",
|
|
57
|
+
"DeviceCollector",
|
|
58
|
+
"DeviceVector",
|
|
59
|
+
"Signal",
|
|
60
|
+
"SignalR",
|
|
61
|
+
"SignalW",
|
|
62
|
+
"SignalRW",
|
|
63
|
+
"SignalX",
|
|
64
|
+
"observe_value",
|
|
65
|
+
"set_and_wait_for_value",
|
|
66
|
+
"set_sim_callback",
|
|
67
|
+
"set_sim_put_proceeds",
|
|
68
|
+
"set_sim_value",
|
|
69
|
+
"wait_for_value",
|
|
70
|
+
"AsyncStatus",
|
|
71
|
+
"DirectoryInfo",
|
|
72
|
+
"DirectoryProvider",
|
|
73
|
+
"NameProvider",
|
|
74
|
+
"ShapeProvider",
|
|
75
|
+
"StaticDirectoryProvider",
|
|
76
|
+
"StandardReadable",
|
|
77
|
+
"TriggerInfo",
|
|
78
|
+
"TriggerLogic",
|
|
79
|
+
"HardwareTriggeredFlyable",
|
|
80
|
+
"DEFAULT_TIMEOUT",
|
|
81
|
+
"Callback",
|
|
82
|
+
"NotConnected",
|
|
83
|
+
"ReadingValueCallback",
|
|
84
|
+
"T",
|
|
85
|
+
"get_dtype",
|
|
86
|
+
"get_unique",
|
|
87
|
+
"merge_gathered_dicts",
|
|
88
|
+
"wait_for_connection",
|
|
89
|
+
"get_signal_values",
|
|
90
|
+
"load_from_yaml",
|
|
91
|
+
"save_to_yaml",
|
|
92
|
+
"set_signal_values",
|
|
93
|
+
"walk_rw_signals",
|
|
94
|
+
"load_device",
|
|
95
|
+
"save_device",
|
|
96
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional, Protocol, Sequence, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class DirectoryInfo:
|
|
9
|
+
"""
|
|
10
|
+
Information about where and how to write a file.
|
|
11
|
+
|
|
12
|
+
The bluesky event model splits the URI for a resource into two segments to aid in
|
|
13
|
+
different applications mounting filesystems at different mount points.
|
|
14
|
+
The portion of this path which is relevant only for the writer is the 'root',
|
|
15
|
+
while the path from an agreed upon mutual mounting is the resource_path.
|
|
16
|
+
The resource_dir is used with the filename to construct the resource_path.
|
|
17
|
+
|
|
18
|
+
:param root: Path of a root directory, relevant only for the file writer
|
|
19
|
+
:param resource_dir: Directory into which files should be written, relative to root
|
|
20
|
+
:param prefix: Optional filename prefix to add to all files
|
|
21
|
+
:param suffix: Optional filename suffix to add to all files
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
root: Path
|
|
25
|
+
resource_dir: Path
|
|
26
|
+
prefix: Optional[str] = ""
|
|
27
|
+
suffix: Optional[str] = ""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DirectoryProvider(Protocol):
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def __call__(self) -> DirectoryInfo:
|
|
33
|
+
"""Get the current directory to write files into"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class StaticDirectoryProvider(DirectoryProvider):
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
directory_path: Union[str, Path],
|
|
40
|
+
filename_prefix: str = "",
|
|
41
|
+
filename_suffix: str = "",
|
|
42
|
+
resource_dir: Path = Path("."),
|
|
43
|
+
) -> None:
|
|
44
|
+
if isinstance(directory_path, str):
|
|
45
|
+
directory_path = Path(directory_path)
|
|
46
|
+
self._directory_info = DirectoryInfo(
|
|
47
|
+
root=directory_path,
|
|
48
|
+
resource_dir=resource_dir,
|
|
49
|
+
prefix=filename_prefix,
|
|
50
|
+
suffix=filename_suffix,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __call__(self) -> DirectoryInfo:
|
|
54
|
+
return self._directory_info
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class NameProvider(Protocol):
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def __call__(self) -> str:
|
|
60
|
+
"""Get the name to be used as a data_key in the descriptor document"""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ShapeProvider(Protocol):
|
|
64
|
+
@abstractmethod
|
|
65
|
+
async def __call__(self) -> Sequence[int]:
|
|
66
|
+
"""Get the shape of the data collection"""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Equivalent of bluesky.
|
|
1
|
+
"""Equivalent of bluesky.protocols.Status for asynchronous tasks."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import functools
|
|
@@ -62,7 +62,9 @@ class AsyncStatus(Status):
|
|
|
62
62
|
@property
|
|
63
63
|
def success(self) -> bool:
|
|
64
64
|
return (
|
|
65
|
-
self.task.done()
|
|
65
|
+
self.task.done()
|
|
66
|
+
and not self.task.cancelled()
|
|
67
|
+
and self.task.exception() is None
|
|
66
68
|
)
|
|
67
69
|
|
|
68
70
|
def watch(self, watcher: Callable):
|
|
@@ -83,12 +85,12 @@ class AsyncStatus(Status):
|
|
|
83
85
|
|
|
84
86
|
def __repr__(self) -> str:
|
|
85
87
|
if self.done:
|
|
86
|
-
if self.exception()
|
|
87
|
-
status = "errored"
|
|
88
|
+
if e := self.exception():
|
|
89
|
+
status = f"errored: {repr(e)}"
|
|
88
90
|
else:
|
|
89
91
|
status = "done"
|
|
90
92
|
else:
|
|
91
93
|
status = "pending"
|
|
92
|
-
return f"<{type(self).__name__} {status}>"
|
|
94
|
+
return f"<{type(self).__name__}, task: {self.task.get_coro()}, {status}>"
|
|
93
95
|
|
|
94
96
|
__str__ = __repr__
|