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.
Files changed (162) hide show
  1. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.codecov.yml +1 -1
  2. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/actions/install_requirements/action.yml +1 -1
  3. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/code.yml +5 -3
  4. {ophyd-async-0.1.0/src/ophyd_async.egg-info → ophyd-async-0.3a1}/PKG-INFO +49 -42
  5. ophyd-async-0.3a1/README.rst +72 -0
  6. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/conf.py +1 -0
  7. ophyd-async-0.3a1/docs/user/explanations/event-loop-choice.rst +52 -0
  8. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/index.rst +1 -0
  9. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/pyproject.toml +5 -9
  10. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/_version.py +2 -2
  11. ophyd-async-0.3a1/src/ophyd_async/core/__init__.py +96 -0
  12. ophyd-async-0.3a1/src/ophyd_async/core/_providers.py +66 -0
  13. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/core/async_status.py +7 -5
  14. ophyd-async-0.3a1/src/ophyd_async/core/detector.py +321 -0
  15. ophyd-async-0.3a1/src/ophyd_async/core/device.py +184 -0
  16. ophyd-async-0.3a1/src/ophyd_async/core/device_save_loader.py +286 -0
  17. ophyd-async-0.3a1/src/ophyd_async/core/flyer.py +94 -0
  18. {ophyd-async-0.1.0/src/ophyd_async/core/_device/_signal → ophyd-async-0.3a1/src/ophyd_async/core}/signal.py +46 -18
  19. {ophyd-async-0.1.0/src/ophyd_async/core/_device/_backend → ophyd-async-0.3a1/src/ophyd_async/core}/signal_backend.py +6 -2
  20. {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
  21. {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/core}/standard_readable.py +3 -3
  22. ophyd-async-0.3a1/src/ophyd_async/core/utils.py +150 -0
  23. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/_backend/_aioca.py +38 -25
  24. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/_backend/_p4p.py +62 -27
  25. ophyd-async-0.3a1/src/ophyd_async/epics/_backend/common.py +20 -0
  26. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/__init__.py +19 -0
  27. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/__init__.py +4 -0
  28. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/ad_sim_controller.py +52 -0
  29. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/controllers/pilatus_controller.py +49 -0
  30. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/__init__.py +15 -0
  31. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/ad_base.py +111 -0
  32. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/drivers/pilatus_driver.py +18 -0
  33. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/areadetector/single_trigger_det.py +4 -4
  34. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/utils.py +114 -0
  35. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/__init__.py +5 -0
  36. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/_hdfdataset.py +10 -0
  37. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/_hdffile.py +54 -0
  38. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/hdf_writer.py +133 -0
  39. {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
  40. ophyd-async-0.3a1/src/ophyd_async/epics/areadetector/writers/nd_plugin.py +30 -0
  41. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/__init__.py +3 -2
  42. ophyd-async-0.3a1/src/ophyd_async/epics/demo/demo_ad_sim_detector.py +35 -0
  43. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/motion/motor.py +2 -1
  44. ophyd-async-0.3a1/src/ophyd_async/epics/pvi.py +70 -0
  45. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/__init__.py +0 -2
  46. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/signal.py +1 -1
  47. ophyd-async-0.3a1/src/ophyd_async/panda/__init__.py +25 -0
  48. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/panda/panda.py +43 -134
  49. ophyd-async-0.3a1/src/ophyd_async/panda/panda_controller.py +41 -0
  50. ophyd-async-0.3a1/src/ophyd_async/panda/table.py +158 -0
  51. ophyd-async-0.3a1/src/ophyd_async/panda/utils.py +15 -0
  52. {ophyd-async-0.1.0 → ophyd-async-0.3a1/src/ophyd_async.egg-info}/PKG-INFO +49 -42
  53. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/SOURCES.txt +45 -23
  54. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/requires.txt +4 -8
  55. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/conftest.py +4 -1
  56. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/core/test_async_status.py +13 -4
  57. {ophyd-async-0.1.0/tests/core/_device → ophyd-async-0.3a1/tests/core}/test_device.py +11 -4
  58. ophyd-async-0.3a1/tests/core/test_device_collector.py +153 -0
  59. ophyd-async-0.3a1/tests/core/test_device_save_loader.py +212 -0
  60. ophyd-async-0.3a1/tests/core/test_flyer.py +248 -0
  61. {ophyd-async-0.1.0/tests/core/_device/_signal → ophyd-async-0.3a1/tests/core}/test_signal.py +2 -1
  62. ophyd-async-0.3a1/tests/core/test_utils.py +249 -0
  63. ophyd-async-0.3a1/tests/epics/areadetector/test_controllers.py +67 -0
  64. ophyd-async-0.3a1/tests/epics/areadetector/test_drivers.py +47 -0
  65. ophyd-async-0.3a1/tests/epics/areadetector/test_scans.py +129 -0
  66. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/areadetector/test_single_trigger_det.py +14 -28
  67. ophyd-async-0.3a1/tests/epics/areadetector/test_utils.py +19 -0
  68. ophyd-async-0.3a1/tests/epics/areadetector/test_writers.py +57 -0
  69. {ophyd-async-0.1.0/tests/epics → ophyd-async-0.3a1/tests/epics/demo}/test_demo.py +32 -22
  70. ophyd-async-0.3a1/tests/epics/demo/test_demo_ad_sim_detector.py +296 -0
  71. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/test_records.db +29 -0
  72. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/test_signals.py +152 -20
  73. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/panda/db/panda.db +27 -0
  74. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/panda/test_panda.py +26 -9
  75. ophyd-async-0.3a1/tests/panda/test_panda_controller.py +28 -0
  76. ophyd-async-0.3a1/tests/panda/test_panda_utils.py +38 -0
  77. ophyd-async-0.3a1/tests/panda/test_table.py +31 -0
  78. ophyd-async-0.1.0/README.rst +0 -61
  79. ophyd-async-0.1.0/docs/examples/ad_demo.py +0 -43
  80. ophyd-async-0.1.0/src/ophyd_async/core/__init__.py +0 -61
  81. ophyd-async-0.1.0/src/ophyd_async/core/_device/device.py +0 -60
  82. ophyd-async-0.1.0/src/ophyd_async/core/_device/device_collector.py +0 -121
  83. ophyd-async-0.1.0/src/ophyd_async/core/_device/device_vector.py +0 -14
  84. ophyd-async-0.1.0/src/ophyd_async/core/utils.py +0 -100
  85. ophyd-async-0.1.0/src/ophyd_async/epics/_backend/__init__.py +0 -0
  86. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/__init__.py +0 -22
  87. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/ad_driver.py +0 -18
  88. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/directory_provider.py +0 -18
  89. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/hdf_streamer_det.py +0 -167
  90. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/nd_plugin.py +0 -13
  91. ophyd-async-0.1.0/src/ophyd_async/epics/areadetector/utils.py +0 -26
  92. ophyd-async-0.1.0/src/ophyd_async/epics/signal/pvi_get.py +0 -22
  93. ophyd-async-0.1.0/src/ophyd_async/panda/__init__.py +0 -21
  94. ophyd-async-0.1.0/tests/core/_device/test_device_collector.py +0 -14
  95. ophyd-async-0.1.0/tests/epics/areadetector/__init__.py +0 -0
  96. ophyd-async-0.1.0/tests/epics/areadetector/test_hdf_streamer_det.py +0 -188
  97. ophyd-async-0.1.0/tests/epics/motion/__init__.py +0 -0
  98. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.devcontainer/Dockerfile +0 -0
  99. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.devcontainer/devcontainer.json +0 -0
  100. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.git-blame-ignore-revs +0 -0
  101. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/CONTRIBUTING.rst +0 -0
  102. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/dependabot.yml +0 -0
  103. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/pages/index.html +0 -0
  104. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/pages/make_switcher.py +0 -0
  105. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/docs.yml +0 -0
  106. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/docs_clean.yml +0 -0
  107. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.github/workflows/linkcheck.yml +0 -0
  108. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.gitignore +0 -0
  109. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.mailmap +0 -0
  110. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/.pre-commit-config.yaml +0 -0
  111. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/LICENSE +0 -0
  112. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/README +0 -0
  113. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/custom-class-template.rst +0 -0
  114. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/_templates/custom-module-template.rst +0 -0
  115. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
  116. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
  117. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
  118. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0004-repository-structure.rst +0 -0
  119. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0005-respect-black-line-length.rst +0 -0
  120. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
  121. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/explanations/decisions.rst +0 -0
  122. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/build-docs.rst +0 -0
  123. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/contribute.rst +0 -0
  124. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/lint.rst +0 -0
  125. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/make-release.rst +0 -0
  126. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/pin-requirements.rst +0 -0
  127. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/run-tests.rst +0 -0
  128. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/static-analysis.rst +0 -0
  129. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/test-container.rst +0 -0
  130. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/how-to/update-tools.rst +0 -0
  131. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/index.rst +0 -0
  132. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/reference/standards.rst +0 -0
  133. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/developer/tutorials/dev-install.rst +0 -0
  134. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/genindex.rst +0 -0
  135. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -0
  136. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/bluesky_ophyd_logo.svg +0 -0
  137. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/images/ophyd_favicon.svg +0 -0
  138. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/index.rst +0 -0
  139. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/examples/epics_demo.py +0 -0
  140. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/explanations/docs-structure.rst +0 -0
  141. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/how-to/make-a-simple-device.rst +0 -0
  142. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/how-to/run-container.rst +0 -0
  143. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/reference/api.rst +0 -0
  144. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/tutorials/installation.rst +0 -0
  145. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/docs/user/tutorials/using-existing-devices.rst +0 -0
  146. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/setup.cfg +0 -0
  147. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/__init__.py +0 -0
  148. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/__main__.py +0 -0
  149. {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/epics}/__init__.py +0 -0
  150. {ophyd-async-0.1.0/src/ophyd_async/core/_device → ophyd-async-0.3a1/src/ophyd_async/epics}/_backend/__init__.py +0 -0
  151. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/mover.db +0 -0
  152. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/demo/sensor.db +0 -0
  153. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/motion/__init__.py +0 -0
  154. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async/epics/signal/_epics_transport.py +0 -0
  155. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
  156. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/entry_points.txt +0 -0
  157. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/src/ophyd_async.egg-info/top_level.txt +0 -0
  158. {ophyd-async-0.1.0/tests/core/_device/_backend → ophyd-async-0.3a1/tests/core}/test_sim.py +0 -0
  159. {ophyd-async-0.1.0/src/ophyd_async/core/_device/_signal → ophyd-async-0.3a1/tests/epics/areadetector}/__init__.py +0 -0
  160. {ophyd-async-0.1.0/src/ophyd_async/epics → ophyd-async-0.3a1/tests/epics/motion}/__init__.py +0 -0
  161. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/epics/motion/test_motor.py +0 -0
  162. {ophyd-async-0.1.0 → ophyd-async-0.3a1}/tests/test_cli.py +0 -0
@@ -5,7 +5,7 @@ coverage:
5
5
  project:
6
6
  default:
7
7
  target: auto
8
- threshold: 0.1%
8
+ threshold: 1%
9
9
  patch:
10
10
  default:
11
11
  target: auto
@@ -9,7 +9,7 @@ inputs:
9
9
  required: true
10
10
  python_version:
11
11
  description: Python version to install
12
- default: "3.x"
12
+ default: "3.9"
13
13
 
14
14
  runs:
15
15
  using: composite
@@ -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
- password: ${{ secrets.PYPI_TOKEN }}
141
+ packages-dir: ./dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ophyd-async
3
- Version: 0.1.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
- |build_status| |coverage| |pypi_version| |license|
95
+ |code_ci| |docs_ci| |coverage| |pypi_version| |license|
101
96
 
102
- Ophyd is a Python library for interfacing with hardware. It provides an
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
- Ophyd is typically used with the `Bluesky Run Engine`_ for experiment
107
- orchestration and data acquisition. It is also sometimes used in a stand-alone
108
- fashion.
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
- Many facilities use ophyd to integrate with control systems that use `EPICS`_ ,
111
- but ophyd's design and some of its objects are also used to integrate with
112
- other control systems.
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
- * Put the details specific to a device or control system behind a **high-level
115
- interface** with methods like ``trigger()``, ``read()``, and ``set(...)``.
116
- * **Group** individual control channels (such as EPICS V3 PVs) into logical
117
- "Devices" to be configured and used as units with internal coordination.
118
- * Assign readings with **names meaningful for data analysis** that will
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
- PyPI ``pip install ophyd``
125
- Conda ``conda install -c conda-forge ophyd``
126
- Source code https://github.com/bluesky/ophyd
127
- Documentation https://blueskyproject.io/ophyd
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
- .. |build_status| image:: https://github.com/bluesky/ophyd/workflows/Unit%20Tests/badge.svg?branch=master
133
- :target: https://github.com/bluesky/ophyd/actions?query=workflow%3A%22Unit+Tests%22
134
- :alt: Build Status
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.
@@ -187,6 +187,7 @@ html_theme_options = dict(
187
187
  url="https://blueskyproject.io",
188
188
  )
189
189
  ],
190
+ navigation_with_keys=False,
190
191
  )
191
192
 
192
193
 
@@ -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
+
@@ -45,6 +45,7 @@ side-bar.
45
45
  :maxdepth: 1
46
46
 
47
47
  explanations/docs-structure
48
+ explanations/event-loop-choice
48
49
 
49
50
  +++
50
51
 
@@ -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
- ] # Add project dependencies here, e.g. ["click", "numpy"]
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]
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.1.0'
16
- __version_tuple__ = version_tuple = (0, 1, 0)
15
+ __version__ = version = '0.3a1'
16
+ __version_tuple__ = version_tuple = (0, 3)
@@ -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.protols.Status for asynchronous tasks."""
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() and not self.task.cancelled() and not self.task.exception()
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() is not None:
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__