ophyd-async 0.12.1__tar.gz → 0.12.3__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 (300) hide show
  1. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/PKG-INFO +2 -2
  2. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/pyproject.toml +1 -1
  3. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/_version.py +2 -2
  4. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/__init__.py +0 -2
  5. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_core_logic.py +4 -3
  6. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_core_writer.py +2 -3
  7. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_utils.py +0 -14
  8. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/__init__.py +2 -0
  9. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_util.py +12 -0
  10. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/eiger/_odin_io.py +25 -7
  11. ophyd_async-0.12.3/src/ophyd_async/epics/pmac/__init__.py +3 -0
  12. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/pmac/_pmac_io.py +33 -23
  13. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/eiger/_eiger.py +1 -1
  14. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/eiger/_eiger_io.py +2 -1
  15. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async.egg-info/PKG-INFO +2 -2
  16. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async.egg-info/requires.txt +1 -1
  17. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/eiger/test_odin_io.py +53 -29
  18. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/pmac/test_pmac_io.py +30 -9
  19. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/eiger/test_eiger_detector.py +11 -2
  20. ophyd_async-0.12.1/src/ophyd_async/epics/pmac/__init__.py +0 -3
  21. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.codecov.yml +0 -0
  22. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.copier-answers.yml +0 -0
  23. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.devcontainer/devcontainer.json +0 -0
  24. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.git-blame-ignore-revs +0 -0
  25. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/CONTRIBUTING.md +0 -0
  26. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  27. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  28. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  29. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/actions/install_requirements/action.yml +0 -0
  30. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/codeql/codeql-config.yml +0 -0
  31. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/dependabot.yml +0 -0
  32. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/pages/index.html +0 -0
  33. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/pages/make_switcher.py +0 -0
  34. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_check.yml +0 -0
  35. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_codeql.yml +0 -0
  36. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_dist.yml +0 -0
  37. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_docs.yml +0 -0
  38. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_import_with_no_extras.yml +0 -0
  39. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_pypi.yml +0 -0
  40. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_release.yml +0 -0
  41. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_test.yml +0 -0
  42. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/_tox.yml +0 -0
  43. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/ci.yml +0 -0
  44. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.github/workflows/periodic.yml +0 -0
  45. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.gitignore +0 -0
  46. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/.pre-commit-config.yaml +0 -0
  47. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/Dockerfile +0 -0
  48. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/LICENSE +0 -0
  49. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/README.md +0 -0
  50. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/_static/custom.css +0 -0
  51. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/conf.py +0 -0
  52. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  53. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  54. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
  55. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
  56. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
  57. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
  58. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
  59. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0008-signal-types.md +0 -0
  60. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +0 -0
  61. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/0010-docstring-format.md +0 -0
  62. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions/COPYME +0 -0
  63. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/decisions.md +0 -0
  64. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/declarative-vs-procedural.md +0 -0
  65. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/design-goals.md +0 -0
  66. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/device-connection-strategies.md +0 -0
  67. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/devices-signals-backends.md +0 -0
  68. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/fly-scanning.md +0 -0
  69. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/plan-stubs.md +0 -0
  70. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations/where-device-logic.md +0 -0
  71. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/explanations.md +0 -0
  72. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/genindex.rst +0 -0
  73. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/choose-right-baseclass.md +0 -0
  74. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/contribute.md +0 -0
  75. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/derive-one-signal-from-others.md +0 -0
  76. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/implement-ad-detector.md +0 -0
  77. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/interact-with-signals.md +0 -0
  78. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/put-device-back.md +0 -0
  79. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to/store-and-retrieve.md +0 -0
  80. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/how-to.md +0 -0
  81. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/images/fly_scan_collection_windows_and_frames.svg +0 -0
  82. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/images/ophyd-async-logo.svg +0 -0
  83. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/images/ophyd-favicon.svg +0 -0
  84. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/images/set_and_wait_for_other_value.excalidraw.svg +0 -0
  85. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/index.md +0 -0
  86. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/reference.md +0 -0
  87. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials/implementing-detectors.md +0 -0
  88. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials/implementing-devices.md +0 -0
  89. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials/installation.md +0 -0
  90. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials/using-devices.md +0 -0
  91. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials/writing-tests-for-devices.md +0 -0
  92. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/docs/tutorials.md +0 -0
  93. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/setup.cfg +0 -0
  94. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/__init__.py +0 -0
  95. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/__main__.py +0 -0
  96. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/_docs_parser.py +0 -0
  97. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/__init__.py +0 -0
  98. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_derived_signal.py +0 -0
  99. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_derived_signal_backend.py +0 -0
  100. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_detector.py +0 -0
  101. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_device.py +0 -0
  102. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_device_filler.py +0 -0
  103. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_flyer.py +0 -0
  104. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_hdf_dataset.py +0 -0
  105. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_log.py +0 -0
  106. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
  107. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_protocol.py +0 -0
  108. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_providers.py +0 -0
  109. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_readable.py +0 -0
  110. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_settings.py +0 -0
  111. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_signal.py +0 -0
  112. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_signal_backend.py +0 -0
  113. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_soft_signal_backend.py +0 -0
  114. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_status.py +0 -0
  115. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_table.py +0 -0
  116. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_utils.py +0 -0
  117. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/core/_yaml_settings.py +0 -0
  118. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/__init__.py +0 -0
  119. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adandor/__init__.py +0 -0
  120. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adandor/_andor.py +0 -0
  121. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adandor/_andor_controller.py +0 -0
  122. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adandor/_andor_io.py +0 -0
  123. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
  124. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
  125. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adaravis/_aravis_controller.py +0 -0
  126. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adaravis/_aravis_io.py +0 -0
  127. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_core_detector.py +0 -0
  128. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_core_io.py +0 -0
  129. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_hdf_writer.py +0 -0
  130. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_jpeg_writer.py +0 -0
  131. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_single_trigger.py +0 -0
  132. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adcore/_tiff_writer.py +0 -0
  133. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
  134. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
  135. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -0
  136. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +0 -0
  137. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
  138. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -0
  139. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +0 -0
  140. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +0 -0
  141. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
  142. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
  143. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -0
  144. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/adsimdetector/_sim_io.py +0 -0
  145. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/advimba/__init__.py +0 -0
  146. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
  147. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -0
  148. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/advimba/_vimba_io.py +0 -0
  149. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_aioca.py +0 -0
  150. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
  151. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_epics_device.py +0 -0
  152. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_p4p.py +0 -0
  153. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_pvi_connector.py +0 -0
  154. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/core/_signal.py +0 -0
  155. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/__init__.py +0 -0
  156. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/__main__.py +0 -0
  157. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/_ioc.py +0 -0
  158. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/_motor.py +0 -0
  159. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/_point_detector.py +0 -0
  160. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/_point_detector_channel.py +0 -0
  161. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/_stage.py +0 -0
  162. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/motor.db +0 -0
  163. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/point_detector.db +0 -0
  164. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/demo/point_detector_channel.db +0 -0
  165. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/eiger/__init__.py +0 -0
  166. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/motor.py +0 -0
  167. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/signal.py +0 -0
  168. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/testing/__init__.py +0 -0
  169. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/testing/_example_ioc.py +0 -0
  170. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/testing/_utils.py +0 -0
  171. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/testing/test_records.db +0 -0
  172. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
  173. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/__init__.py +0 -0
  174. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/core.py +0 -0
  175. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/eiger/__init__.py +0 -0
  176. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/eiger/_eiger_controller.py +0 -0
  177. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
  178. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/__init__.py +0 -0
  179. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_block.py +0 -0
  180. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_control.py +0 -0
  181. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_hdf_panda.py +0 -0
  182. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_table.py +0 -0
  183. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_trigger.py +0 -0
  184. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
  185. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/__init__.py +0 -0
  186. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -0
  187. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_fly.py +0 -0
  188. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_nd_attributes.py +0 -0
  189. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_panda.py +0 -0
  190. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_settings.py +0 -0
  191. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_utils.py +0 -0
  192. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +0 -0
  193. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/py.typed +0 -0
  194. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/__init__.py +0 -0
  195. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/__main__.py +0 -0
  196. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_blob_detector.py +0 -0
  197. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_blob_detector_controller.py +0 -0
  198. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_blob_detector_writer.py +0 -0
  199. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_mirror_horizontal.py +0 -0
  200. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_mirror_vertical.py +0 -0
  201. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_motor.py +0 -0
  202. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_pattern_generator.py +0 -0
  203. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_point_detector.py +0 -0
  204. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/sim/_stage.py +0 -0
  205. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/__init__.py +0 -0
  206. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/__init__.py +0 -0
  207. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_base_device.py +0 -0
  208. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_converters.py +0 -0
  209. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_signal.py +0 -0
  210. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_tango_readable.py +0 -0
  211. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_tango_transport.py +0 -0
  212. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/core/_utils.py +0 -0
  213. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/__init__.py +0 -0
  214. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/_counter.py +0 -0
  215. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/_detector.py +0 -0
  216. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/_mover.py +0 -0
  217. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
  218. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -0
  219. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/testing/__init__.py +0 -0
  220. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/tango/testing/_one_of_everything.py +0 -0
  221. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/__init__.py +0 -0
  222. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/__pytest_assert_rewrite.py +0 -0
  223. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_assert.py +0 -0
  224. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_mock_signal_utils.py +0 -0
  225. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_one_of_everything.py +0 -0
  226. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_single_derived.py +0 -0
  227. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_utils.py +0 -0
  228. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async/testing/_wait_for_pending.py +0 -0
  229. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async.egg-info/SOURCES.txt +0 -0
  230. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
  231. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/src/ophyd_async.egg-info/top_level.txt +0 -0
  232. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/system_tests/epics/eiger/README.md +0 -0
  233. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
  234. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/system_tests/epics/eiger/test_eiger_system.py +0 -0
  235. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/conftest.py +0 -0
  236. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_auto_init_devices.py +0 -0
  237. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_detector.py +0 -0
  238. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_device.py +0 -0
  239. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_flyer.py +0 -0
  240. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_log.py +0 -0
  241. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_mock_signal_backend.py +0 -0
  242. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_multi_derived_signal.py +0 -0
  243. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_observe.py +0 -0
  244. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_protocol.py +0 -0
  245. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_providers.py +0 -0
  246. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_readable.py +0 -0
  247. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_signal.py +0 -0
  248. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_single_derived_signal.py +0 -0
  249. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_soft_signal_backend.py +0 -0
  250. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_status.py +0 -0
  251. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_subset_enum.py +0 -0
  252. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_table.py +0 -0
  253. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_utils.py +0 -0
  254. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/core/test_watchable_async_status.py +0 -0
  255. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adandor/test_andor.py +0 -0
  256. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adaravis/test_aravis.py +0 -0
  257. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_cont_acq_detector.py +0 -0
  258. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_detectors.py +0 -0
  259. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_drivers.py +0 -0
  260. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_scans.py +0 -0
  261. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_single_trigger.py +0 -0
  262. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adcore/test_writers.py +0 -0
  263. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adkinetix/test_kinetix.py +0 -0
  264. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adpilatus/test_pilatus.py +0 -0
  265. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/adsimdetector/test_sim.py +0 -0
  266. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/advimba/test_vimba.py +0 -0
  267. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/conftest.py +0 -0
  268. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/demo/test_epics_demo.py +0 -0
  269. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/pvi/test_pvi.py +0 -0
  270. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/signal/test_common.py +0 -0
  271. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/signal/test_signals.py +0 -0
  272. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/signal/test_yaml_save_ca.yaml +0 -0
  273. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/signal/test_yaml_save_pva.yaml +0 -0
  274. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/test_areadetector_subclass_naming.py +0 -0
  275. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/epics/test_motor.py +0 -0
  276. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/eiger/test_eiger_controller.py +0 -0
  277. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/db/panda.db +0 -0
  278. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_hdf_panda.py +0 -0
  279. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_panda_connect.py +0 -0
  280. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_panda_control.py +0 -0
  281. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_panda_utils.py +0 -0
  282. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_seq_table.py +0 -0
  283. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_trigger.py +0 -0
  284. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/fastcs/panda/test_writer.py +0 -0
  285. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/plan_stubs/test_ensure_connected.py +0 -0
  286. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/plan_stubs/test_fly.py +0 -0
  287. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/plan_stubs/test_settings.py +0 -0
  288. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/plan_stubs/test_setup.py +0 -0
  289. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/sim/__init__.py +0 -0
  290. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/sim/test_sim_blob_detector.py +0 -0
  291. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/sim/test_sim_motor.py +0 -0
  292. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/tango/conftest.py +0 -0
  293. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/tango/context_subprocess.py +0 -0
  294. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/tango/test_base_device.py +0 -0
  295. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/tango/test_tango_signals.py +0 -0
  296. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/tango/test_tango_transport.py +0 -0
  297. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/test_cli.py +0 -0
  298. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/test_data/test_yaml_config_save.yaml +0 -0
  299. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/test_data/test_yaml_save.yaml +0 -0
  300. {ophyd_async-0.12.1 → ophyd_async-0.12.3}/tests/test_tutorials.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ophyd-async
3
- Version: 0.12.1
3
+ Version: 0.12.3
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
@@ -52,7 +52,7 @@ Requires-Dist: stamina>=23.1.0
52
52
  Provides-Extra: sim
53
53
  Requires-Dist: h5py; extra == "sim"
54
54
  Provides-Extra: ca
55
- Requires-Dist: aioca>=1.6; extra == "ca"
55
+ Requires-Dist: aioca>=2.0a4; extra == "ca"
56
56
  Provides-Extra: pva
57
57
  Requires-Dist: p4p>=4.2.0; extra == "pva"
58
58
  Provides-Extra: tango
@@ -29,7 +29,7 @@ requires-python = ">=3.10"
29
29
 
30
30
  [project.optional-dependencies]
31
31
  sim = ["h5py"]
32
- ca = ["aioca>=1.6"]
32
+ ca = ["aioca>=2.0a4"]
33
33
  pva = ["p4p>=4.2.0"]
34
34
  tango = ["pytango==10.0.0"]
35
35
  demo = ["ipython", "matplotlib", "pyqt6"]
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.12.1'
21
- __version_tuple__ = version_tuple = (0, 12, 1)
20
+ __version__ = version = '0.12.3'
21
+ __version_tuple__ = version_tuple = (0, 12, 3)
@@ -33,7 +33,6 @@ from ._utils import (
33
33
  NDAttributeParam,
34
34
  NDAttributePv,
35
35
  NDAttributePvDbrType,
36
- stop_busy_record,
37
36
  )
38
37
 
39
38
  __all__ = [
@@ -64,7 +63,6 @@ __all__ = [
64
63
  "NDAttributePv",
65
64
  "NDAttributeParam",
66
65
  "NDAttributeDataType",
67
- "stop_busy_record",
68
66
  "NDAttributePvDbrType",
69
67
  "NDCBFlushOnSoftTrgMode",
70
68
  "NDPluginCBIO",
@@ -10,6 +10,7 @@ from ophyd_async.core import (
10
10
  observe_value,
11
11
  set_and_wait_for_value,
12
12
  )
13
+ from ophyd_async.epics.core import stop_busy_record
13
14
 
14
15
  from ._core_io import (
15
16
  ADBaseIO,
@@ -18,7 +19,7 @@ from ._core_io import (
18
19
  NDCBFlushOnSoftTrgMode,
19
20
  NDPluginCBIO,
20
21
  )
21
- from ._utils import ADImageMode, stop_busy_record
22
+ from ._utils import ADImageMode
22
23
 
23
24
  # Default set of states that we should consider "good" i.e. the acquisition
24
25
  # is complete and went well
@@ -65,7 +66,7 @@ class ADBaseController(DetectorController, Generic[ADBaseIOT]):
65
66
  async def disarm(self):
66
67
  # We can't use caput callback as we already used it in arm() and we can't have
67
68
  # 2 or they will deadlock
68
- await stop_busy_record(self.driver.acquire, False, timeout=1)
69
+ await stop_busy_record(self.driver.acquire, False)
69
70
 
70
71
  async def set_exposure_time_and_acquire_period_if_supplied(
71
72
  self,
@@ -218,7 +219,7 @@ class ADBaseContAcqController(ADBaseController[ADBaseIO]):
218
219
  await self.cb_plugin.trigger.set(True, wait=False)
219
220
 
220
221
  async def disarm(self) -> None:
221
- await stop_busy_record(self.cb_plugin.capture, False, timeout=1)
222
+ await stop_busy_record(self.cb_plugin.capture, False)
222
223
  if self._arm_status and not self._arm_status.done:
223
224
  await self._arm_status
224
225
  self._arm_status = None
@@ -16,10 +16,10 @@ from ophyd_async.core._providers import DatasetDescriber, PathInfo, PathProvider
16
16
  from ophyd_async.core._signal import (
17
17
  observe_value,
18
18
  set_and_wait_for_value,
19
- wait_for_value,
20
19
  )
21
20
  from ophyd_async.core._status import AsyncStatus
22
21
  from ophyd_async.core._utils import DEFAULT_TIMEOUT, error_if_none
22
+ from ophyd_async.epics.core import stop_busy_record
23
23
 
24
24
  # from ophyd_async.epics.adcore._core_logic import ADBaseDatasetDescriber
25
25
  from ._core_io import (
@@ -213,8 +213,7 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
213
213
 
214
214
  async def close(self):
215
215
  # Already done a caput callback in _capture_status, so can't do one here
216
- await self.fileio.capture.set(False, wait=False)
217
- await wait_for_value(self.fileio.capture, False, DEFAULT_TIMEOUT)
216
+ await stop_busy_record(self.fileio.capture, False, timeout=DEFAULT_TIMEOUT)
218
217
  if self._capture_status and not self._capture_status.done:
219
218
  # We kicked off an open, so wait for it to return
220
219
  await self._capture_status
@@ -1,14 +1,10 @@
1
1
  from dataclasses import dataclass
2
2
 
3
3
  from ophyd_async.core import (
4
- DEFAULT_TIMEOUT,
5
- SignalDatatypeT,
6
4
  SignalR,
7
- SignalRW,
8
5
  StrictEnum,
9
6
  SubsetEnum,
10
7
  SupersetEnum,
11
- wait_for_value,
12
8
  )
13
9
 
14
10
 
@@ -134,13 +130,3 @@ class NDAttributeParam:
134
130
  datatype: NDAttributeDataType # The datatype of the parameter
135
131
  addr: int = 0 # The address as seen in the INP link of the record
136
132
  description: str = "" # A description that appears in the HDF file as an attribute
137
-
138
-
139
- async def stop_busy_record(
140
- signal: SignalRW[SignalDatatypeT],
141
- value: SignalDatatypeT,
142
- timeout: float = DEFAULT_TIMEOUT,
143
- status_timeout: float | None = None,
144
- ) -> None:
145
- await signal.set(value, wait=False, timeout=status_timeout)
146
- await wait_for_value(signal, value, timeout=timeout)
@@ -10,6 +10,7 @@ from ._signal import (
10
10
  epics_signal_w,
11
11
  epics_signal_x,
12
12
  )
13
+ from ._util import stop_busy_record
13
14
 
14
15
  __all__ = [
15
16
  "PviDeviceConnector",
@@ -23,4 +24,5 @@ __all__ = [
23
24
  "epics_signal_rw_rbv",
24
25
  "epics_signal_w",
25
26
  "epics_signal_x",
27
+ "stop_busy_record",
26
28
  ]
@@ -4,13 +4,16 @@ from typing import Any, TypeVar, get_args, get_origin
4
4
  import numpy as np
5
5
 
6
6
  from ophyd_async.core import (
7
+ DEFAULT_TIMEOUT,
7
8
  SignalBackend,
8
9
  SignalDatatypeT,
10
+ SignalRW,
9
11
  StrictEnum,
10
12
  SubsetEnum,
11
13
  SupersetEnum,
12
14
  get_dtype,
13
15
  get_enum_cls,
16
+ wait_for_value,
14
17
  )
15
18
 
16
19
  T = TypeVar("T")
@@ -76,3 +79,12 @@ class EpicsSignalBackend(SignalBackend[SignalDatatypeT]):
76
79
  self.read_pv = read_pv
77
80
  self.write_pv = write_pv
78
81
  super().__init__(datatype)
82
+
83
+
84
+ async def stop_busy_record(
85
+ signal: SignalRW[SignalDatatypeT],
86
+ value: SignalDatatypeT,
87
+ timeout: float = DEFAULT_TIMEOUT,
88
+ ) -> None:
89
+ await signal.set(value, wait=False)
90
+ await wait_for_value(signal, value, timeout=timeout)
@@ -6,6 +6,7 @@ from event_model import DataKey # type: ignore
6
6
 
7
7
  from ophyd_async.core import (
8
8
  DEFAULT_TIMEOUT,
9
+ AsyncStatus,
9
10
  DetectorWriter,
10
11
  Device,
11
12
  DeviceVector,
@@ -21,6 +22,7 @@ from ophyd_async.epics.core import (
21
22
  epics_signal_r,
22
23
  epics_signal_rw,
23
24
  epics_signal_rw_rbv,
25
+ stop_busy_record,
24
26
  )
25
27
 
26
28
 
@@ -68,10 +70,15 @@ class Odin(Device):
68
70
 
69
71
  self.file_path = epics_signal_rw_rbv(str, f"{prefix}FilePath")
70
72
  self.file_name = epics_signal_rw_rbv(str, f"{prefix}FileName")
73
+ self.id = epics_signal_r(str, f"{prefix}AcquisitionID_RBV")
71
74
 
72
75
  self.num_frames_chunks = epics_signal_rw(int, prefix + "NumFramesChunks")
73
76
  self.meta_active = epics_signal_r(str, prefix + "META:AcquisitionActive_RBV")
74
77
  self.meta_writing = epics_signal_r(str, prefix + "META:Writing_RBV")
78
+ self.meta_file_name = epics_signal_r(str, f"{prefix}META:FileName_RBV")
79
+ self.meta_stop = epics_signal_rw(bool, f"{prefix}META:Stop")
80
+
81
+ self.fan_ready = epics_signal_rw(float, f"{prefix}FAN:StateReady_RBV")
75
82
 
76
83
  self.data_type = epics_signal_rw_rbv(str, f"{prefix}DataType")
77
84
 
@@ -88,6 +95,7 @@ class OdinWriter(DetectorWriter):
88
95
  self._drv = odin_driver
89
96
  self._path_provider = path_provider
90
97
  self._eiger_bit_depth = Reference(eiger_bit_depth)
98
+ self._capture_status: AsyncStatus | None = None
91
99
  super().__init__()
92
100
 
93
101
  async def open(self, name: str, exposures_per_event: int = 1) -> dict[str, DataKey]:
@@ -95,17 +103,23 @@ class OdinWriter(DetectorWriter):
95
103
  self._exposures_per_event = exposures_per_event
96
104
 
97
105
  await asyncio.gather(
98
- self._drv.file_path.set(str(info.directory_path)),
99
- self._drv.file_name.set(info.filename),
100
106
  self._drv.data_type.set(f"UInt{await self._eiger_bit_depth().get_value()}"),
101
107
  self._drv.num_to_capture.set(0),
108
+ self._drv.file_path.set(str(info.directory_path)),
109
+ self._drv.file_name.set(info.filename),
102
110
  )
103
111
 
104
- await wait_for_value(self._drv.meta_active, "Active", timeout=DEFAULT_TIMEOUT)
112
+ await asyncio.gather(
113
+ wait_for_value(
114
+ self._drv.meta_file_name, info.filename, timeout=DEFAULT_TIMEOUT
115
+ ),
116
+ wait_for_value(self._drv.id, info.filename, timeout=DEFAULT_TIMEOUT),
117
+ wait_for_value(self._drv.meta_active, "Active", timeout=DEFAULT_TIMEOUT),
118
+ )
105
119
 
106
- await self._drv.capture.set(
107
- Writing.CAPTURE, wait=False
108
- ) # TODO: Investigate why we do not get a put callback when setting capture pv https://github.com/bluesky/ophyd-async/issues/866
120
+ self._capture_status = await set_and_wait_for_value(
121
+ self._drv.capture, Writing.CAPTURE, wait_for_set_completion=False
122
+ )
109
123
 
110
124
  await asyncio.gather(
111
125
  wait_for_value(self._drv.capture_rbv, "Capturing", timeout=DEFAULT_TIMEOUT),
@@ -146,4 +160,8 @@ class OdinWriter(DetectorWriter):
146
160
  raise NotImplementedError()
147
161
 
148
162
  async def close(self) -> None:
149
- await set_and_wait_for_value(self._drv.capture, Writing.DONE)
163
+ await stop_busy_record(self._drv.capture, Writing.DONE, timeout=DEFAULT_TIMEOUT)
164
+ await self._drv.meta_stop.set(True, wait=True)
165
+ if self._capture_status and not self._capture_status.done:
166
+ await self._capture_status
167
+ self._capture_status = None
@@ -0,0 +1,3 @@
1
+ from ._pmac_io import PmacAxisAssignmentIO, PmacCoordIO, PmacIO, PmacTrajectoryIO
2
+
3
+ __all__ = ["PmacAxisAssignmentIO", "PmacCoordIO", "PmacIO", "PmacTrajectoryIO"]
@@ -3,6 +3,7 @@ from collections.abc import Sequence
3
3
  import numpy as np
4
4
 
5
5
  from ophyd_async.core import Array1D, Device, DeviceVector, StandardReadable
6
+ from ophyd_async.epics import motor
6
7
  from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
7
8
 
8
9
  CS_LETTERS = "ABCUVWXYZ"
@@ -13,52 +14,53 @@ class PmacTrajectoryIO(StandardReadable):
13
14
 
14
15
  def __init__(self, prefix: str, name: str = "") -> None:
15
16
  self.time_array = epics_signal_rw(
16
- Array1D[np.float64], prefix + ":ProfileTimeArray"
17
+ Array1D[np.float64], prefix + "ProfileTimeArray"
17
18
  )
18
- self.user_array = epics_signal_rw(Array1D[np.int32], prefix + ":UserArray")
19
+ self.user_array = epics_signal_rw(Array1D[np.int32], prefix + "UserArray")
19
20
  # 1 indexed CS axes so we can index into them from the compound motor input link
20
21
  self.positions = DeviceVector(
21
22
  {
22
23
  i + 1: epics_signal_rw(
23
- Array1D[np.float64], f"{prefix}:{letter}:Positions"
24
+ Array1D[np.float64], f"{prefix}{letter}:Positions"
24
25
  )
25
26
  for i, letter in enumerate(CS_LETTERS)
26
27
  }
27
28
  )
28
29
  self.use_axis = DeviceVector(
29
30
  {
30
- i + 1: epics_signal_rw(bool, f"{prefix}:{letter}:UseAxis")
31
+ i + 1: epics_signal_rw(bool, f"{prefix}{letter}:UseAxis")
31
32
  for i, letter in enumerate(CS_LETTERS)
32
33
  }
33
34
  )
34
35
  self.velocities = DeviceVector(
35
36
  {
36
37
  i + 1: epics_signal_rw(
37
- Array1D[np.float64], f"{prefix}:{letter}:Velocities"
38
+ Array1D[np.float64], f"{prefix}{letter}:Velocities"
38
39
  )
39
40
  for i, letter in enumerate(CS_LETTERS)
40
41
  }
41
42
  )
42
- self.points_to_build = epics_signal_rw(int, prefix + ":ProfilePointsToBuild")
43
- self.build_profile = epics_signal_rw(bool, prefix + ":ProfileBuild")
44
- self.execute_profile = epics_signal_rw(bool, prefix + ":ProfileExecute")
45
- self.scan_percent = epics_signal_r(float, prefix + ":TscanPercent_RBV")
46
- self.abort_profile = epics_signal_rw(bool, prefix + ":ProfileAbort")
47
- self.profile_cs_name = epics_signal_rw(str, prefix + ":ProfileCsName")
48
- self.calculate_velocities = epics_signal_rw(bool, prefix + ":ProfileCalcVel")
43
+ self.points_to_build = epics_signal_rw(int, prefix + "ProfilePointsToBuild")
44
+ self.build_profile = epics_signal_rw(bool, prefix + "ProfileBuild")
45
+ self.execute_profile = epics_signal_rw(bool, prefix + "ProfileExecute")
46
+ self.scan_percent = epics_signal_r(float, prefix + "TscanPercent_RBV")
47
+ self.abort_profile = epics_signal_rw(bool, prefix + "ProfileAbort")
48
+ self.profile_cs_name = epics_signal_rw(str, prefix + "ProfileCsName")
49
+ self.calculate_velocities = epics_signal_rw(bool, prefix + "ProfileCalcVel")
49
50
 
50
51
  super().__init__(name=name)
51
52
 
52
53
 
53
- class PmacAxisIO(Device):
54
+ class PmacAxisAssignmentIO(Device):
54
55
  """A Device that (direct) moves a PMAC Coordinate System Motor.
55
56
 
56
57
  Note that this does not go through a motor record.
57
58
  """
58
59
 
59
60
  def __init__(self, prefix: str, name: str = "") -> None:
60
- self.cs_axis_letter = epics_signal_r(str, f"{prefix}:CsAxis_RBV")
61
- self.cs_port = epics_signal_r(str, f"{prefix}:CsPort_RBV")
61
+ self.cs_axis_letter = epics_signal_r(str, f"{prefix}CsAxis_RBV")
62
+ self.cs_port = epics_signal_r(str, f"{prefix}CsPort_RBV")
63
+ self.cs_number = epics_signal_r(int, f"{prefix}CsRaw_RBV")
62
64
  super().__init__(name=name)
63
65
 
64
66
 
@@ -66,12 +68,10 @@ class PmacCoordIO(Device):
66
68
  """A Device that represents a Pmac Coordinate System."""
67
69
 
68
70
  def __init__(self, prefix: str, name: str = "") -> None:
69
- self.defer_moves = epics_signal_r(bool, f"{prefix}:DeferMoves")
71
+ self.defer_moves = epics_signal_rw(bool, f"{prefix}DeferMoves")
70
72
  self.cs_axis_setpoint = DeviceVector(
71
73
  {
72
- i + 1: epics_signal_rw(
73
- Array1D[np.float64], f"{prefix}:M{i + 1}:DirectDemand"
74
- )
74
+ i + 1: epics_signal_rw(np.float64, f"{prefix}M{i + 1}:DirectDemand")
75
75
  for i in range(len(CS_LETTERS))
76
76
  }
77
77
  )
@@ -84,15 +84,25 @@ class PmacIO(Device):
84
84
  def __init__(
85
85
  self,
86
86
  prefix: str,
87
- axis_nums: Sequence[int],
87
+ raw_motors: Sequence[motor.Motor],
88
88
  coord_nums: Sequence[int],
89
89
  name: str = "",
90
90
  ) -> None:
91
- self.axis = DeviceVector(
92
- {axis: PmacAxisIO(f"{prefix}:M{axis}") for axis in axis_nums}
91
+ motor_prefixes = [motor.motor_egu.source.split(".")[0] for motor in raw_motors]
92
+
93
+ self.assignment = DeviceVector(
94
+ {
95
+ i: PmacAxisAssignmentIO(motor_prefix)
96
+ for i, motor_prefix in enumerate(motor_prefixes)
97
+ }
93
98
  )
99
+
100
+ # Public Look up for motor to axis assignment DeviceVector index
101
+
102
+ self.motor_assignment_index = {motor: i for i, motor in enumerate(raw_motors)}
103
+
94
104
  self.coord = DeviceVector(
95
- {coord: PmacCoordIO(f"{prefix}:CS{coord}") for coord in coord_nums}
105
+ {coord: PmacCoordIO(prefix=f"{prefix}CS{coord}:") for coord in coord_nums}
96
106
  )
97
107
  # Trajectory PVs have the same prefix as the pmac device
98
108
  self.trajectory = PmacTrajectoryIO(prefix)
@@ -33,7 +33,7 @@ class EigerDetector(StandardDetector):
33
33
  OdinWriter(
34
34
  path_provider,
35
35
  self.odin,
36
- self.drv.detector.bit_depth_readout,
36
+ self.drv.detector.bit_depth_image,
37
37
  ),
38
38
  name=name,
39
39
  )
@@ -23,11 +23,12 @@ class EigerStreamIO(Device):
23
23
 
24
24
 
25
25
  class EigerDetectorIO(Device):
26
- bit_depth_readout: SignalR[int]
26
+ bit_depth_image: SignalR[int]
27
27
  state: SignalR[str]
28
28
  count_time: SignalRW[float]
29
29
  frame_time: SignalRW[float]
30
30
  nimages: SignalRW[int]
31
+ ntrigger: SignalRW[int]
31
32
  nexpi: SignalRW[int]
32
33
  trigger_mode: SignalRW[str]
33
34
  roi_mode: SignalRW[str]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ophyd-async
3
- Version: 0.12.1
3
+ Version: 0.12.3
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
@@ -52,7 +52,7 @@ Requires-Dist: stamina>=23.1.0
52
52
  Provides-Extra: sim
53
53
  Requires-Dist: h5py; extra == "sim"
54
54
  Provides-Extra: ca
55
- Requires-Dist: aioca>=1.6; extra == "ca"
55
+ Requires-Dist: aioca>=2.0a4; extra == "ca"
56
56
  Provides-Extra: pva
57
57
  Requires-Dist: p4p>=4.2.0; extra == "pva"
58
58
  Provides-Extra: tango
@@ -8,7 +8,7 @@ pydantic-numpy
8
8
  stamina>=23.1.0
9
9
 
10
10
  [ca]
11
- aioca>=1.6
11
+ aioca>=2.0a4
12
12
 
13
13
  [demo]
14
14
  ipython
@@ -1,11 +1,17 @@
1
+ import asyncio
2
+ from asyncio import Event
1
3
  from pathlib import Path
2
- from unittest.mock import ANY, AsyncMock, MagicMock, call, patch
4
+ from unittest.mock import ANY, AsyncMock, MagicMock
3
5
 
4
6
  import pytest
5
7
 
6
- from ophyd_async.core import DEFAULT_TIMEOUT, init_devices
8
+ from ophyd_async.core import init_devices
7
9
  from ophyd_async.epics.eiger import Odin, OdinWriter, Writing
8
- from ophyd_async.testing import get_mock_put, set_mock_value
10
+ from ophyd_async.testing import (
11
+ callback_on_mock_put,
12
+ get_mock_put,
13
+ set_mock_value,
14
+ )
9
15
 
10
16
  ODIN_DETECTOR_NAME = "odin_detector"
11
17
  EIGER_BIT_DEPTH = 16
@@ -19,22 +25,26 @@ def odin_driver_and_writer(RE) -> OdinDriverAndWriter:
19
25
  with init_devices(mock=True):
20
26
  driver = Odin("")
21
27
  writer = OdinWriter(MagicMock(), driver, eiger_bit_depth)
28
+ writer._path_provider.return_value.filename = "filename.h5" # type: ignore
29
+ return driver, writer
30
+
22
31
 
23
- # Set meta and capturing pvs high
32
+ def initialise_signals_to_armed(driver):
24
33
  set_mock_value(driver.meta_active, "Active")
25
34
  set_mock_value(driver.capture_rbv, "Capturing")
26
35
  set_mock_value(driver.meta_writing, "Writing")
27
- return driver, writer
36
+ set_mock_value(driver.meta_file_name, "filename.h5")
37
+ set_mock_value(driver.id, "filename.h5")
28
38
 
29
39
 
30
40
  async def test_when_open_called_then_file_correctly_set(
31
41
  odin_driver_and_writer: OdinDriverAndWriter, tmp_path: Path
32
42
  ):
33
43
  driver, writer = odin_driver_and_writer
44
+ initialise_signals_to_armed(driver)
34
45
  path_info = writer._path_provider.return_value # type: ignore
35
- expected_filename = "filename.h5"
36
46
  path_info.directory_path = tmp_path
37
- path_info.filename = expected_filename
47
+ expected_filename = "filename.h5"
38
48
 
39
49
  await writer.open(ODIN_DETECTOR_NAME)
40
50
 
@@ -46,6 +56,7 @@ async def test_when_open_called_then_all_expected_signals_set(
46
56
  odin_driver_and_writer: OdinDriverAndWriter,
47
57
  ):
48
58
  driver, writer = odin_driver_and_writer
59
+ initialise_signals_to_armed(driver)
49
60
 
50
61
  await writer.open(ODIN_DETECTOR_NAME)
51
62
 
@@ -59,6 +70,7 @@ async def test_bit_depth_is_passed_before_open_and_set_to_data_type_after_open(
59
70
  odin_driver_and_writer: OdinDriverAndWriter,
60
71
  ):
61
72
  driver, writer = odin_driver_and_writer
73
+ initialise_signals_to_armed(driver)
62
74
 
63
75
  assert await writer._eiger_bit_depth().get_value() == EIGER_BIT_DEPTH
64
76
  assert await driver.data_type.get_value() == ""
@@ -72,6 +84,8 @@ async def test_given_data_shape_set_when_open_called_then_describe_has_correct_s
72
84
  odin_driver_and_writer: OdinDriverAndWriter,
73
85
  ):
74
86
  driver, writer = odin_driver_and_writer
87
+ initialise_signals_to_armed(driver)
88
+
75
89
  set_mock_value(driver.image_width, 1024)
76
90
  set_mock_value(driver.image_height, 768)
77
91
  description = await writer.open(ODIN_DETECTOR_NAME)
@@ -87,29 +101,39 @@ async def test_when_closed_then_data_capture_turned_off(
87
101
 
88
102
 
89
103
  @pytest.mark.asyncio
90
- @patch("ophyd_async.epics.eiger._odin_io.wait_for_value")
91
- async def test_wait_for_active_before_capture_then_wait_for_writing(
92
- mock_wait_for_value,
104
+ async def test_wait_for_active_and_file_names_before_capture_then_wait_for_writing(
93
105
  odin_driver_and_writer,
94
106
  ):
95
107
  driver, writer = odin_driver_and_writer
96
- writer._drv.capture.set = AsyncMock()
97
-
98
- mock_manager = AsyncMock()
99
- mock_manager.attach_mock(mock_wait_for_value, "mock_wait_for_value")
100
- mock_manager.attach_mock(writer._drv.capture.set, "mock_capture_set")
101
108
 
102
- await writer.open(ODIN_DETECTOR_NAME)
103
-
104
- expected_calls = [
105
- call.mock_wait_for_value(driver.meta_active, "Active", timeout=DEFAULT_TIMEOUT),
106
- call.mock_capture_set(Writing.CAPTURE, wait=False),
107
- call.mock_wait_for_value(
108
- driver.capture_rbv, "Capturing", timeout=DEFAULT_TIMEOUT
109
- ),
110
- call.mock_wait_for_value(
111
- driver.meta_writing, "Writing", timeout=DEFAULT_TIMEOUT
112
- ),
113
- ]
114
-
115
- assert mock_manager.mock_calls == expected_calls
109
+ file_name_is_set = Event()
110
+ capture_is_set = Event()
111
+ callback_on_mock_put(
112
+ driver.file_name, lambda *args, **kwargs: file_name_is_set.set()
113
+ )
114
+ callback_on_mock_put(driver.capture, lambda *args, **kwargs: capture_is_set.set())
115
+
116
+ async def set_waited_signals():
117
+ set_mock_value(driver.meta_active, "Active")
118
+ set_mock_value(driver.id, "filename.h5")
119
+ set_mock_value(driver.meta_file_name, "filename.h5")
120
+
121
+ async def set_ready_signals():
122
+ set_mock_value(driver.meta_writing, "Writing")
123
+ set_mock_value(driver.capture_rbv, "Capturing")
124
+
125
+ async def wait_and_set_signals():
126
+ # Block until filename is set
127
+ await file_name_is_set.wait()
128
+ # Allow writer.open to proceed to wait_for_value.
129
+ await asyncio.sleep(0.1)
130
+ # writer.open now waits on signals; set these, and unset event
131
+ await set_waited_signals()
132
+ # Block until capture sets event
133
+ await capture_is_set.wait()
134
+ # Allow writer.open to proceed to wait_for_value.
135
+ await asyncio.sleep(0.1)
136
+ # writer.open now waits on signals; set these
137
+ await set_ready_signals()
138
+
139
+ await asyncio.gather(writer.open(ODIN_DETECTOR_NAME), wait_and_set_signals())
@@ -1,5 +1,6 @@
1
+ from ophyd_async.epics.motor import Motor
1
2
  from ophyd_async.epics.pmac import (
2
- PmacAxisIO,
3
+ PmacAxisAssignmentIO,
3
4
  PmacCoordIO,
4
5
  PmacIO,
5
6
  PmacTrajectoryIO, # type: ignore
@@ -8,16 +9,29 @@ from ophyd_async.epics.pmac import (
8
9
 
9
10
  def test_pmac_io():
10
11
  """Instantiate a PmacIO object that looks like the P47 training beamline"""
12
+ raw_motors = [
13
+ Motor("BL47P-MO-MAP-01:STAGE:X:"),
14
+ Motor("BL47P-MO-MAP-01:STAGE:A:"),
15
+ ]
11
16
 
12
17
  pmac = PmacIO(
13
- axis_nums=[1, 2],
18
+ prefix="BL47P-MO-BRICK-01:",
19
+ raw_motors=raw_motors,
14
20
  coord_nums=[1, 9],
15
- prefix="BL47P-MO-BRICK-01",
16
21
  name="p47-brick-01",
17
22
  )
18
23
 
19
24
  assert pmac.name == "p47-brick-01"
20
25
 
26
+ # check assignments
27
+ assert len(pmac.assignment) == 2
28
+ assert isinstance(pmac.assignment[0], PmacAxisAssignmentIO)
29
+ assert isinstance(pmac.assignment[1], PmacAxisAssignmentIO)
30
+
31
+ # check_look_up
32
+ assert pmac.motor_assignment_index[raw_motors[0]] == 0
33
+ assert pmac.motor_assignment_index[raw_motors[1]] == 1
34
+
21
35
  # check coords PVs
22
36
  assert pmac.coord[1].defer_moves.source == "ca://BL47P-MO-BRICK-01:CS1:DeferMoves"
23
37
  assert (
@@ -34,8 +48,13 @@ def test_pmac_io():
34
48
  )
35
49
 
36
50
  # check axes PVs
37
- assert pmac.axis[1].cs_axis_letter.source == "ca://BL47P-MO-BRICK-01:M1:CsAxis_RBV"
38
- assert pmac.axis[1].cs_port.source == "ca://BL47P-MO-BRICK-01:M1:CsPort_RBV"
51
+ assert (
52
+ pmac.assignment[1].cs_axis_letter.source
53
+ == "ca://BL47P-MO-MAP-01:STAGE:A:CsAxis_RBV"
54
+ )
55
+ assert (
56
+ pmac.assignment[1].cs_port.source == "ca://BL47P-MO-MAP-01:STAGE:A:CsPort_RBV"
57
+ )
39
58
 
40
59
  # check trajectory scan PVs
41
60
  assert (
@@ -53,7 +72,7 @@ def test_pmac_trajectory_io():
53
72
  """Instantiate a PmacTrajectoryIO object with a specific prefix."""
54
73
 
55
74
  pmac_trajectory = PmacTrajectoryIO(
56
- prefix="BL47P-MO-BRICK-01", name="p47-brick-01-trajectory"
75
+ prefix="BL47P-MO-BRICK-01:", name="p47-brick-01-trajectory"
57
76
  )
58
77
 
59
78
  assert pmac_trajectory.name == "p47-brick-01-trajectory"
@@ -69,9 +88,11 @@ def test_pmac_trajectory_io():
69
88
 
70
89
 
71
90
  def test_pmac_axis_io():
72
- """Instantiate a PmacAxisIO object with a specific prefix."""
91
+ """Instantiate a PmacAxisAssignmentIO object with a specific prefix."""
73
92
 
74
- pmac_axis = PmacAxisIO(prefix="BL47P-MO-BRICK-01:M1", name="p47-brick-01-axis")
93
+ pmac_axis = PmacAxisAssignmentIO(
94
+ prefix="BL47P-MO-BRICK-01:M1:", name="p47-brick-01-axis"
95
+ )
75
96
 
76
97
  assert pmac_axis.name == "p47-brick-01-axis"
77
98
  assert pmac_axis.cs_axis_letter.source == "ca://BL47P-MO-BRICK-01:M1:CsAxis_RBV"
@@ -81,7 +102,7 @@ def test_pmac_axis_io():
81
102
  def test_pmac_coord_io():
82
103
  """Instantiate a PmacCoordIO object with a specific prefix."""
83
104
 
84
- pmac_coord = PmacCoordIO(prefix="BL47P-MO-BRICK-01:CS1", name="p47-brick-01-coord")
105
+ pmac_coord = PmacCoordIO(prefix="BL47P-MO-BRICK-01:CS1:", name="p47-brick-01-coord")
85
106
 
86
107
  assert pmac_coord.name == "p47-brick-01-coord"
87
108
  assert pmac_coord.defer_moves.source == "ca://BL47P-MO-BRICK-01:CS1:DeferMoves"