dls-dodal 1.31.0__tar.gz → 1.32.0__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 (334) hide show
  1. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/PKG-INFO +3 -2
  2. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/pyproject.toml +2 -1
  3. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/PKG-INFO +3 -2
  4. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/SOURCES.txt +2 -0
  5. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/requires.txt +2 -1
  6. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/_version.py +2 -2
  7. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i04.py +1 -0
  8. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i22.py +1 -0
  9. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/aperturescatterguard.py +10 -10
  10. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/areadetector/plugins/MJPG.py +32 -8
  11. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/detector.py +1 -1
  12. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/fast_grid_scan.py +2 -1
  13. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/focusing_mirror.py +4 -5
  14. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/pmac.py +77 -15
  15. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/robot.py +18 -6
  16. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/tetramm.py +11 -16
  17. dls_dodal-1.32.0/src/dodal/devices/undulator.py +154 -0
  18. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/undulator_dcm.py +3 -57
  19. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/lookup_tables.py +1 -1
  20. dls_dodal-1.32.0/src/dodal/devices/webcam.py +62 -0
  21. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/zocalo/zocalo_interaction.py +6 -1
  22. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/zocalo/zocalo_results.py +114 -10
  23. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/utils.py +4 -3
  24. dls_dodal-1.32.0/tests/devices/system_tests/test_undulator_system.py +19 -0
  25. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/areadetector/plugins/test_MJPG.py +12 -0
  26. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/detector/test_detector.py +2 -2
  27. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/i24/test_pmac.py +41 -8
  28. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_aperture_scatterguard.py +27 -3
  29. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_bart_robot.py +10 -1
  30. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_focusing_mirror.py +8 -10
  31. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_gridscan.py +1 -1
  32. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_tetramm.py +70 -26
  33. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_undulator.py +33 -1
  34. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_undulator_dcm.py +15 -29
  35. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_webcam.py +36 -16
  36. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_xspress3.py +2 -2
  37. dls_dodal-1.32.0/tests/devices/unit_tests/test_zocalo_results.py +500 -0
  38. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_zocalo/__main__.py +1 -1
  39. dls_dodal-1.32.0/tests/test_data/test_images/oav_snapshot_expected.png +0 -0
  40. dls_dodal-1.32.0/tests/test_data/test_images/oav_snapshot_test.png +0 -0
  41. dls_dodal-1.31.0/src/dodal/devices/undulator.py +0 -65
  42. dls_dodal-1.31.0/src/dodal/devices/webcam.py +0 -36
  43. dls_dodal-1.31.0/tests/devices/system_tests/test_undulator_system.py +0 -12
  44. dls_dodal-1.31.0/tests/devices/unit_tests/test_zocalo_results.py +0 -252
  45. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.copier-answers.yml +0 -0
  46. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.devcontainer/devcontainer.json +0 -0
  47. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/CONTRIBUTING.md +0 -0
  48. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/ISSUE_TEMPLATE/issue_template.md +0 -0
  49. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/actions/install_requirements/action.yml +0 -0
  50. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/dependabot.yml +0 -0
  51. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/pages/index.html +0 -0
  52. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/pages/make_switcher.py +0 -0
  53. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_check.yml +0 -0
  54. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_dist.yml +0 -0
  55. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_docs.yml +0 -0
  56. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_pypi.yml +0 -0
  57. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_release.yml +0 -0
  58. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_test.yml +0 -0
  59. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/_tox.yml +0 -0
  60. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/ci.yml +0 -0
  61. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.github/workflows/periodic.yml +0 -0
  62. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.gitignore +0 -0
  63. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.pre-commit-config.yaml +0 -0
  64. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.vscode/extensions.json +0 -0
  65. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.vscode/launch.json +0 -0
  66. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.vscode/settings.json +0 -0
  67. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/.vscode/tasks.json +0 -0
  68. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/Dockerfile +0 -0
  69. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/LICENSE +0 -0
  70. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/README.md +0 -0
  71. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/catalog-info.yaml +0 -0
  72. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/_templates/autosummary/class.rst +0 -0
  73. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/_templates/autosummary/module.rst +0 -0
  74. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/assets/zocalo.png +0 -0
  75. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/conf.py +0 -0
  76. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  77. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  78. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/explanations/decisions/COPYME +0 -0
  79. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/explanations/decisions.md +0 -0
  80. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/explanations.md +0 -0
  81. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/genindex.md +0 -0
  82. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/build-docs.md +0 -0
  83. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/contribute.md +0 -0
  84. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/coverage.md +0 -0
  85. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/create-beamline.rst +0 -0
  86. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/dev-install.md +0 -0
  87. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/excalidraw.md +0 -0
  88. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/lint.md +0 -0
  89. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/lock-requirements.md +0 -0
  90. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/make-new-ophyd-async-device.rst +0 -0
  91. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/make-release.md +0 -0
  92. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/move-code.rst +0 -0
  93. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/pypi.md +0 -0
  94. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/run-tests.md +0 -0
  95. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/static-analysis.md +0 -0
  96. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/update-template.md +0 -0
  97. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to/zocalo.rst +0 -0
  98. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/how-to.md +0 -0
  99. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/images/dls-logo.svg +0 -0
  100. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/images/excalidraw-example.svg +0 -0
  101. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/index.md +0 -0
  102. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/reference/api.md +0 -0
  103. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/reference/device-standards.rst +0 -0
  104. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/reference/standards.rst +0 -0
  105. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/reference.md +0 -0
  106. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/tutorials/get_started.rst +0 -0
  107. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/tutorials/installation.md +0 -0
  108. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/docs/tutorials.md +0 -0
  109. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/pull_request_template.md +0 -0
  110. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/setup.cfg +0 -0
  111. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/__init__.py +0 -0
  112. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/dependency_links.txt +0 -0
  113. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/entry_points.txt +0 -0
  114. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dls_dodal.egg-info/top_level.txt +0 -0
  115. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/__init__.py +0 -0
  116. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/__main__.py +0 -0
  117. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/adsim.py +0 -0
  118. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamline_specific_utils/__init__.py +0 -0
  119. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamline_specific_utils/i03.py +0 -0
  120. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/README.md +0 -0
  121. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/__init__.py +0 -0
  122. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i03.py +1 -1
  123. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i04_1.py +0 -0
  124. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i13_1.py +0 -0
  125. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i20_1.py +0 -0
  126. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i23.py +0 -0
  127. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/i24.py +0 -0
  128. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/p38.py +0 -0
  129. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/p45.py +0 -0
  130. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/p99.py +0 -0
  131. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/beamlines/training_rig.py +0 -0
  132. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/cli.py +0 -0
  133. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/__init__.py +0 -0
  134. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/beamlines/__init__.py +0 -0
  135. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/beamlines/beamline_parameters.py +0 -0
  136. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/beamlines/beamline_utils.py +0 -0
  137. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/beamlines/device_helpers.py +0 -0
  138. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/coordination.py +0 -0
  139. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/maths.py +0 -0
  140. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/types.py +0 -0
  141. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/udc_directory_provider.py +0 -0
  142. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/common/visit.py +0 -0
  143. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/CTAB.py +0 -0
  144. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/__init__.py +0 -0
  145. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/adsim.py +0 -0
  146. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/aperture.py +0 -0
  147. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/areadetector/__init__.py +0 -0
  148. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/areadetector/adaravis.py +0 -0
  149. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/areadetector/adsim.py +0 -0
  150. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/areadetector/adutils.py +0 -0
  151. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/attenuator.py +0 -0
  152. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/backlight.py +0 -0
  153. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/cryostream.py +0 -0
  154. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/dcm.py +0 -0
  155. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/__init__.py +0 -0
  156. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/det_dim_constants.py +0 -0
  157. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/det_dist_to_beam_converter.py +0 -0
  158. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/det_resolution.py +0 -0
  159. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/detector/detector_motion.py +0 -0
  160. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/eiger.py +0 -0
  161. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/eiger_odin.py +0 -0
  162. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/fluorescence_detector_motion.py +0 -0
  163. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/flux.py +0 -0
  164. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/hutch_shutter.py +0 -0
  165. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i03/__init__.py +0 -0
  166. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i04/transfocator.py +0 -0
  167. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i20_1/__init__.py +0 -0
  168. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i22/dcm.py +0 -0
  169. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i22/fswitch.py +0 -0
  170. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i22/nxsas.py +0 -0
  171. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/__init__.py +0 -0
  172. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/aperture.py +0 -0
  173. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/beamstop.py +0 -0
  174. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/dcm.py +0 -0
  175. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/dual_backlight.py +0 -0
  176. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/i24_detector_motion.py +0 -0
  177. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/i24/i24_vgonio.py +0 -0
  178. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/ipin.py +0 -0
  179. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/linkam3.py +0 -0
  180. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/logging_ophyd_device.py +0 -0
  181. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/motors.py +0 -0
  182. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/__init__.py +0 -0
  183. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/grid_overlay.py +0 -0
  184. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/microns_for_zoom_levels.json +0 -0
  185. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/oav_calculations.py +0 -0
  186. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/oav_detector.py +0 -0
  187. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/oav_errors.py +0 -0
  188. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/oav_parameters.py +0 -0
  189. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/oav_to_redis_forwarder.py +0 -0
  190. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/pin_image_recognition/__init__.py +0 -0
  191. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/pin_image_recognition/manual_test.py +0 -0
  192. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/pin_image_recognition/utils.py +0 -0
  193. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/oav/utils.py +0 -0
  194. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/p45.py +0 -0
  195. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/p99/__init__.py +0 -0
  196. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/p99/sample_stage.py +0 -0
  197. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/s4_slit_gaps.py +0 -0
  198. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/scatterguard.py +0 -0
  199. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/scintillator.py +0 -0
  200. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/slits.py +0 -0
  201. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/smargon.py +0 -0
  202. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/status.py +0 -0
  203. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/synchrotron.py +0 -0
  204. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/thawer.py +0 -0
  205. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/training_rig/__init__.py +0 -0
  206. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/training_rig/sample_stage.py +0 -0
  207. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/turbo_slit.py +0 -0
  208. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/__init__.py +0 -0
  209. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/adjuster_plans.py +0 -0
  210. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/epics_util.py +0 -0
  211. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/motor_utils.py +0 -0
  212. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/save_panda.py +0 -0
  213. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/util/test_utils.py +0 -0
  214. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/xbpm_feedback.py +0 -0
  215. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/xspress3/xspress3.py +0 -0
  216. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/xspress3/xspress3_channel.py +0 -0
  217. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/zebra.py +0 -0
  218. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/zebra_controlled_shutter.py +0 -0
  219. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/devices/zocalo/__init__.py +0 -0
  220. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/log.py +0 -0
  221. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/parameters/experiment_parameter_base.py +0 -0
  222. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/plans/check_topup.py +0 -0
  223. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/plans/data_session_metadata.py +0 -0
  224. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/src/dodal/plans/motor_util_plans.py +0 -0
  225. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/__init__.py +0 -0
  226. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/beamlines/__init__.py +0 -0
  227. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/beamlines/unit_tests/__init__.py +0 -0
  228. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/beamlines/unit_tests/test_i03.py +0 -0
  229. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/beamlines/unit_tests/test_i24.py +0 -0
  230. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/beamlines/unit_tests/test_mapping.py +0 -0
  231. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/__init__.py +0 -0
  232. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/beamlines/__init__.py +0 -0
  233. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/beamlines/test_beamline_parameters.py +0 -0
  234. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/beamlines/test_beamline_utils.py +0 -0
  235. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/beamlines/test_device_helpers.py +0 -0
  236. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/beamlines/test_device_instantiation.py +0 -0
  237. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/test_coordination.py +0 -0
  238. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/test_maths.py +0 -0
  239. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/test_udc_directory_provider.py +0 -0
  240. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/common/test_visit.py +0 -0
  241. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/conftest.py +0 -0
  242. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/__init__.py +0 -0
  243. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/i04/__init__.py +0 -0
  244. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/i04/test_transfocator.py +0 -0
  245. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/i22/test_dcm.py +0 -0
  246. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/i22/test_fswitch.py +0 -0
  247. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/i22/test_metadataholder.py +0 -0
  248. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/__init__.py +0 -0
  249. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_aperturescatterguard_system.py +0 -0
  250. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_eiger_system.py +0 -0
  251. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_gridscan_system.py +0 -0
  252. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_oav_system.py +0 -0
  253. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_oav_to_redis_system.py +0 -0
  254. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_slit_gaps_system.py +0 -0
  255. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_smargon_system.py +0 -0
  256. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_synchrotron_system.py +0 -0
  257. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_zebra_system.py +0 -0
  258. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/system_tests/test_zocalo_results.py +0 -0
  259. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/training_rig/test_sample_stage.py +0 -0
  260. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/__init__.py +0 -0
  261. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/conftest.py +0 -0
  262. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/detector/test_det_dim_constants.py +0 -0
  263. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/detector/test_det_resolution.py +0 -0
  264. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/i24/__init__.py +0 -0
  265. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/i24/test_dual_backlight.py +0 -0
  266. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/__init__.py +0 -0
  267. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect.py +0 -0
  268. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect_utils.py +0 -0
  269. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/test_oav.py +0 -0
  270. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/test_oav_parameters.py +0 -0
  271. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/oav/test_oav_to_redis_forwarder.py +0 -0
  272. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/p99/test_p99_stage.py +0 -0
  273. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_OAVCentring.json +0 -0
  274. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_aperture.py +0 -0
  275. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_attenuator.py +0 -0
  276. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_backlight.py +0 -0
  277. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_beam_converter.py +0 -0
  278. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_beamline_undulator_to_gap_lookup_table.txt +0 -0
  279. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_daq_configuration/domain/beamlineParameters +0 -0
  280. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Pitch_converter.txt +0 -0
  281. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Roll_converter.txt +0 -0
  282. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_dcm.py +0 -0
  283. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_display.configuration +0 -0
  284. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_eiger.py +0 -0
  285. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_grid_overlay.py +0 -0
  286. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_hutch_shutter.py +0 -0
  287. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_jCameraManZoomLevels.xml +0 -0
  288. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_linkam3.py +0 -0
  289. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_lookup_table.txt +0 -0
  290. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_lookup_table_2.txt +0 -0
  291. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_oav.py +0 -0
  292. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_odin.py +0 -0
  293. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_shutter.py +0 -0
  294. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_slits.py +0 -0
  295. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_smargon.py +0 -0
  296. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_status.py +0 -0
  297. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_synchrotron.py +0 -0
  298. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_thawer.py +0 -0
  299. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_utils.py +0 -0
  300. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_xbpm_feedback.py +0 -0
  301. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_zebra.py +0 -0
  302. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/test_zocalo_interaction.py +0 -0
  303. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/util/__init__.py +0 -0
  304. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/util/test_adjuster_plans.py +0 -0
  305. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/util/test_beamline_specific_utils.py +0 -0
  306. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/util/test_lookup_tables.py +0 -0
  307. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/devices/unit_tests/util/test_save_panda.py +0 -0
  308. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline.py +0 -0
  309. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_all_devices_raise_exception.py +0 -0
  310. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_broken_dependency.py +0 -0
  311. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_dependencies.py +0 -0
  312. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_disordered_dependencies.py +0 -0
  313. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_misbehaving_builtins.py +0 -0
  314. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_beamline_some_devices_working.py +0 -0
  315. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_zocalo/README.rst +0 -0
  316. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_zocalo/__init__.py +0 -0
  317. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/fake_zocalo/dls_start_fake_zocalo.sh +0 -0
  318. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/plans/test_motor_util_plans.py +0 -0
  319. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/plans/test_topup_plan.py +0 -0
  320. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/preprocessors/test_filesystem_metadata.py +0 -0
  321. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_cli.py +0 -0
  322. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/bad_beamlineParameters +0 -0
  323. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/i04_beamlineParameters +0 -0
  324. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/test_beamline_dcm_roll_converter.txt +0 -0
  325. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/test_beamline_dcm_roll_converter_non_monotonic.txt +0 -0
  326. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/test_beamline_dcm_roll_converter_reversed.txt +0 -0
  327. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/test_beamline_parameters.txt +0 -0
  328. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/test_det_dist_converter.txt +0 -0
  329. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/topup_long_delay.txt +0 -0
  330. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_data/topup_short_params.txt +0 -0
  331. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/test_utils.py +0 -0
  332. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/unit_tests/__init__.py +0 -0
  333. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/unit_tests/test_cli.py +0 -0
  334. {dls_dodal-1.31.0 → dls_dodal-1.32.0}/tests/unit_tests/test_log.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.31.0
3
+ Version: 1.32.0
4
4
  Summary: Ophyd devices and other utils that could be used across DLS beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
6
6
  License: Apache License
@@ -216,7 +216,7 @@ Description-Content-Type: text/markdown
216
216
  License-File: LICENSE
217
217
  Requires-Dist: click
218
218
  Requires-Dist: ophyd
219
- Requires-Dist: ophyd-async>=0.5.2
219
+ Requires-Dist: ophyd-async<0.7,>=0.6
220
220
  Requires-Dist: bluesky
221
221
  Requires-Dist: pyepics
222
222
  Requires-Dist: dataclasses-json
@@ -232,6 +232,7 @@ Requires-Dist: numpy<2.0
232
232
  Requires-Dist: aiofiles
233
233
  Requires-Dist: aiohttp
234
234
  Requires-Dist: redis
235
+ Requires-Dist: deepdiff
235
236
  Provides-Extra: dev
236
237
  Requires-Dist: black; extra == "dev"
237
238
  Requires-Dist: diff-cover; extra == "dev"
@@ -15,7 +15,7 @@ description = "Ophyd devices and other utils that could be used across DLS beaml
15
15
  dependencies = [
16
16
  "click",
17
17
  "ophyd",
18
- "ophyd-async>=0.5.2",
18
+ "ophyd-async>=0.6,<0.7",
19
19
  "bluesky",
20
20
  "pyepics",
21
21
  "dataclasses-json",
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "aiofiles",
32
32
  "aiohttp",
33
33
  "redis",
34
+ "deepdiff",
34
35
  ]
35
36
 
36
37
  dynamic = ["version"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.31.0
3
+ Version: 1.32.0
4
4
  Summary: Ophyd devices and other utils that could be used across DLS beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
6
6
  License: Apache License
@@ -216,7 +216,7 @@ Description-Content-Type: text/markdown
216
216
  License-File: LICENSE
217
217
  Requires-Dist: click
218
218
  Requires-Dist: ophyd
219
- Requires-Dist: ophyd-async>=0.5.2
219
+ Requires-Dist: ophyd-async<0.7,>=0.6
220
220
  Requires-Dist: bluesky
221
221
  Requires-Dist: pyepics
222
222
  Requires-Dist: dataclasses-json
@@ -232,6 +232,7 @@ Requires-Dist: numpy<2.0
232
232
  Requires-Dist: aiofiles
233
233
  Requires-Dist: aiohttp
234
234
  Requires-Dist: redis
235
+ Requires-Dist: deepdiff
235
236
  Provides-Extra: dev
236
237
  Requires-Dist: black; extra == "dev"
237
238
  Requires-Dist: diff-cover; extra == "dev"
@@ -321,6 +321,8 @@ tests/test_data/test_beamline_parameters.txt
321
321
  tests/test_data/test_det_dist_converter.txt
322
322
  tests/test_data/topup_long_delay.txt
323
323
  tests/test_data/topup_short_params.txt
324
+ tests/test_data/test_images/oav_snapshot_expected.png
325
+ tests/test_data/test_images/oav_snapshot_test.png
324
326
  tests/unit_tests/__init__.py
325
327
  tests/unit_tests/test_cli.py
326
328
  tests/unit_tests/test_log.py
@@ -1,6 +1,6 @@
1
1
  click
2
2
  ophyd
3
- ophyd-async>=0.5.2
3
+ ophyd-async<0.7,>=0.6
4
4
  bluesky
5
5
  pyepics
6
6
  dataclasses-json
@@ -16,6 +16,7 @@ numpy<2.0
16
16
  aiofiles
17
17
  aiohttp
18
18
  redis
19
+ deepdiff
19
20
 
20
21
  [dev]
21
22
  black
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.31.0'
16
- __version_tuple__ = version_tuple = (1, 31, 0)
15
+ __version__ = version = '1.32.0'
16
+ __version_tuple__ = version_tuple = (1, 32, 0)
@@ -308,6 +308,7 @@ def undulator(
308
308
  wait_for_connection,
309
309
  fake_with_ophyd_sim,
310
310
  bl_prefix=False,
311
+ id_gap_lookup_table_path="/dls_sw/i04/software/gda/config/lookupTables/BeamLine_Undulator_toGap.txt",
311
312
  )
312
313
 
313
314
 
@@ -199,6 +199,7 @@ def undulator(
199
199
  bl_prefix=False,
200
200
  poles=80,
201
201
  length=2.0,
202
+ id_gap_lookup_table_path="/dls_sw/i22/software/daq_configuration/lookup/BeamLine_Undulator_toGap.txt",
202
203
  )
203
204
 
204
205
 
@@ -220,15 +220,15 @@ class ApertureScatterguard(StandardReadable, Movable):
220
220
  self.aperture.y.set(aperture_y),
221
221
  self.aperture.z.set(aperture_z),
222
222
  )
223
- return
224
- await asyncio.gather(
225
- self.aperture.x.set(aperture_x),
226
- self.aperture.y.set(aperture_y),
227
- self.aperture.z.set(aperture_z),
228
- )
223
+ else:
224
+ await asyncio.gather(
225
+ self.aperture.x.set(aperture_x),
226
+ self.aperture.y.set(aperture_y),
227
+ self.aperture.z.set(aperture_z),
228
+ )
229
229
 
230
- await asyncio.gather(
231
- self.scatterguard.x.set(scatterguard_x),
232
- self.scatterguard.y.set(scatterguard_y),
233
- )
230
+ await asyncio.gather(
231
+ self.scatterguard.x.set(scatterguard_x),
232
+ self.scatterguard.y.set(scatterguard_y),
233
+ )
234
234
  await self.selected_aperture.set(value)
@@ -87,11 +87,12 @@ class MJPG(Device, ABC):
87
87
 
88
88
 
89
89
  class SnapshotWithBeamCentre(MJPG):
90
- """A child of MJPG which, when triggered, draws a crosshair at the beam centre in the
91
- image and saves the image to disk."""
90
+ """A child of MJPG which, when triggered, draws an outlined crosshair at the beam
91
+ centre in the image and saves the image to disk."""
92
92
 
93
93
  CROSSHAIR_LENGTH_PX = 20
94
- CROSSHAIR_COLOUR = "Blue"
94
+ CROSSHAIR_OUTLINE_COLOUR = "Black"
95
+ CROSSHAIR_FILL_COLOUR = "White"
95
96
 
96
97
  def post_processing(self, image: Image.Image):
97
98
  assert (
@@ -100,15 +101,38 @@ class SnapshotWithBeamCentre(MJPG):
100
101
  beam_x = self.oav_params.beam_centre_i
101
102
  beam_y = self.oav_params.beam_centre_j
102
103
 
104
+ SnapshotWithBeamCentre.draw_crosshair(image, beam_x, beam_y)
105
+
106
+ self._save_image(image)
107
+
108
+ @classmethod
109
+ def draw_crosshair(cls, image: Image.Image, beam_x: int, beam_y: int):
103
110
  draw = ImageDraw.Draw(image)
104
- HALF_LEN = self.CROSSHAIR_LENGTH_PX / 2
111
+ OUTLINE_WIDTH = 1
112
+ HALF_LEN = cls.CROSSHAIR_LENGTH_PX / 2
113
+ draw.rectangle(
114
+ [
115
+ beam_x - OUTLINE_WIDTH,
116
+ beam_y - HALF_LEN - OUTLINE_WIDTH,
117
+ beam_x + OUTLINE_WIDTH,
118
+ beam_y + HALF_LEN + OUTLINE_WIDTH,
119
+ ],
120
+ fill=cls.CROSSHAIR_OUTLINE_COLOUR,
121
+ )
122
+ draw.rectangle(
123
+ [
124
+ beam_x - HALF_LEN - OUTLINE_WIDTH,
125
+ beam_y - OUTLINE_WIDTH,
126
+ beam_x + HALF_LEN + OUTLINE_WIDTH,
127
+ beam_y + OUTLINE_WIDTH,
128
+ ],
129
+ fill=cls.CROSSHAIR_OUTLINE_COLOUR,
130
+ )
105
131
  draw.line(
106
132
  ((beam_x, beam_y - HALF_LEN), (beam_x, beam_y + HALF_LEN)),
107
- fill=self.CROSSHAIR_COLOUR,
133
+ fill=cls.CROSSHAIR_FILL_COLOUR,
108
134
  )
109
135
  draw.line(
110
136
  ((beam_x - HALF_LEN, beam_y), (beam_x + HALF_LEN, beam_y)),
111
- fill=self.CROSSHAIR_COLOUR,
137
+ fill=cls.CROSSHAIR_FILL_COLOUR,
112
138
  )
113
-
114
- self._save_image(image)
@@ -79,7 +79,7 @@ class DetectorParams(BaseModel):
79
79
  def _parse_directory(cls, directory: str | Path) -> str:
80
80
  path = Path(directory)
81
81
  assert path.is_dir()
82
- return str(path)
82
+ return f"{path}/"
83
83
 
84
84
  def get_beam_position_mm(self, detector_distance: float) -> tuple[float, float]:
85
85
  x_beam_mm = self.beam_xy_converter.get_beam_xy_from_det_dist(
@@ -3,6 +3,7 @@ from typing import Generic, TypeVar
3
3
 
4
4
  import numpy as np
5
5
  from bluesky.plan_stubs import mv
6
+ from bluesky.protocols import Flyable
6
7
  from numpy import ndarray
7
8
  from ophyd_async.core import (
8
9
  AsyncStatus,
@@ -193,7 +194,7 @@ class ExpectedImages(SignalR[int]):
193
194
  return first_grid + second_grid
194
195
 
195
196
 
196
- class FastGridScanCommon(StandardReadable, ABC, Generic[ParamType]):
197
+ class FastGridScanCommon(StandardReadable, Flyable, ABC, Generic[ParamType]):
197
198
  """Device for a general fast grid scan
198
199
 
199
200
  When the motion program is started, the goniometer will move in a snake-like grid trajectory,
@@ -76,7 +76,7 @@ class MirrorVoltageDevice(Device):
76
76
  LOGGER.debug(f"{setpoint_v.name} already at {value} - skipping set")
77
77
  return
78
78
 
79
- LOGGER.debug(f"setting {setpoint_v.name} to {value}")
79
+ LOGGER.debug(f"Setting {setpoint_v.name} to {value}")
80
80
 
81
81
  # Register an observer up front to ensure we don't miss events after we
82
82
  # perform the set
@@ -85,16 +85,14 @@ class MirrorVoltageDevice(Device):
85
85
  )
86
86
  # discard the current value (OK) so we can await a subsequent change
87
87
  await anext(demand_accepted_iterator)
88
- await setpoint_v.set(value)
88
+ set_status = setpoint_v.set(value, wait=False)
89
89
 
90
90
  # The set should always change to SLEW regardless of whether we are
91
91
  # already at the set point, then change back to OK/FAIL depending on
92
92
  # success
93
93
  accepted_value = await anext(demand_accepted_iterator)
94
94
  assert accepted_value == MirrorVoltageDemand.SLEW
95
- LOGGER.debug(
96
- f"Demand not accepted for {setpoint_v.name}, waiting for acceptance..."
97
- )
95
+ LOGGER.debug(f"Waiting for {setpoint_v.name} to set")
98
96
  while MirrorVoltageDemand.SLEW == (
99
97
  accepted_value := await anext(demand_accepted_iterator)
100
98
  ):
@@ -104,6 +102,7 @@ class MirrorVoltageDevice(Device):
104
102
  raise AssertionError(
105
103
  f"Voltage slew failed for {setpoint_v.name}, new state={accepted_value}"
106
104
  )
105
+ await set_status
107
106
 
108
107
 
109
108
  class VFMMirrorVoltages(StandardReadable):
@@ -1,16 +1,17 @@
1
+ from asyncio import sleep
1
2
  from enum import Enum, IntEnum
2
- from typing import SupportsFloat
3
3
 
4
- from bluesky.protocols import Triggerable
4
+ from bluesky.protocols import Flyable, Triggerable
5
5
  from ophyd_async.core import (
6
+ CALCULATE_TIMEOUT,
6
7
  DEFAULT_TIMEOUT,
7
8
  AsyncStatus,
8
- CalculateTimeout,
9
9
  SignalBackend,
10
10
  SignalR,
11
11
  SignalRW,
12
12
  SoftSignalBackend,
13
13
  StandardReadable,
14
+ soft_signal_rw,
14
15
  wait_for_value,
15
16
  )
16
17
  from ophyd_async.epics.motor import Motor
@@ -89,7 +90,7 @@ class PMACStringLaser(SignalRW):
89
90
  self,
90
91
  value: LaserSettings,
91
92
  wait=True,
92
- timeout=CalculateTimeout,
93
+ timeout=CALCULATE_TIMEOUT,
93
94
  ):
94
95
  await self.signal.set(value.value, wait, timeout)
95
96
 
@@ -112,13 +113,13 @@ class PMACStringEncReset(SignalRW):
112
113
  self,
113
114
  value: EncReset,
114
115
  wait=True,
115
- timeout=CalculateTimeout,
116
+ timeout=CALCULATE_TIMEOUT,
116
117
  ):
117
118
  await self.signal.set(value.value, wait, timeout)
118
119
 
119
120
 
120
- class ProgramRunner(SignalRW):
121
- """Trigger the collection by setting the program number on the PMAC string.
121
+ class ProgramRunner(SignalRW, Flyable):
122
+ """Run the collection by setting the program number on the PMAC string.
122
123
 
123
124
  Once the program number has been set, wait for the collection to be complete.
124
125
  This will only be true when the status becomes 0.
@@ -128,22 +129,73 @@ class ProgramRunner(SignalRW):
128
129
  self,
129
130
  pmac_str_sig: SignalRW,
130
131
  status_sig: SignalR,
132
+ prog_num_sig: SignalRW,
133
+ collection_time_sig: SignalRW,
131
134
  backend: SignalBackend,
132
135
  timeout: float | None = DEFAULT_TIMEOUT,
133
136
  name: str = "",
134
137
  ) -> None:
135
138
  self.signal = pmac_str_sig
136
139
  self.status = status_sig
140
+ self.prog_num = prog_num_sig
141
+
142
+ self.collection_time = collection_time_sig
143
+ self.KICKOFF_TIMEOUT = timeout
144
+
137
145
  super().__init__(backend, timeout, name)
138
146
 
147
+ async def _get_prog_number_string(self) -> str:
148
+ prog_num = await self.prog_num.get_value()
149
+ return f"&2b{prog_num}r"
150
+
151
+ @AsyncStatus.wrap
152
+ async def kickoff(self):
153
+ """Kick off the collection by sending a program number to the pmac_string and \
154
+ wait for the scan status PV to go to 1.
155
+ """
156
+ prog_num_str = await self._get_prog_number_string()
157
+ await self.signal.set(prog_num_str, wait=True)
158
+ await wait_for_value(
159
+ self.status,
160
+ ScanState.RUNNING,
161
+ timeout=self.KICKOFF_TIMEOUT,
162
+ )
163
+
164
+ @AsyncStatus.wrap
165
+ async def complete(self):
166
+ """Stop collecting when the scan status PV goes to 0.
167
+
168
+ Args:
169
+ complete_time (float): total time required by the collection to \
170
+ finish correctly.
171
+ """
172
+ scan_complete_time = await self.collection_time.get_value()
173
+ await wait_for_value(self.status, ScanState.DONE, timeout=scan_complete_time)
174
+
175
+
176
+ class ProgramAbort(Triggerable):
177
+ """Abort a data collection by setting the PMAC string and then wait for the \
178
+ status value to go back to 0.
179
+ """
180
+
181
+ def __init__(
182
+ self,
183
+ pmac_str_sig: SignalRW,
184
+ status_sig: SignalR,
185
+ ) -> None:
186
+ self.signal = pmac_str_sig
187
+ self.status = status_sig
188
+
139
189
  @AsyncStatus.wrap
140
- async def set(self, value: int, wait=True, timeout=None):
141
- prog_str = f"&2b{value}r"
142
- assert isinstance(timeout, SupportsFloat) or (
143
- timeout is None
144
- ), f"ProgramRunner does not support calculating timeout itself, {timeout=}"
145
- await self.signal.set(prog_str, wait=wait)
146
- await wait_for_value(self.status, ScanState.DONE, timeout)
190
+ async def trigger(self):
191
+ await self.signal.set("A", wait=True)
192
+ await sleep(1.0) # TODO Check with scientist what this sleep is really for.
193
+ await self.signal.set("P2401=0", wait=True)
194
+ await wait_for_value(
195
+ self.status,
196
+ ScanState.DONE,
197
+ timeout=DEFAULT_TIMEOUT,
198
+ )
147
199
 
148
200
 
149
201
  class PMAC(StandardReadable):
@@ -172,8 +224,18 @@ class PMAC(StandardReadable):
172
224
  self.scanstatus = epics_signal_r(float, "BL24I-MO-STEP-14:signal:P2401")
173
225
  self.counter = epics_signal_r(float, "BL24I-MO-STEP-14:signal:P2402")
174
226
 
227
+ # A couple of soft signals for running a collection: program number to send to
228
+ # the PMAC_STRING and expected collection time.
229
+ self.program_number = soft_signal_rw(int)
230
+ self.collection_time = soft_signal_rw(float, initial_value=600.0, units="s")
231
+
175
232
  self.run_program = ProgramRunner(
176
- self.pmac_string, self.scanstatus, backend=SoftSignalBackend(str)
233
+ self.pmac_string,
234
+ self.scanstatus,
235
+ self.program_number,
236
+ self.collection_time,
237
+ backend=SoftSignalBackend(str),
177
238
  )
239
+ self.abort_program = ProgramAbort(self.pmac_string, self.scanstatus)
178
240
 
179
241
  super().__init__(name)
@@ -1,5 +1,5 @@
1
1
  import asyncio
2
- from asyncio import FIRST_COMPLETED, CancelledError, Task
2
+ from asyncio import FIRST_COMPLETED, CancelledError, Task, wait_for
3
3
  from dataclasses import dataclass
4
4
  from enum import Enum
5
5
 
@@ -41,6 +41,9 @@ class PinMounted(str, Enum):
41
41
  class BartRobot(StandardReadable, Movable):
42
42
  """The sample changing robot."""
43
43
 
44
+ # How long to wait for the robot if it is busy soaking/drying
45
+ NOT_BUSY_TIMEOUT = 60
46
+ # How long to wait for the actual load to happen
44
47
  LOAD_TIMEOUT = 60
45
48
  NO_PIN_ERROR_CODE = 25
46
49
 
@@ -54,10 +57,15 @@ class BartRobot(StandardReadable, Movable):
54
57
  ) -> None:
55
58
  self.barcode = epics_signal_r(str, prefix + "BARCODE")
56
59
  self.gonio_pin_sensor = epics_signal_r(PinMounted, prefix + "PIN_MOUNTED")
60
+
57
61
  self.next_pin = epics_signal_rw_rbv(float, prefix + "NEXT_PIN")
58
62
  self.next_puck = epics_signal_rw_rbv(float, prefix + "NEXT_PUCK")
63
+ self.current_puck = epics_signal_r(float, prefix + "CURRENT_PUCK_RBV")
64
+ self.current_pin = epics_signal_r(float, prefix + "CURRENT_PIN_RBV")
65
+
59
66
  self.next_sample_id = epics_signal_rw_rbv(float, prefix + "NEXT_ID")
60
67
  self.sample_id = epics_signal_r(float, prefix + "CURRENT_ID_RBV")
68
+
61
69
  self.load = epics_signal_x(prefix + "LOAD.PROC")
62
70
  self.program_running = epics_signal_r(bool, prefix + "PROGRAM_RUNNING")
63
71
  self.program_name = epics_signal_r(str, prefix + "PROGRAM_NAME")
@@ -93,7 +101,7 @@ class BartRobot(StandardReadable, Movable):
93
101
  for task in finished:
94
102
  await task
95
103
  except CancelledError:
96
- # If the outer enclosing task cancels after LOAD_TIMEOUT, this causes CancelledError to be raised
104
+ # If the outer enclosing task cancels after a timeout, this causes CancelledError to be raised
97
105
  # in the current task, when it propagates to here we should cancel all pending tasks before bubbling up
98
106
  for task in tasks:
99
107
  task.cancel()
@@ -105,7 +113,9 @@ class BartRobot(StandardReadable, Movable):
105
113
  LOGGER.info(
106
114
  f"Waiting on robot to finish {await self.program_name.get_value()}"
107
115
  )
108
- await wait_for_value(self.program_running, False, None)
116
+ await wait_for_value(
117
+ self.program_running, False, timeout=self.NOT_BUSY_TIMEOUT
118
+ )
109
119
  await asyncio.gather(
110
120
  set_and_wait_for_value(self.next_puck, sample_location.puck),
111
121
  set_and_wait_for_value(self.next_pin, sample_location.pin),
@@ -121,10 +131,12 @@ class BartRobot(StandardReadable, Movable):
121
131
  @AsyncStatus.wrap
122
132
  async def set(self, value: SampleLocation):
123
133
  try:
124
- await asyncio.wait_for(
125
- self._load_pin_and_puck(value), timeout=self.LOAD_TIMEOUT
134
+ await wait_for(
135
+ self._load_pin_and_puck(value),
136
+ timeout=self.LOAD_TIMEOUT + self.NOT_BUSY_TIMEOUT,
126
137
  )
127
- except asyncio.TimeoutError as e:
138
+ except (asyncio.TimeoutError, TimeoutError) as e:
139
+ # Will only need to catch asyncio.TimeoutError after https://github.com/bluesky/ophyd-async/issues/572
128
140
  error_code = await self.error_code.get_value()
129
141
  error_string = await self.error_str.get_value()
130
142
  raise RobotLoadFailed(int(error_code), error_string) from e
@@ -3,13 +3,13 @@ from enum import Enum
3
3
 
4
4
  from bluesky.protocols import Hints
5
5
  from ophyd_async.core import (
6
- AsyncStatus,
7
6
  DatasetDescriber,
8
7
  DetectorControl,
9
8
  DetectorTrigger,
10
9
  Device,
11
10
  PathProvider,
12
11
  StandardDetector,
12
+ TriggerInfo,
13
13
  set_and_wait_for_value,
14
14
  soft_signal_r_and_setter,
15
15
  )
@@ -113,29 +113,24 @@ class TetrammController(DetectorControl):
113
113
  # 2 internal clock cycles. Best effort approximation
114
114
  return 2 / self.base_sample_rate
115
115
 
116
- async def arm(
117
- self,
118
- num: int,
119
- trigger: DetectorTrigger = DetectorTrigger.edge_trigger,
120
- exposure: float | None = None,
121
- ) -> AsyncStatus:
122
- if exposure is None:
123
- raise ValueError(
124
- "Tetramm does not support arm without exposure time. "
125
- "Is this a software scan? Tetramm only supports hardware scans."
126
- )
127
- self._validate_trigger(trigger)
116
+ async def prepare(self, trigger_info: TriggerInfo):
117
+ self._validate_trigger(trigger_info.trigger)
118
+ assert trigger_info.livetime is not None
128
119
 
129
120
  # trigger mode must be set first and on its own!
130
121
  await self._drv.trigger_mode.set(TetrammTrigger.ExtTrigger)
131
122
 
132
123
  await asyncio.gather(
133
- self._drv.averaging_time.set(exposure), self.set_exposure(exposure)
124
+ self._drv.averaging_time.set(trigger_info.livetime),
125
+ self.set_exposure(trigger_info.livetime),
134
126
  )
135
127
 
136
- status = await set_and_wait_for_value(self._drv.acquire, True)
128
+ async def arm(self):
129
+ self._arm_status = await set_and_wait_for_value(self._drv.acquire, True)
137
130
 
138
- return status
131
+ async def wait_for_idle(self):
132
+ if self._arm_status:
133
+ await self._arm_status
139
134
 
140
135
  def _validate_trigger(self, trigger: DetectorTrigger) -> None:
141
136
  supported_trigger_types = {