ophyd-async 0.3a2__tar.gz → 0.3a3__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 (199) hide show
  1. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_docs.yml +1 -1
  2. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/PKG-INFO +20 -3
  3. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/README.md +16 -1
  4. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/conf.py +5 -9
  5. ophyd_async-0.3a3/docs/examples/foo_detector.py +82 -0
  6. ophyd_async-0.3a3/docs/explanations/design-goals.rst +57 -0
  7. ophyd_async-0.3a3/docs/explanations/flyscanning.rst +63 -0
  8. ophyd_async-0.3a3/docs/how-to/choose-interfaces-for-devices.md +15 -0
  9. ophyd_async-0.3a3/docs/how-to/make-a-standard-detector.rst +64 -0
  10. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/how-to/write-tests-for-devices.rst +11 -0
  11. ophyd_async-0.3a3/docs/images/hardware-triggered-scan.png +0 -0
  12. ophyd_async-0.3a3/docs/images/outer-scan.png +0 -0
  13. ophyd_async-0.3a3/docs/images/simple-hardware-scan.png +0 -0
  14. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/pyproject.toml +3 -1
  15. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/_version.py +1 -1
  16. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/__init__.py +11 -1
  17. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/detector.py +8 -9
  18. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/flyer.py +2 -2
  19. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/signal.py +102 -7
  20. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/signal_backend.py +2 -2
  21. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/sim_signal_backend.py +6 -6
  22. ophyd_async-0.3a3/src/ophyd_async/core/standard_readable.py +261 -0
  23. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/_backend/_aioca.py +6 -6
  24. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/_backend/_p4p.py +17 -11
  25. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/__init__.py +4 -0
  26. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/aravis.py +7 -9
  27. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/controllers/__init__.py +5 -0
  28. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/controllers/kinetix_controller.py +49 -0
  29. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/controllers/vimba_controller.py +66 -0
  30. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/drivers/__init__.py +6 -0
  31. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/drivers/kinetix_driver.py +24 -0
  32. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/drivers/vimba_driver.py +58 -0
  33. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/kinetix.py +46 -0
  34. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/pilatus.py +7 -12
  35. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/single_trigger_det.py +14 -6
  36. ophyd_async-0.3a3/src/ophyd_async/epics/areadetector/vimba.py +43 -0
  37. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/hdf_writer.py +6 -3
  38. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/nd_file_hdf.py +1 -0
  39. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/demo/__init__.py +19 -22
  40. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/motion/motor.py +11 -12
  41. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/signal/signal.py +1 -1
  42. ophyd_async-0.3a3/src/ophyd_async/log.py +130 -0
  43. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/writers/_hdf_writer.py +3 -3
  44. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/protocols.py +26 -3
  45. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/demo/sim_motor.py +11 -9
  46. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/pattern_generator.py +4 -4
  47. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/sim_pattern_detector_writer.py +2 -2
  48. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/sim_pattern_generator.py +2 -2
  49. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/PKG-INFO +20 -3
  50. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/SOURCES.txt +19 -0
  51. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/requires.txt +3 -1
  52. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_flyer.py +3 -3
  53. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_signal.py +75 -0
  54. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_sim.py +2 -2
  55. ophyd_async-0.3a3/tests/core/test_standard_readable.py +221 -0
  56. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_aravis.py +1 -26
  57. ophyd_async-0.3a3/tests/epics/areadetector/test_kinetix.py +125 -0
  58. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_pilatus.py +6 -45
  59. ophyd_async-0.3a3/tests/epics/areadetector/test_vimba.py +137 -0
  60. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/demo/test_demo.py +65 -35
  61. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/test_signals.py +4 -6
  62. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_hdf_panda.py +1 -6
  63. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/demo/test_sim_motor.py +29 -0
  64. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/test_sim_detector.py +1 -1
  65. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/test_streaming_plan.py +1 -6
  66. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/test_flyer_with_panda.py +3 -3
  67. ophyd_async-0.3a3/tests/test_log.py +88 -0
  68. ophyd_async-0.3a2/src/ophyd_async/core/standard_readable.py +0 -74
  69. ophyd_async-0.3a2/src/ophyd_async/epics/areadetector/controllers/__init__.py +0 -4
  70. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.codecov.yml +0 -0
  71. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.copier-answers.yml +0 -0
  72. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.devcontainer/devcontainer.json +0 -0
  73. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.git-blame-ignore-revs +0 -0
  74. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/CONTRIBUTING.md +0 -0
  75. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/actions/install_requirements/action.yml +0 -0
  76. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/dependabot.yml +0 -0
  77. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/pages/index.html +0 -0
  78. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/pages/make_switcher.py +0 -0
  79. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_check.yml +0 -0
  80. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_dist.yml +0 -0
  81. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_pypi.yml +0 -0
  82. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_release.yml +0 -0
  83. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_test.yml +0 -0
  84. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/_tox.yml +0 -0
  85. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/ci.yml +0 -0
  86. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.github/workflows/periodic.yml +0 -0
  87. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.gitignore +0 -0
  88. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.mailmap +0 -0
  89. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/.pre-commit-config.yaml +0 -0
  90. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/Dockerfile +0 -0
  91. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/LICENSE +0 -0
  92. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/_templates/README +0 -0
  93. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/_templates/custom-class-template.rst +0 -0
  94. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/_templates/custom-module-template.rst +0 -0
  95. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/examples/epics_demo.py +0 -0
  96. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  97. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  98. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
  99. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
  100. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
  101. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
  102. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions/COPYME +0 -0
  103. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/decisions.md +0 -0
  104. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations/event-loop-choice.rst +0 -0
  105. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/explanations.md +0 -0
  106. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/genindex.rst +0 -0
  107. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/how-to/compound-devices.rst +0 -0
  108. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/how-to/contribute.md +0 -0
  109. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/how-to/make-a-simple-device.rst +0 -0
  110. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/how-to.md +0 -0
  111. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -0
  112. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/images/bluesky_ophyd_logo.svg +0 -0
  113. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/images/ophyd_favicon.svg +0 -0
  114. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/index.md +0 -0
  115. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/reference/api.rst +0 -0
  116. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/reference.md +0 -0
  117. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/tutorials/installation.md +0 -0
  118. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/tutorials/using-existing-devices.rst +0 -0
  119. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/docs/tutorials.md +0 -0
  120. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/setup.cfg +0 -0
  121. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/__init__.py +0 -0
  122. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/__main__.py +0 -0
  123. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/_providers.py +0 -0
  124. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/async_status.py +0 -0
  125. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/device.py +0 -0
  126. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/device_save_loader.py +0 -0
  127. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/core/utils.py +0 -0
  128. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/__init__.py +0 -0
  129. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/_backend/__init__.py +0 -0
  130. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/_backend/common.py +0 -0
  131. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/controllers/ad_sim_controller.py +0 -0
  132. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/controllers/aravis_controller.py +0 -0
  133. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/controllers/pilatus_controller.py +0 -0
  134. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/drivers/ad_base.py +0 -0
  135. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/drivers/aravis_driver.py +0 -0
  136. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/drivers/pilatus_driver.py +0 -0
  137. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/utils.py +0 -0
  138. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/__init__.py +0 -0
  139. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/_hdfdataset.py +0 -0
  140. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/_hdffile.py +0 -0
  141. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -0
  142. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/demo/demo_ad_sim_detector.py +0 -0
  143. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/demo/mover.db +0 -0
  144. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/demo/sensor.db +0 -0
  145. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/motion/__init__.py +0 -0
  146. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/pvi/__init__.py +0 -0
  147. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/pvi/pvi.py +0 -0
  148. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/signal/__init__.py +0 -0
  149. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/epics/signal/_epics_transport.py +0 -0
  150. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/__init__.py +0 -0
  151. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_common_blocks.py +0 -0
  152. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_hdf_panda.py +0 -0
  153. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_panda_controller.py +0 -0
  154. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_table.py +0 -0
  155. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_trigger.py +0 -0
  156. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/_utils.py +0 -0
  157. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/writers/__init__.py +0 -0
  158. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/panda/writers/_panda_hdf_file.py +0 -0
  159. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/planstubs/__init__.py +0 -0
  160. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/planstubs/prepare_trigger_and_dets.py +0 -0
  161. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/__init__.py +0 -0
  162. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/demo/__init__.py +0 -0
  163. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async/sim/sim_pattern_detector_control.py +0 -0
  164. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
  165. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/entry_points.txt +0 -0
  166. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/src/ophyd_async.egg-info/top_level.txt +0 -0
  167. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/conftest.py +0 -0
  168. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_async_status.py +0 -0
  169. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_device.py +0 -0
  170. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_device_collector.py +0 -0
  171. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_device_save_loader.py +0 -0
  172. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/core/test_utils.py +0 -0
  173. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/_backend/test_common.py +0 -0
  174. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/__init__.py +0 -0
  175. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_controllers.py +0 -0
  176. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_drivers.py +0 -0
  177. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_scans.py +0 -0
  178. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_single_trigger_det.py +0 -0
  179. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_utils.py +0 -0
  180. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/areadetector/test_writers.py +0 -0
  181. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/demo/test_demo_ad_sim_detector.py +0 -0
  182. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/motion/__init__.py +0 -0
  183. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/motion/test_motor.py +0 -0
  184. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/test_pvi.py +0 -0
  185. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/epics/test_records.db +0 -0
  186. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/db/panda.db +0 -0
  187. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_panda_connect.py +0 -0
  188. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_panda_controller.py +0 -0
  189. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_panda_utils.py +0 -0
  190. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_table.py +0 -0
  191. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_trigger.py +0 -0
  192. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/panda/test_writer.py +0 -0
  193. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/protocols/test_protocols.py +0 -0
  194. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/__init__.py +0 -0
  195. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/conftest.py +0 -0
  196. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/demo/__init__.py +0 -0
  197. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/test_pattern_generator.py +0 -0
  198. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/sim/test_sim_writer.py +0 -0
  199. {ophyd_async-0.3a2 → ophyd_async-0.3a3}/tests/test_cli.py +0 -0
@@ -47,7 +47,7 @@ jobs:
47
47
  if: github.ref_type == 'tag' || github.ref_name == 'main'
48
48
  # We pin to the SHA, not the tag, for security reasons.
49
49
  # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions
50
- uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3
50
+ uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
51
51
  with:
52
52
  github_token: ${{ secrets.GITHUB_TOKEN }}
53
53
  publish_dir: .github/pages
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ophyd-async
3
- Version: 0.3a2
3
+ Version: 0.3a3
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
@@ -72,7 +72,7 @@ Requires-Dist: pipdeptree; extra == "dev"
72
72
  Requires-Dist: pre-commit; extra == "dev"
73
73
  Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
74
74
  Requires-Dist: pyepics>=3.4.2; extra == "dev"
75
- Requires-Dist: pyside6==6.6.2; extra == "dev"
75
+ Requires-Dist: pyside6==6.7.0; extra == "dev"
76
76
  Requires-Dist: pytest; extra == "dev"
77
77
  Requires-Dist: pytest-asyncio; extra == "dev"
78
78
  Requires-Dist: pytest-cov; extra == "dev"
@@ -81,18 +81,20 @@ Requires-Dist: pytest-rerunfailures; extra == "dev"
81
81
  Requires-Dist: pytest-timeout; extra == "dev"
82
82
  Requires-Dist: ruff; extra == "dev"
83
83
  Requires-Dist: sphinx-autobuild; extra == "dev"
84
+ Requires-Dist: sphinxcontrib-mermaid; extra == "dev"
84
85
  Requires-Dist: sphinx-copybutton; extra == "dev"
85
86
  Requires-Dist: sphinx-design; extra == "dev"
86
87
  Requires-Dist: tox-direct; extra == "dev"
87
88
  Requires-Dist: types-mock; extra == "dev"
88
89
  Requires-Dist: types-pyyaml; extra == "dev"
90
+ Requires-Dist: colorlog; extra == "dev"
89
91
 
90
92
  [![CI](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml/badge.svg)](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
91
93
  [![Coverage](https://codecov.io/gh/bluesky/ophyd-async/branch/main/graph/badge.svg)](https://codecov.io/gh/bluesky/ophyd-async)
92
94
  [![PyPI](https://img.shields.io/pypi/v/ophyd-async.svg)](https://pypi.org/project/ophyd-async)
93
95
  [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
94
96
 
95
- # ophyd_async
97
+ # ophyd-async
96
98
 
97
99
  Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
98
100
 
@@ -102,6 +104,21 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
102
104
  | Documentation | <https://bluesky.github.io/ophyd-async> |
103
105
  | Releases | <https://github.com/bluesky/ophyd-async/releases> |
104
106
 
107
+ Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
108
+ be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
109
+ systems.
110
+
111
+ Both ophyd and ophyd-async are typically used with the [Bluesky Run Engine][] for experiment orchestration and data acquisition.
112
+
113
+ While [EPICS][] is the most common control system layer that ophyd-async can interface with, support for other control systems like [Tango][] will be supported in the future. The focus of ophyd-async is:
114
+
115
+ * Asynchronous signal access, opening the possibility for hardware-triggered scanning (also known as fly-scanning)
116
+ * Simpler instantiation of devices (groupings of signals) with less reliance upon complex class hierarchies
117
+
118
+ [Bluesky Run Engine]: http://blueskyproject.io/bluesky
119
+ [EPICS]: http://www.aps.anl.gov/epics/
120
+ [Tango]: https://www.tango-controls.org/
121
+
105
122
  <!-- README only content. Anything below this line won't be included in index.md -->
106
123
 
107
124
  See https://bluesky.github.io/ophyd-async for more detailed documentation.
@@ -3,7 +3,7 @@
3
3
  [![PyPI](https://img.shields.io/pypi/v/ophyd-async.svg)](https://pypi.org/project/ophyd-async)
4
4
  [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
5
5
 
6
- # ophyd_async
6
+ # ophyd-async
7
7
 
8
8
  Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
9
9
 
@@ -13,6 +13,21 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
13
13
  | Documentation | <https://bluesky.github.io/ophyd-async> |
14
14
  | Releases | <https://github.com/bluesky/ophyd-async/releases> |
15
15
 
16
+ Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
17
+ be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
18
+ systems.
19
+
20
+ Both ophyd and ophyd-async are typically used with the [Bluesky Run Engine][] for experiment orchestration and data acquisition.
21
+
22
+ While [EPICS][] is the most common control system layer that ophyd-async can interface with, support for other control systems like [Tango][] will be supported in the future. The focus of ophyd-async is:
23
+
24
+ * Asynchronous signal access, opening the possibility for hardware-triggered scanning (also known as fly-scanning)
25
+ * Simpler instantiation of devices (groupings of signals) with less reliance upon complex class hierarchies
26
+
27
+ [Bluesky Run Engine]: http://blueskyproject.io/bluesky
28
+ [EPICS]: http://www.aps.anl.gov/epics/
29
+ [Tango]: https://www.tango-controls.org/
30
+
16
31
  <!-- README only content. Anything below this line won't be included in index.md -->
17
32
 
18
33
  See https://bluesky.github.io/ophyd-async for more detailed documentation.
@@ -32,6 +32,8 @@ else:
32
32
  version = release
33
33
 
34
34
  extensions = [
35
+ # for diagrams
36
+ "sphinxcontrib.mermaid",
35
37
  # Use this for generating API docs
36
38
  "sphinx.ext.autodoc",
37
39
  "sphinx.ext.doctest",
@@ -57,6 +59,9 @@ extensions = [
57
59
  "numpydoc",
58
60
  ]
59
61
 
62
+ # So we can use the ::: syntax
63
+ myst_enable_extensions = ["colon_fence"]
64
+
60
65
  napoleon_google_docstring = False
61
66
  napoleon_numpy_docstring = True
62
67
 
@@ -184,11 +189,6 @@ html_theme_options = {
184
189
  "url": f"https://pypi.org/project/{project}",
185
190
  "icon": "fas fa-cube",
186
191
  },
187
- {
188
- "name": "Gitter",
189
- "url": "https://gitter.im/NSLS-II/DAMA",
190
- "icon": "fas fa-person-circle-question",
191
- },
192
192
  ],
193
193
  "switcher": {
194
194
  "json_url": switcher_json,
@@ -201,10 +201,6 @@ html_theme_options = {
201
201
  "name": "Bluesky Project",
202
202
  "url": "https://blueskyproject.io",
203
203
  },
204
- {
205
- "name": "Release Notes",
206
- "url": f"https://github.com/{github_user}/{github_repo}/releases",
207
- },
208
204
  ],
209
205
  "navigation_with_keys": False,
210
206
  }
@@ -0,0 +1,82 @@
1
+ import asyncio
2
+ from typing import Optional
3
+
4
+ from bluesky.protocols import HasHints, Hints
5
+
6
+ from ophyd_async.core import DirectoryProvider
7
+ from ophyd_async.core.async_status import AsyncStatus
8
+ from ophyd_async.core.detector import DetectorControl, DetectorTrigger, StandardDetector
9
+ from ophyd_async.epics.areadetector.drivers.ad_base import (
10
+ ADBase,
11
+ ADBaseShapeProvider,
12
+ start_acquiring_driver_and_ensure_status,
13
+ )
14
+ from ophyd_async.epics.areadetector.utils import ImageMode, ad_rw, stop_busy_record
15
+ from ophyd_async.epics.areadetector.writers.hdf_writer import HDFWriter
16
+ from ophyd_async.epics.areadetector.writers.nd_file_hdf import NDFileHDF
17
+
18
+
19
+ class FooDriver(ADBase):
20
+ def __init__(self, prefix: str, name: str = "") -> None:
21
+ self.trigger_mode = ad_rw(str, prefix + "TriggerMode")
22
+ super().__init__(prefix, name)
23
+
24
+
25
+ class FooController(DetectorControl):
26
+ def __init__(self, driver: FooDriver) -> None:
27
+ self._drv = driver
28
+
29
+ def get_deadtime(self, exposure: float) -> float:
30
+ # FooDetector deadtime handling
31
+ return 0.001
32
+
33
+ async def arm(
34
+ self,
35
+ num: int,
36
+ trigger: DetectorTrigger = DetectorTrigger.internal,
37
+ exposure: Optional[float] = None,
38
+ ) -> AsyncStatus:
39
+ await asyncio.gather(
40
+ self._drv.num_images.set(num),
41
+ self._drv.image_mode.set(ImageMode.multiple),
42
+ self._drv.trigger_mode.set(f"FOO{trigger}"),
43
+ )
44
+ if exposure is not None:
45
+ await self._drv.acquire_time.set(exposure)
46
+ return await start_acquiring_driver_and_ensure_status(self._drv)
47
+
48
+ async def disarm(self):
49
+ await stop_busy_record(self._drv.acquire, False, timeout=1)
50
+
51
+
52
+ class FooDetector(StandardDetector, HasHints):
53
+ _controller: FooController
54
+ _writer: HDFWriter
55
+
56
+ def __init__(
57
+ self,
58
+ prefix: str,
59
+ directory_provider: DirectoryProvider,
60
+ drv_suffix="cam1:",
61
+ hdf_suffix="HDF1:",
62
+ name="",
63
+ ):
64
+ # Must be children to pick up connect
65
+ self.drv = FooDriver(prefix + drv_suffix)
66
+ self.hdf = NDFileHDF(prefix + hdf_suffix)
67
+
68
+ super().__init__(
69
+ FooController(self.drv),
70
+ HDFWriter(
71
+ self.hdf,
72
+ directory_provider,
73
+ lambda: self.name,
74
+ ADBaseShapeProvider(self.drv),
75
+ ),
76
+ config_sigs=(self.drv.acquire_time,),
77
+ name=name,
78
+ )
79
+
80
+ @property
81
+ def hints(self) -> Hints:
82
+ return self._writer.hints
@@ -0,0 +1,57 @@
1
+ Design Goals
2
+ ============
3
+
4
+
5
+ Parity with Ophyd
6
+ -----------------
7
+
8
+ It should be possible to migrate applications that use ophyd_ to ophyd-async. Meaning it must support:
9
+
10
+ - Definition of devices
11
+ - Conformity to the bluesky protocols
12
+ - Epics (ChannelAccess) as a backend
13
+
14
+ Ophyd-async should provide built-in support logic for controlling `the same set of devices as ophyd <https://blueskyproject.io/ophyd/user/reference/builtin-devices.html>`_.
15
+
16
+
17
+ Clean Device Definition
18
+ -----------------------
19
+
20
+ It should be easy to define devices with signals that talk to multiple backends and to cleanly organize device logic via composition.
21
+
22
+ We need to be able to:
23
+
24
+ - Separate the Device interface from the multiple pieces of logic that might use that Device in a particular way
25
+ - Define that Signals of a particular type exist without creating them so backends like Tango or EPICS + PVI can fill them in
26
+
27
+
28
+ Parity with Malcolm
29
+ -------------------
30
+
31
+ .. seealso:: `./flyscanning`
32
+
33
+ Ophyd-async should provide the same building blocks for defining flyscans scans as malcolm_. It should support PandA and Zebra as timing masters by default, but also provide easy helpers for developers to write support for their own devices.
34
+
35
+ It should enable `motor trajectory scanning <motortraj_>` and `multiple triggering rates<detectorsync_>` based around a base rate, and pausing/resuming scans. Scans should be modelled using scanspec_, which serves as a universal language for defining trajectory and time-resolved scans, and converted to the underlying format of the given motion controller. It should also be possible to define an `outer scan <outerscan_>`.
36
+
37
+
38
+ Improved Trajectory Calculation
39
+ -------------------------------
40
+
41
+ Ophyd-async will provide and improve upon the algorithms that malcolm_ uses to calculate trajectories for supported hardware.
42
+
43
+ The EPICS pmac_ module supports trajectory scanning, specifying a growing array of positions, velocities and time for axes to move through to perform a scan.
44
+ Ophyd-async will provide mechanisms for specifying these scans via a scanspec_, calculating run-ups and turnarounds based on motor parameters, keeping the trajectory scan arrays filled based on the ScanSpec, and allowing this scan to be paused and resumed.
45
+
46
+
47
+ Outstanding Design Decisions
48
+ ----------------------------
49
+
50
+ To view and contribute to discussions on outstanding decisions, please see the design_ label in our Github issues.
51
+
52
+
53
+ .. _ophyd: https://github.com/bluesky/ophyd
54
+ .. _malcolm: https://github.com/dls-controls/pymalcolm
55
+ .. _scanspec: https://github.com/dls-controls/scanspec
56
+ .. _design: https://github.com/bluesky/ophyd-async/issues?q=is%3Aissue+is%3Aopen+label%3Adesign
57
+ .. _pmac: https://github.com/dls-controls/pmac
@@ -0,0 +1,63 @@
1
+ Flyscanning
2
+ ===========
3
+
4
+ Flyscanning (also known as hardware triggered scanning, asynchronous acquisition, and hardware synchronized scanning) is the practice of accelerating the rate of data collection by handing control over to an external hardware system that can control and synchronize the triggering of detectors with other signals and/or commands. Flyscans take many forms.
5
+
6
+ .. _detectorsync_:
7
+
8
+ Detector Synchronization
9
+ ------------------------
10
+
11
+ .. figure:: ../images/simple-hardware-scan.png
12
+ :alt: hardware-triggered setup
13
+ :width: 300
14
+
15
+ A triggering system can send pulses to two or more detectors to make them expose simultaneously, or at different multiples of the same base rate (e.g. 200Hz and 400Hz).
16
+
17
+ .. _motortraj_:
18
+
19
+ Motor Trajectory Scanning
20
+ -------------------------
21
+
22
+ .. figure:: ../images/hardware-triggered-scan.png
23
+ :alt: trajectory scanning setup
24
+
25
+ The triggering system can be configured to trigger the detectors at the same time as the motion controller commands the motors to go to certain points, or even exactly when they reach those points, using the readback values. This can be achieved on the scale of microseconds/nanoseconds, in comparison to traditional soft scans controlled via a network, which normally synchronize on the scale of seconds.
26
+
27
+ .. _outerscan_:
28
+
29
+ Outer Scanning
30
+ --------------
31
+
32
+ Outer scans are flyscans nested inside soft scans.
33
+
34
+ .. figure:: ../images/outer-scan.png
35
+ :alt: hardware-triggered setup
36
+
37
+ In the example above a 2D grid scan in ``x`` and ``y`` is repeated in a third dimension: ``z``. Given that ``z`` only needs to move for every 1 in every 25 points, it could be synchronized via software rather than hardware without significantly affecting scan time (and saving the effort/expense of wiring it into a triggering system). It then becomes the responsibility of the software to move ``z``, hand control to the external hardware, wait for one grid's worth of points, take control back, and repeat.
38
+
39
+
40
+ Hardware
41
+ --------
42
+
43
+ Ophyd-async ships with support for Quantum Detectors' PandA_ and Zebra_ as triggering mechanisms.
44
+
45
+ These are very modular and can be used to trigger a variety of detectors and handle readback signals from a variety of sample control devices. See full specs for more information.
46
+
47
+ It is possible to write support for additional systems/devices.
48
+
49
+
50
+ Role of Ophyd-Async
51
+ -------------------
52
+
53
+ Bluesky supports devices that configure acquisition and then hand over control to an external system via the ``Flyer`` protocol.
54
+
55
+ Ophyd-async's job is to provide devices that implement ``Flyer`` and can:
56
+
57
+ - Configure all necessary hardware for a scan
58
+ - Kickoff a scan and monitor progress until complete
59
+ - Produce documents representing the progress of the scan
60
+ - Allow handing control back and forth to enable outer scanning
61
+
62
+ .. _PandA: https://quantumdetectors.com/products/pandabox/
63
+ .. _Zebra: https://quantumdetectors.com/products/zebra/
@@ -0,0 +1,15 @@
1
+ # Decision Flowchart for Creating a New ophyd_async Device
2
+
3
+ This document contains a decision flowchart designed to guide developers through the process of creating a new ophyd_async device in the Ophyd library. It outlines a series of decisions based on the device's capabilities, such as file writing, reading values from process variables (PVs), and mobility within scans. The flowchart helps in determining the appropriate class inheritance and methods to override for optimal device functionality and integration into the system.
4
+
5
+ ```{mermaid}
6
+
7
+ flowchart TD
8
+ start([Start]) --> isFileWriting{Is it a File Writing Detector?}
9
+ isFileWriting -- Yes --> useStandardDetector[Use StandardDetector]
10
+ isFileWriting -- No --> producesPVValue{Does it produce a value from a PV you want to read in a scan?}
11
+ producesPVValue -- Yes --> isMovable{Is it something that you move in a scan?}
12
+ isMovable -- Yes --> useReadableMovable[Use StandardReadable + AsyncMovable + Override set method]
13
+ isMovable -- No --> useReadable[Use StandardReadable]
14
+ producesPVValue -- No --> useDevice[Use Device]
15
+ ```
@@ -0,0 +1,64 @@
1
+ .. note::
2
+
3
+ Ophyd async is included on a provisional basis until the v1.0 release and
4
+ may change API on minor release numbers before then
5
+
6
+ Make a StandardDetector
7
+ =======================
8
+
9
+ `StandardDetector` is an abstract class to assist in creating Device classes for hardware that writes its own data e.g. an AreaDetector implementation, or a PandA writing motor encoder positions to file.
10
+ The `StandardDetector` is a simple compound device, with 2 standard components:
11
+
12
+ - `DetectorWriter` to handle data persistence, i/o and pass information about data to the RunEngine (usually an instance of :py:class:`HDFWriter`)
13
+ - `DetectorControl` with logic for arming and disarming the detector. This will be unique to the StandardDetector implementation.
14
+
15
+ Writing an AreaDetector StandardDetector
16
+ ----------------------------------------
17
+
18
+ For an AreaDetector implementation of the StandardDetector, two entity objects which are subdevices of the `StandardDetector` are used to map to AreaDetector plugins:
19
+
20
+ - An NDPluginFile instance (for :py:class:`HDFWriter` an instance of :py:class:`NDFileHDF`)
21
+ - An :py:class:`ADBase` instance mapping to NDArray for the "driver" of the detector implementation
22
+
23
+
24
+ Define a :py:class:`FooDriver` if the NDArray requires fields in addition to those on :py:class:`ADBase` to be exposed. It should extend :py:class:`ADBase`.
25
+ Enumeration fields should be named to prevent namespace collision, i.e. for a Signal named "TriggerSource" use the enum "FooTriggerSource"
26
+
27
+ .. literalinclude:: ../examples/foo_detector.py
28
+ :language: python
29
+ :pyobject: FooDriver
30
+
31
+ Define a :py:class:`FooController` with handling for converting the standard pattern of :py:meth:`ophyd_async.core.DetectorControl.arm` and :py:meth:`ophyd_async.core.DetectorControl.disarm` to required state of :py:class:`FooDriver` e.g. setting a compatible "FooTriggerSource" for a given `DetectorTrigger`, or raising an exception if incompatible with the `DetectorTrigger`.
32
+
33
+ The :py:meth:`ophyd_async.core.DetectorControl.get_deadtime` method is used when constructing sequence tables for hardware controlled scanning. Details on how to calculate the deadtime may be only available from technical manuals or otherwise complex. **If it requires fetching from signals, it is recommended to cache the value during the StandardDetector `prepare` method.**
34
+
35
+ .. literalinclude:: ../examples/foo_detector.py
36
+ :pyobject: FooController
37
+
38
+ :py:class:`FooDetector` ties the Driver, Controller and data persistence layer together. The example :py:class:`FooDetector` writes h5 files using the standard NDPlugin. It additionally supports the :py:class:`HasHints` protocol which is optional but recommended.
39
+
40
+ Its initialiser assumes the NSLS-II AreaDetector plugin EPICS address suffixes as defaults but allows overriding: **this pattern is recommended for consistency**.
41
+ If the :py:class:`FooDriver` signals that should be read as configuration, they should be added to the "config_sigs" passed to the super.
42
+
43
+ .. literalinclude:: ../examples/foo_detector.py
44
+ :pyobject: FooDetector
45
+
46
+
47
+ Writing a non-AreaDetector StandardDetector
48
+ -------------------------------------------
49
+
50
+ A non-AreaDetector `StandardDetector` should implement `DetectorControl` and `DetectorWriter` directly.
51
+ Here we construct a `DetectorControl` that co-ordinates signals on a PandA PositionCapture block - a child device "pcap" of the `StandardDetector` implementation, analogous to the :py:class:`FooDriver`.
52
+
53
+ .. literalinclude:: ../../src/ophyd_async/panda/_panda_controller.py
54
+ :pyobject: PandaPcapController
55
+
56
+ The PandA may write a number of fields, and the :py:class:`PandaHDFWriter` co-ordinates those, configures the filewriter and describes the data for the RunEngine.
57
+
58
+ .. literalinclude:: ../../src/ophyd_async/panda/writers/_hdf_writer.py
59
+ :pyobject: PandaHDFWriter
60
+
61
+ The PandA StandardDetector implementation simply ties the component parts and its child devices together.
62
+
63
+ .. literalinclude:: ../../src/ophyd_async/panda/_hdf_panda.py
64
+ :pyobject: HDFPanda
@@ -35,6 +35,8 @@ Sim Utility Functions
35
35
 
36
36
  Sim signals behave as simply as possible, holding a sensible default value when initialized and retaining any value (in memory) to which they are set. This model breaks down in the case of read-only signals, which cannot be set because there is an expectation of some external device setting them in the real world. There is a utility function, ``set_sim_value``, to mock-set values for sim signals, including read-only ones.
37
37
 
38
+ In addition this example also utilizes helper functions like ``assert_reading`` and ``assert_value`` to ensure the validity of device readings and values. For more information see: :doc:`API.core<../generated/ophyd_async.core>`
39
+
38
40
  .. literalinclude:: ../../tests/epics/demo/test_demo.py
39
41
  :pyobject: test_sensor_reading_shows_value
40
42
 
@@ -43,3 +45,12 @@ There is another utility function, ``set_sim_callback``, for hooking in logic wh
43
45
 
44
46
  .. literalinclude:: ../../tests/epics/demo/test_demo.py
45
47
  :pyobject: test_mover_stopped
48
+
49
+
50
+ Testing a Device in a Plan with the RunEngine
51
+ ---------------------------------------------
52
+ .. literalinclude:: ../../tests/epics/demo/test_demo.py
53
+ :pyobject: test_sensor_in_plan
54
+
55
+
56
+ This test verifies that the sim_sensor behaves as expected within a plan. The plan we use here is a ``count``, which takes a specified number of readings from the ``sim_sensor``. Since we set the ``repeat`` to two in this test, the sensor should emit two "event" documents along with "start", "stop" and "descriptor" documents. Finally, we use the helper function ``assert_emitted`` to confirm that the emitted documents match our expectations.
@@ -49,7 +49,7 @@ dev = [
49
49
  "pre-commit",
50
50
  "pydata-sphinx-theme>=0.12",
51
51
  "pyepics>=3.4.2",
52
- "pyside6==6.6.2",
52
+ "pyside6==6.7.0",
53
53
  "pytest",
54
54
  "pytest-asyncio",
55
55
  "pytest-cov",
@@ -58,11 +58,13 @@ dev = [
58
58
  "pytest-timeout",
59
59
  "ruff",
60
60
  "sphinx-autobuild",
61
+ "sphinxcontrib-mermaid",
61
62
  "sphinx-copybutton",
62
63
  "sphinx-design",
63
64
  "tox-direct",
64
65
  "types-mock",
65
66
  "types-pyyaml",
67
+ "colorlog"
66
68
  ]
67
69
 
68
70
  [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.3a2'
15
+ __version__ = version = '0.3a3'
16
16
  __version_tuple__ = version_tuple = (0, 3)
@@ -30,6 +30,10 @@ from .signal import (
30
30
  SignalRW,
31
31
  SignalW,
32
32
  SignalX,
33
+ assert_configuration,
34
+ assert_emitted,
35
+ assert_reading,
36
+ assert_value,
33
37
  observe_value,
34
38
  set_and_wait_for_value,
35
39
  set_sim_callback,
@@ -41,7 +45,7 @@ from .signal import (
41
45
  )
42
46
  from .signal_backend import SignalBackend
43
47
  from .sim_signal_backend import SimSignalBackend
44
- from .standard_readable import StandardReadable
48
+ from .standard_readable import ConfigSignal, HintedSignal, StandardReadable
45
49
  from .utils import (
46
50
  DEFAULT_TIMEOUT,
47
51
  Callback,
@@ -84,6 +88,8 @@ __all__ = [
84
88
  "ShapeProvider",
85
89
  "StaticDirectoryProvider",
86
90
  "StandardReadable",
91
+ "ConfigSignal",
92
+ "HintedSignal",
87
93
  "TriggerInfo",
88
94
  "TriggerLogic",
89
95
  "HardwareTriggeredFlyable",
@@ -103,4 +109,8 @@ __all__ = [
103
109
  "walk_rw_signals",
104
110
  "load_device",
105
111
  "save_device",
112
+ "assert_reading",
113
+ "assert_value",
114
+ "assert_configuration",
115
+ "assert_emitted",
106
116
  ]
@@ -19,7 +19,7 @@ from typing import (
19
19
 
20
20
  from bluesky.protocols import (
21
21
  Collectable,
22
- Descriptor,
22
+ DataKey,
23
23
  Flyable,
24
24
  Preparable,
25
25
  Reading,
@@ -33,7 +33,6 @@ from ophyd_async.protocols import AsyncConfigurable, AsyncReadable
33
33
 
34
34
  from .async_status import AsyncStatus
35
35
  from .device import Device
36
- from .signal import SignalR
37
36
  from .utils import DEFAULT_TIMEOUT, merge_gathered_dicts
38
37
 
39
38
  T = TypeVar("T")
@@ -110,7 +109,7 @@ class DetectorWriter(ABC):
110
109
  (e.g. an HDF5 file)"""
111
110
 
112
111
  @abstractmethod
113
- async def open(self, multiplier: int = 1) -> Dict[str, Descriptor]:
112
+ async def open(self, multiplier: int = 1) -> Dict[str, DataKey]:
114
113
  """Open writer and wait for it to be ready for data.
115
114
 
116
115
  Args:
@@ -161,7 +160,7 @@ class StandardDetector(
161
160
  self,
162
161
  controller: DetectorControl,
163
162
  writer: DetectorWriter,
164
- config_sigs: Sequence[SignalR] = (),
163
+ config_sigs: Sequence[AsyncReadable] = (),
165
164
  name: str = "",
166
165
  writer_timeout: float = DEFAULT_TIMEOUT,
167
166
  ) -> None:
@@ -181,7 +180,7 @@ class StandardDetector(
181
180
  """
182
181
  self._controller = controller
183
182
  self._writer = writer
184
- self._describe: Dict[str, Descriptor] = {}
183
+ self._describe: Dict[str, DataKey] = {}
185
184
  self._config_sigs = list(config_sigs)
186
185
  self._frame_writing_timeout = writer_timeout
187
186
  # For prepare
@@ -214,7 +213,7 @@ class StandardDetector(
214
213
  async def _check_config_sigs(self):
215
214
  """Checks configuration signals are named and connected."""
216
215
  for signal in self._config_sigs:
217
- if signal._name == "":
216
+ if signal.name == "":
218
217
  raise Exception(
219
218
  "config signal must be named before it is passed to the detector"
220
219
  )
@@ -234,14 +233,14 @@ class StandardDetector(
234
233
  async def read_configuration(self) -> Dict[str, Reading]:
235
234
  return await merge_gathered_dicts(sig.read() for sig in self._config_sigs)
236
235
 
237
- async def describe_configuration(self) -> Dict[str, Descriptor]:
236
+ async def describe_configuration(self) -> Dict[str, DataKey]:
238
237
  return await merge_gathered_dicts(sig.describe() for sig in self._config_sigs)
239
238
 
240
239
  async def read(self) -> Dict[str, Reading]:
241
240
  # All data is in StreamResources, not Events, so nothing to output here
242
241
  return {}
243
242
 
244
- async def describe(self) -> Dict[str, Descriptor]:
243
+ async def describe(self) -> Dict[str, DataKey]:
245
244
  return self._describe
246
245
 
247
246
  @AsyncStatus.wrap
@@ -330,7 +329,7 @@ class StandardDetector(
330
329
  assert self._fly_status, "Kickoff not run"
331
330
  return await self._fly_status
332
331
 
333
- async def describe_collect(self) -> Dict[str, Descriptor]:
332
+ async def describe_collect(self) -> Dict[str, DataKey]:
334
333
  return self._describe
335
334
 
336
335
  async def collect_asset_docs(
@@ -1,7 +1,7 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from typing import Dict, Generic, Sequence, TypeVar
3
3
 
4
- from bluesky.protocols import Descriptor, Flyable, Preparable, Reading, Stageable
4
+ from bluesky.protocols import DataKey, Flyable, Preparable, Reading, Stageable
5
5
 
6
6
  from .async_status import AsyncStatus
7
7
  from .device import Device
@@ -74,7 +74,7 @@ class HardwareTriggeredFlyable(
74
74
  async def complete(self) -> None:
75
75
  await self._trigger_logic.complete()
76
76
 
77
- async def describe_configuration(self) -> Dict[str, Descriptor]:
77
+ async def describe_configuration(self) -> Dict[str, DataKey]:
78
78
  return await merge_gathered_dicts(
79
79
  [sig.describe() for sig in self._configuration_signals]
80
80
  )