dls-dodal 1.36.1a0__tar.gz → 1.36.2__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 (385) hide show
  1. dls_dodal-1.36.2/.github/CODEOWNERS +1 -0
  2. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/PKG-INFO +1 -1
  3. dls_dodal-1.36.2/docs/explanations/decisions/0003-codeowners.md +19 -0
  4. dls_dodal-1.36.2/docs/explanations/reviews.md +56 -0
  5. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/pyproject.toml +2 -1
  6. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/PKG-INFO +1 -1
  7. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/SOURCES.txt +5 -5
  8. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/_version.py +2 -2
  9. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/__init__.py +1 -0
  10. dls_dodal-1.36.2/src/dodal/beamlines/adsim.py +75 -0
  11. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i24.py +16 -0
  12. dls_dodal-1.36.2/src/dodal/devices/adsim.py +13 -0
  13. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/aperture.py +0 -7
  14. dls_dodal-1.36.2/src/dodal/devices/aperturescatterguard.py +243 -0
  15. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/attenuator.py +15 -5
  16. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/focusing_mirror.py +12 -3
  17. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/pin_image_recognition/__init__.py +2 -4
  18. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/undulator_dcm.py +4 -0
  19. dls_dodal-1.36.2/system_tests/test_adsim.py +183 -0
  20. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_aperture_scatterguard.py +52 -127
  21. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_focusing_mirror.py +10 -3
  22. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_undulator_dcm.py +33 -0
  23. dls_dodal-1.36.1a0/src/dodal/adsim.py +0 -17
  24. dls_dodal-1.36.1a0/src/dodal/devices/adsim.py +0 -13
  25. dls_dodal-1.36.1a0/src/dodal/devices/aperturescatterguard.py +0 -359
  26. dls_dodal-1.36.1a0/src/dodal/devices/areadetector/__init__.py +0 -10
  27. dls_dodal-1.36.1a0/src/dodal/devices/areadetector/adaravis.py +0 -101
  28. dls_dodal-1.36.1a0/src/dodal/devices/areadetector/adsim.py +0 -47
  29. dls_dodal-1.36.1a0/src/dodal/devices/areadetector/adutils.py +0 -81
  30. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.copier-answers.yml +0 -0
  31. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.devcontainer/devcontainer.json +0 -0
  32. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/CONTRIBUTING.md +0 -0
  33. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/ISSUE_TEMPLATE/issue_template.md +0 -0
  34. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/actions/install_requirements/action.yml +0 -0
  35. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/dependabot.yml +0 -0
  36. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/pages/index.html +0 -0
  37. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/pages/make_switcher.py +0 -0
  38. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_check.yml +0 -0
  39. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_dist.yml +0 -0
  40. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_docs.yml +0 -0
  41. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_pypi.yml +0 -0
  42. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_release.yml +0 -0
  43. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_test.yml +0 -0
  44. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/_tox.yml +0 -0
  45. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/ci.yml +0 -0
  46. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.github/workflows/periodic.yml +0 -0
  47. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.gitignore +0 -0
  48. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.pre-commit-config.yaml +0 -0
  49. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.vscode/extensions.json +0 -0
  50. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.vscode/launch.json +0 -0
  51. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.vscode/settings.json +0 -0
  52. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/.vscode/tasks.json +0 -0
  53. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/Dockerfile +0 -0
  54. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/LICENSE +0 -0
  55. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/README.md +0 -0
  56. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/catalog-info.yaml +0 -0
  57. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/conftest.py +0 -0
  58. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/_api.rst +0 -0
  59. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/_templates/autosummary/class.rst +0 -0
  60. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/_templates/autosummary/module.rst +0 -0
  61. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/_templates/custom-module-template.rst +0 -0
  62. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/assets/zocalo.png +0 -0
  63. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/conf.py +0 -0
  64. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  65. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  66. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations/decisions/0003-make-devices-factory.md +0 -0
  67. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations/decisions/COPYME +0 -0
  68. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations/decisions.md +0 -0
  69. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/explanations.md +0 -0
  70. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/genindex.md +0 -0
  71. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/build-docs.md +0 -0
  72. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/contribute.md +0 -0
  73. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/coverage.md +0 -0
  74. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/create-beamline.rst +0 -0
  75. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/dev-install.md +0 -0
  76. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/excalidraw.md +0 -0
  77. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/lint.md +0 -0
  78. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/lock-requirements.md +0 -0
  79. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/make-new-ophyd-async-device.rst +0 -0
  80. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/make-release.md +0 -0
  81. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/move-code.rst +0 -0
  82. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/pypi.md +0 -0
  83. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/run-tests.md +0 -0
  84. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/static-analysis.md +0 -0
  85. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/update-template.md +0 -0
  86. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/write-tests.md +0 -0
  87. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to/zocalo.rst +0 -0
  88. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/how-to.md +0 -0
  89. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/images/dls-logo.svg +0 -0
  90. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/images/excalidraw-example.svg +0 -0
  91. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/index.md +0 -0
  92. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/reference/device-standards.rst +0 -0
  93. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/reference/standards.rst +0 -0
  94. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/reference.md +0 -0
  95. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/tutorials/get_started.rst +0 -0
  96. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/tutorials/installation.md +0 -0
  97. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/docs/tutorials.md +0 -0
  98. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/pull_request_template.md +0 -0
  99. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/setup.cfg +0 -0
  100. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/__init__.py +0 -0
  101. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/dependency_links.txt +0 -0
  102. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/entry_points.txt +0 -0
  103. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/requires.txt +0 -0
  104. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dls_dodal.egg-info/top_level.txt +0 -0
  105. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/__init__.py +0 -0
  106. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/__main__.py +0 -0
  107. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamline_specific_utils/__init__.py +0 -0
  108. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamline_specific_utils/i03.py +0 -0
  109. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/README.md +0 -0
  110. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/b01_1.py +0 -0
  111. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i03.py +0 -0
  112. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i04.py +0 -0
  113. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i10.py +0 -0
  114. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i13_1.py +0 -0
  115. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i20_1.py +0 -0
  116. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i22.py +0 -0
  117. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/i23.py +0 -0
  118. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/p38.py +0 -0
  119. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/p45.py +0 -0
  120. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/p99.py +0 -0
  121. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/beamlines/training_rig.py +0 -0
  122. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/cli.py +0 -0
  123. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/__init__.py +0 -0
  124. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/beamlines/__init__.py +0 -0
  125. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/beamlines/beamline_parameters.py +0 -0
  126. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/beamlines/beamline_utils.py +0 -0
  127. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/beamlines/device_helpers.py +0 -0
  128. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/coordination.py +0 -0
  129. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/crystal_metadata.py +0 -0
  130. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/maths.py +0 -0
  131. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/signal_utils.py +0 -0
  132. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/types.py +0 -0
  133. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/udc_directory_provider.py +0 -0
  134. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/common/visit.py +0 -0
  135. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/CTAB.py +0 -0
  136. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/__init__.py +0 -0
  137. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/apple2_undulator.py +0 -0
  138. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/areadetector/plugins/CAM.py +0 -0
  139. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/areadetector/plugins/MJPG.py +0 -0
  140. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/backlight.py +0 -0
  141. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/cryostream.py +0 -0
  142. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/dcm.py +0 -0
  143. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/__init__.py +0 -0
  144. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/det_dim_constants.py +0 -0
  145. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/det_dist_to_beam_converter.py +0 -0
  146. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/det_resolution.py +0 -0
  147. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/detector.py +0 -0
  148. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/detector/detector_motion.py +0 -0
  149. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/diamond_filter.py +0 -0
  150. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/eiger.py +0 -0
  151. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/eiger_odin.py +0 -0
  152. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/fast_grid_scan.py +0 -0
  153. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/fluorescence_detector_motion.py +0 -0
  154. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/flux.py +0 -0
  155. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/hutch_shutter.py +0 -0
  156. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i03/__init__.py +0 -0
  157. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i04/transfocator.py +0 -0
  158. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i10/i10_apple2.py +0 -0
  159. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i10/i10_setting_data.py +0 -0
  160. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i20_1/__init__.py +0 -0
  161. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i22/dcm.py +0 -0
  162. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i22/fswitch.py +0 -0
  163. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i22/nxsas.py +0 -0
  164. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/__init__.py +0 -0
  165. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/aperture.py +0 -0
  166. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/beam_center.py +0 -0
  167. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/beamstop.py +0 -0
  168. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/dcm.py +0 -0
  169. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/dual_backlight.py +0 -0
  170. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/focus_mirrors.py +0 -0
  171. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/i24_detector_motion.py +0 -0
  172. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/pilatus_metadata.py +0 -0
  173. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/pmac.py +0 -0
  174. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/i24/vgonio.py +0 -0
  175. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/ipin.py +0 -0
  176. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/linkam3.py +0 -0
  177. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/logging_ophyd_device.py +0 -0
  178. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/motors.py +0 -0
  179. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/__init__.py +0 -0
  180. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/microns_for_zoom_levels.json +0 -0
  181. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/oav_calculations.py +0 -0
  182. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/oav_detector.py +0 -0
  183. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/oav_parameters.py +0 -0
  184. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/oav_to_redis_forwarder.py +0 -0
  185. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/pin_image_recognition/manual_test.py +0 -0
  186. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/pin_image_recognition/utils.py +0 -0
  187. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/snapshots/grid_overlay.py +0 -0
  188. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/snapshots/snapshot_with_beam_centre.py +0 -0
  189. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/snapshots/snapshot_with_grid.py +0 -0
  190. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/oav/utils.py +0 -0
  191. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/p45.py +0 -0
  192. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/p99/__init__.py +0 -0
  193. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/p99/sample_stage.py +0 -0
  194. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/pgm.py +0 -0
  195. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/pressure_jump_cell.py +0 -0
  196. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/qbpm.py +0 -0
  197. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/robot.py +0 -0
  198. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/s4_slit_gaps.py +0 -0
  199. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/scatterguard.py +0 -0
  200. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/scintillator.py +0 -0
  201. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/slits.py +0 -0
  202. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/smargon.py +0 -0
  203. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/status.py +0 -0
  204. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/synchrotron.py +0 -0
  205. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/tetramm.py +0 -0
  206. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/thawer.py +0 -0
  207. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/training_rig/__init__.py +0 -0
  208. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/training_rig/sample_stage.py +0 -0
  209. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/turbo_slit.py +0 -0
  210. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/undulator.py +0 -0
  211. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/__init__.py +0 -0
  212. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/adjuster_plans.py +0 -0
  213. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/epics_util.py +0 -0
  214. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/lookup_tables.py +0 -0
  215. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/motor_utils.py +0 -0
  216. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/save_panda.py +0 -0
  217. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/util/test_utils.py +0 -0
  218. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/watsonmarlow323_pump.py +0 -0
  219. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/webcam.py +0 -0
  220. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/xbpm_feedback.py +0 -0
  221. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/xspress3/xspress3.py +0 -0
  222. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/xspress3/xspress3_channel.py +0 -0
  223. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zebra.py +0 -0
  224. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zebra_controlled_shutter.py +0 -0
  225. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zocalo/__init__.py +0 -0
  226. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zocalo/zocalo_constants.py +0 -0
  227. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zocalo/zocalo_interaction.py +0 -0
  228. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/devices/zocalo/zocalo_results.py +0 -0
  229. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/log.py +0 -0
  230. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/parameters/experiment_parameter_base.py +0 -0
  231. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plan_stubs/__init__.py +0 -0
  232. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plan_stubs/check_topup.py +0 -0
  233. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plan_stubs/data_session.py +0 -0
  234. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plan_stubs/motor_utils.py +0 -0
  235. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plan_stubs/wrapped.py +0 -0
  236. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plans/__init__.py +0 -0
  237. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plans/scanspec.py +0 -0
  238. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/plans/wrapped.py +0 -0
  239. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/src/dodal/utils.py +0 -0
  240. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/__init__.py +0 -0
  241. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_aperturescatterguard_system.py +0 -0
  242. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_eiger_system.py +0 -0
  243. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_gridscan_system.py +0 -0
  244. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_oav_system.py +0 -0
  245. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_oav_to_redis_system.py +0 -0
  246. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_slit_gaps_system.py +0 -0
  247. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_smargon_system.py +0 -0
  248. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_synchrotron_system.py +0 -0
  249. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_undulator_system.py +0 -0
  250. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_zebra_system.py +0 -0
  251. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/system_tests/test_zocalo_results.py +0 -0
  252. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/__init__.py +0 -0
  253. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/beamlines/__init__.py +0 -0
  254. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/beamlines/unit_tests/__init__.py +0 -0
  255. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/beamlines/unit_tests/test_i03.py +0 -0
  256. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/beamlines/unit_tests/test_i24.py +0 -0
  257. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/beamlines/unit_tests/test_mapping.py +0 -0
  258. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/__init__.py +0 -0
  259. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/beamlines/__init__.py +0 -0
  260. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/beamlines/test_beamline_parameters.py +0 -0
  261. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/beamlines/test_beamline_utils.py +0 -0
  262. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/beamlines/test_device_helpers.py +0 -0
  263. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/beamlines/test_device_instantiation.py +0 -0
  264. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/test_coordination.py +0 -0
  265. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/test_crystal_metadata.py +0 -0
  266. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/test_maths.py +0 -0
  267. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/test_udc_directory_provider.py +0 -0
  268. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/common/test_visit.py +0 -0
  269. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/__init__.py +0 -0
  270. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i04/__init__.py +0 -0
  271. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i04/test_transfocator.py +0 -0
  272. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/IDEnergy2GapCalibrations.csv +0 -0
  273. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/IDEnergy2PhaseCalibrations.csv +0 -0
  274. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/expectedIDEnergy2GapCalibrationsIdd.pkl +0 -0
  275. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/expectedIDEnergy2GapCalibrationsIdu.pkl +0 -0
  276. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/expectedIDEnergy2PhaseCalibrationsidd.pkl +0 -0
  277. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/lookupTables/expectedIDEnergy2PhaseCalibrationsidu.pkl +0 -0
  278. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i10/test_i10Apple2.py +0 -0
  279. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i22/test_dcm.py +0 -0
  280. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i22/test_fswitch.py +0 -0
  281. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/i22/test_metadataholder.py +0 -0
  282. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/test_diamond_filter.py +0 -0
  283. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/training_rig/test_sample_stage.py +0 -0
  284. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/__init__.py +0 -0
  285. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/conftest.py +0 -0
  286. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/detector/test_det_dim_constants.py +0 -0
  287. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/detector/test_det_resolution.py +0 -0
  288. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/detector/test_detector.py +0 -0
  289. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/__init__.py +0 -0
  290. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/test_dual_backlight.py +0 -0
  291. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/test_focus_mirrors.py +0 -0
  292. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/test_pilatus_metadata.py +0 -0
  293. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/test_pmac.py +0 -0
  294. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/i24/test_vgonio.py +0 -0
  295. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/__init__.py +0 -0
  296. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/conftest.py +0 -0
  297. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect.py +0 -0
  298. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect_utils.py +0 -0
  299. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_grid_overlay.py +0 -0
  300. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_oav.py +0 -0
  301. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_oav_parameters.py +0 -0
  302. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_oav_to_redis_forwarder.py +0 -0
  303. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_oav_utils.py +0 -0
  304. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/oav/test_snapshots.py +0 -0
  305. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/p99/test_p99_stage.py +0 -0
  306. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_OAVCentring.json +0 -0
  307. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_aperture.py +0 -0
  308. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_apple2_undulator.py +0 -0
  309. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_attenuator.py +0 -0
  310. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_backlight.py +0 -0
  311. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_bart_robot.py +0 -0
  312. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_beam_converter.py +0 -0
  313. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_beamline_undulator_to_gap_lookup_table.txt +0 -0
  314. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_daq_configuration/domain/beamlineParameters +0 -0
  315. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Pitch_converter.txt +0 -0
  316. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Roll_converter.txt +0 -0
  317. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_dcm.py +0 -0
  318. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_display.configuration +0 -0
  319. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_eiger.py +0 -0
  320. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_gridscan.py +0 -0
  321. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_hutch_shutter.py +0 -0
  322. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_jCameraManZoomLevels.xml +0 -0
  323. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_linkam3.py +0 -0
  324. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_lookup_table.txt +0 -0
  325. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_lookup_table_2.txt +0 -0
  326. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_odin.py +0 -0
  327. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_pressure_jump_cell.py +0 -0
  328. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_qbpm.py +0 -0
  329. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_shutter.py +0 -0
  330. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_slits.py +0 -0
  331. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_smargon.py +0 -0
  332. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_status.py +0 -0
  333. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_synchrotron.py +0 -0
  334. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_tetramm.py +0 -0
  335. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_thawer.py +0 -0
  336. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_undulator.py +0 -0
  337. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_utils.py +0 -0
  338. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_watsonmarlow323_pump.py +0 -0
  339. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_webcam.py +0 -0
  340. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_xbpm_feedback.py +0 -0
  341. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_xspress3.py +0 -0
  342. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_zebra.py +0 -0
  343. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_zocalo_interaction.py +0 -0
  344. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/test_zocalo_results.py +0 -0
  345. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/util/__init__.py +0 -0
  346. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/util/test_adjuster_plans.py +0 -0
  347. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/util/test_beamline_specific_utils.py +0 -0
  348. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/util/test_lookup_tables.py +0 -0
  349. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/devices/unit_tests/util/test_save_panda.py +0 -0
  350. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline.py +0 -0
  351. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_all_devices_raise_exception.py +0 -0
  352. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_broken_dependency.py +0 -0
  353. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_dependencies.py +0 -0
  354. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_disordered_dependencies.py +0 -0
  355. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_misbehaving_builtins.py +0 -0
  356. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_beamline_some_devices_working.py +0 -0
  357. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_device_factory_beamline.py +0 -0
  358. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_zocalo/README.rst +0 -0
  359. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_zocalo/__init__.py +0 -0
  360. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_zocalo/__main__.py +0 -0
  361. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/fake_zocalo/dls_start_fake_zocalo.sh +0 -0
  362. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plan_stubs/test_motor_util_plans.py +0 -0
  363. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plan_stubs/test_topup_plan.py +0 -0
  364. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plan_stubs/test_wrapped_stubs.py +0 -0
  365. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plans/conftest.py +0 -0
  366. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plans/test_compliance.py +0 -0
  367. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plans/test_scanspec.py +0 -0
  368. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/plans/test_wrapped.py +0 -0
  369. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/preprocessors/test_filesystem_metadata.py +0 -0
  370. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_cli.py +0 -0
  371. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/bad_beamlineParameters +0 -0
  372. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/i04_beamlineParameters +0 -0
  373. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_beamline_dcm_roll_converter.txt +0 -0
  374. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_beamline_dcm_roll_converter_non_monotonic.txt +0 -0
  375. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_beamline_dcm_roll_converter_reversed.txt +0 -0
  376. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_beamline_parameters.txt +0 -0
  377. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_det_dist_converter.txt +0 -0
  378. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_images/oav_snapshot_expected.png +0 -0
  379. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/test_images/oav_snapshot_test.png +0 -0
  380. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/topup_long_delay.txt +0 -0
  381. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_data/topup_short_params.txt +0 -0
  382. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/test_utils.py +0 -0
  383. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/unit_tests/__init__.py +0 -0
  384. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/unit_tests/test_cli.py +0 -0
  385. {dls_dodal-1.36.1a0 → dls_dodal-1.36.2}/tests/unit_tests/test_log.py +0 -0
@@ -0,0 +1 @@
1
+ * @DiamondLightSource/bluesky-reviewers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.36.1a0
3
+ Version: 1.36.2
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
@@ -0,0 +1,19 @@
1
+ # 3. Use CODEOWNERS Github feature to restrict approved reviewers
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ As dodal expands and covers an increasing number of beamlines it is important to maintain quality. So far we have seen good results from following bluesky's own standards: Encouraging high test coverage, readable code (including type annotations, where appropriate) and collective ownership, including via thorough reviews which appropriately balance velocity with technical debt management. We would like to make sure this developer culture is preserved as we expand.
10
+
11
+ ## Decision
12
+
13
+ Have a team of approved reviewers in the DiamondLightSource Github organisation. Every PR into dodal **must** be reviewed by a member of this team before merging (enforced by repo settings and [CODEOWNERS feature](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners)). Have a set of [documented criteria](../reviews.md) for becoming part of the team, with the expectation that any team that regularly works on dodal will become members over time. The hope is that a consistent set of standards can be maintained by the approver community.
14
+
15
+ ## Consequences
16
+
17
+ PRs will not be mergable until an approved owner has reviewed them, approved individuals/teams will have to review/support onboarding of new individuals/teams for some time before they are approved for review.
18
+
19
+ Once a critical mass of Diamond staff are used to this way of working, this ADR may be obsolete and should be replaced with a more open review system.
@@ -0,0 +1,56 @@
1
+ # Approved Reviewers
2
+
3
+ Code reviews are an important tool for ensuring both quality and collective responsibility for the codebase. Dodal PRs *must* be reviewed by a member of [the approved review team](https://github.com/orgs/DiamondLightSource/teams/bluesky-reviewers) before they are merged.
4
+
5
+ ## Review Standards and Practices
6
+
7
+ When reviewing you should ensure the code meets the [repository standards](../reference/standards.rst) and [device standards](../reference/device-standards.rst). Approved reviewers will adhere to the following, if they do not, junior reviewers and reviewees should feel empowered to hold them to account.
8
+
9
+ ### Questions and Comments
10
+
11
+ Questions and requests for clarification are encouraged. If you have comments for the reviewer you could add them with the following prefixes to be helpful:
12
+
13
+ - **Must**: This will negatively effect functionality if not implemented. The PR will not be merged until the comment is addressed to both the reviewer and developer's satisfaction.
14
+ - **Should**: This will improve quality/performance/etc. is but unlikely to affect functionality. If the developer doesn't want to do this they should write an explanation.
15
+ - **Could**: Similar to **Should** but without the requirement for explicit justification. The developer can dismiss on the grounds that velocity is the priority at the moment.
16
+ - **Nit**: Preference only, the developer can dismiss without any justification.
17
+
18
+ ### The Happy Path
19
+
20
+ If the review passes then the reviewer should approve the change and either the reviewer or PR author should merge it.
21
+
22
+ ### Requesting Changes
23
+
24
+ If the review fails the reviewer should request any changes (this issue is said to require rework)
25
+ A developer should ideally pick up any rework PRs before starting new work
26
+ When a developer is happy that a rework is complete they should press the re-request review button on the PR
27
+
28
+ ### Making Changes
29
+
30
+ Reviewers should feel free to make small changes to a PR as part of a review e.g. typos, poorly named variables, fixing a test. However, if code has been changed in this way they need then need to run it past another developer (ideally the original developer). This means that no code is merged into main without being looked at by at least 2 people, ensuring collective responsibility for the codebase.
31
+
32
+ ### Dismissing Stale Reviews
33
+
34
+ There may be times where one person requests changes on a PR, these changes are addressed and another person then approves it. In this case the PR still cannot be merged until the original review is dismissed. We're happy for people to dismiss stale reviews with the understanding that:
35
+
36
+ - The new reviewer should check that the must and should comments have been addressed
37
+ - If it's a big change it may still be worth the original reviewer looking again, if so they should make this clear to the original reviewer and the person that wrote the code
38
+
39
+ ## Joining the Review Team
40
+
41
+ At least two members of the review team from two different DLS teams *must* approve adding a new member, neither of them can be on the new member's DLS team. At least one of the approvers should ideally be a senior engineer but this will not always be possible.
42
+
43
+ In the event of a rejection the review team should provide concise and actionable feedback and set a date for re-consideration.
44
+
45
+ ### Criteria for New Members
46
+
47
+ New members should be regular contributors to dodal and should have been "shadow-reviewing" approved reviewers for a period of weeks or months before becoming approved. In both their contributions and reviews they should be consistently demonstrating the following *without prompting*:
48
+
49
+ - A good understanding of Python, including advanced langauge features such as [generators](https://wiki.python.org/moin/Generators), [coroutines](https://docs.python.org/3/library/asyncio-task.html), [comprehensions](https://www.geeksforgeeks.org/comprehensions-in-python/) and [pattern matching](https://peps.python.org/pep-0636/).
50
+ - A pythonic coding style, demonstrated by using appropriate class/variable names, aherence to [PEP 8](https://peps.python.org/pep-0008).
51
+ - Adherence to the review standards above as well as the [repository standards](../reference/standards.rst) and [device standards](../reference/device-standards.rst).
52
+ - Independent (i.e. not just to satisfy a reviewer) motivation to make sure all code in dodal is well-tested. Use of unit and system tests as appropriate. Clear effort made to keep test coverage high (>90%).
53
+ - Advanced understanding of bluesky and ophyd-async including concepts and best practices, such as how to appropriately split logic between devices/plans/callbacks.
54
+ - Humility in the use of reviewing as a tool in a way that balances the need to preserve quality with the need for progress. Appropriate use of the Must/Should/Could/Nit system documented above is helpful in showing this, as it gives the reviewer the opportunity to weight their comments in terms of project impact. They should also demonstrate similar humiliary as a reviewee.
55
+
56
+ Additionally, they should be regularly raising issues in the repository and demonstrating the ability to write well formed issues, with well defined acceptance criteria, that are understandable without large amounts of context.
@@ -101,6 +101,7 @@ reportMissingImports = false # Ignore missing stubs in imported modules
101
101
  asyncio_mode = "auto"
102
102
  markers = [
103
103
  "s03: marks tests as requiring the s03 simulator running (deselect with '-m \"not s03\"')",
104
+ "adsim: marks tests as requiring the containerised AreaDetector simulator running (deselect with '-m \"not adsim\"')",
104
105
  "skip_in_pycharm: marks test as not working in pycharm testrunner",
105
106
  ]
106
107
  addopts = """
@@ -150,7 +151,7 @@ allowlist_externals =
150
151
  sphinx-build
151
152
  sphinx-autobuild
152
153
  commands =
153
- tests: pytest -m 'not s03' --cov=dodal --cov-report term --cov-report xml:cov.xml {posargs}
154
+ tests: pytest -m 'not (s03 or adsim)' --cov=dodal --cov-report term --cov-report xml:cov.xml {posargs}
154
155
  type-checking: pyright src tests {posargs}
155
156
  pre-commit: pre-commit run --all-files --show-diff-on-failure {posargs}
156
157
  docs: sphinx-{posargs:build -E} -T docs build/html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.36.1a0
3
+ Version: 1.36.2
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
@@ -9,6 +9,7 @@ conftest.py
9
9
  pull_request_template.md
10
10
  pyproject.toml
11
11
  .devcontainer/devcontainer.json
12
+ .github/CODEOWNERS
12
13
  .github/CONTRIBUTING.md
13
14
  .github/dependabot.yml
14
15
  .github/ISSUE_TEMPLATE/issue_template.md
@@ -41,8 +42,10 @@ docs/_templates/autosummary/class.rst
41
42
  docs/_templates/autosummary/module.rst
42
43
  docs/assets/zocalo.png
43
44
  docs/explanations/decisions.md
45
+ docs/explanations/reviews.md
44
46
  docs/explanations/decisions/0001-record-architecture-decisions.md
45
47
  docs/explanations/decisions/0002-switched-to-python-copier-template.md
48
+ docs/explanations/decisions/0003-codeowners.md
46
49
  docs/explanations/decisions/0003-make-devices-factory.md
47
50
  docs/explanations/decisions/COPYME
48
51
  docs/how-to/build-docs.md
@@ -78,7 +81,6 @@ src/dls_dodal.egg-info/top_level.txt
78
81
  src/dodal/__init__.py
79
82
  src/dodal/__main__.py
80
83
  src/dodal/_version.py
81
- src/dodal/adsim.py
82
84
  src/dodal/cli.py
83
85
  src/dodal/log.py
84
86
  src/dodal/utils.py
@@ -86,6 +88,7 @@ src/dodal/beamline_specific_utils/__init__.py
86
88
  src/dodal/beamline_specific_utils/i03.py
87
89
  src/dodal/beamlines/README.md
88
90
  src/dodal/beamlines/__init__.py
91
+ src/dodal/beamlines/adsim.py
89
92
  src/dodal/beamlines/b01_1.py
90
93
  src/dodal/beamlines/i03.py
91
94
  src/dodal/beamlines/i04.py
@@ -155,10 +158,6 @@ src/dodal/devices/webcam.py
155
158
  src/dodal/devices/xbpm_feedback.py
156
159
  src/dodal/devices/zebra.py
157
160
  src/dodal/devices/zebra_controlled_shutter.py
158
- src/dodal/devices/areadetector/__init__.py
159
- src/dodal/devices/areadetector/adaravis.py
160
- src/dodal/devices/areadetector/adsim.py
161
- src/dodal/devices/areadetector/adutils.py
162
161
  src/dodal/devices/areadetector/plugins/CAM.py
163
162
  src/dodal/devices/areadetector/plugins/MJPG.py
164
163
  src/dodal/devices/detector/__init__.py
@@ -226,6 +225,7 @@ src/dodal/plans/__init__.py
226
225
  src/dodal/plans/scanspec.py
227
226
  src/dodal/plans/wrapped.py
228
227
  system_tests/__init__.py
228
+ system_tests/test_adsim.py
229
229
  system_tests/test_aperturescatterguard_system.py
230
230
  system_tests/test_eiger_system.py
231
231
  system_tests/test_gridscan_system.py
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.36.1a0'
16
- __version_tuple__ = version_tuple = (1, 36, 1)
15
+ __version__ = version = '1.36.2'
16
+ __version_tuple__ = version_tuple = (1, 36, 2)
@@ -16,6 +16,7 @@ _BEAMLINE_NAME_OVERRIDES = {
16
16
  "p47": "training_rig",
17
17
  "p48": "training_rig",
18
18
  "p49": "training_rig",
19
+ "t01": "adsim",
19
20
  }
20
21
 
21
22
 
@@ -0,0 +1,75 @@
1
+ from pathlib import Path
2
+
3
+ from ophyd_async.epics.adsimdetector import SimDetector
4
+
5
+ from dodal.common.beamlines.beamline_utils import (
6
+ device_factory,
7
+ get_path_provider,
8
+ set_path_provider,
9
+ )
10
+ from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
11
+ from dodal.common.visit import LocalDirectoryServiceClient, StaticVisitPathProvider
12
+ from dodal.devices.adsim import SimStage
13
+ from dodal.log import set_beamline as set_log_beamline
14
+ from dodal.utils import BeamlinePrefix
15
+
16
+ BL = "adsim"
17
+ PREFIX = BeamlinePrefix("t01")
18
+ set_log_beamline(BL)
19
+ set_utils_beamline(BL)
20
+
21
+ set_path_provider(
22
+ StaticVisitPathProvider(
23
+ BL,
24
+ Path("/tmp"),
25
+ client=LocalDirectoryServiceClient(),
26
+ )
27
+ )
28
+
29
+ """
30
+ Beamline module for use with the simulated AreaDetector and motors.
31
+ These devices are simulated at the EPICS level, enabling testing of
32
+ dodal and ophyd-async against what appear to be "real" signals.
33
+
34
+ Usage Example
35
+ -------------
36
+
37
+ Start the simulated beamline by following the epics-containers tutorial at
38
+ https://epics-containers.github.io/main/tutorials/launch_example.html
39
+ And ensure that the signals are visible:
40
+
41
+ ```sh
42
+ export EPICS_CA_ADDR_LIST=127.0.0.1
43
+ ```
44
+
45
+ How to use the devices in a plan:
46
+ In an ipython terminal run:
47
+
48
+ ```python
49
+ from bluesky.run_engine import RunEngine
50
+
51
+ from dodal.beamlines.adsim import det, stage
52
+ from dodal.plans import count
53
+
54
+ RE = RunEngine()
55
+ d = det(connect_immediately=True)
56
+ s = stage(connect_immediately=True)
57
+ RE(count([d], num=10))
58
+ ```
59
+
60
+ """
61
+
62
+
63
+ @device_factory()
64
+ def stage() -> SimStage:
65
+ return SimStage(f"{PREFIX.beamline_prefix}-MO-SIMC-01:")
66
+
67
+
68
+ @device_factory()
69
+ def det() -> SimDetector:
70
+ return SimDetector(
71
+ f"{PREFIX.beamline_prefix}-DI-CAM-01:",
72
+ path_provider=get_path_provider(),
73
+ drv_suffix="DET:",
74
+ hdf_suffix="HDF:",
75
+ )
@@ -1,5 +1,6 @@
1
1
  from dodal.common.beamlines.beamline_utils import BL, device_instantiation
2
2
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
3
+ from dodal.devices.attenuator import ReadOnlyAttenuator
3
4
  from dodal.devices.detector import DetectorParams
4
5
  from dodal.devices.eiger import EigerDetector
5
6
  from dodal.devices.hutch_shutter import HutchShutter
@@ -29,6 +30,21 @@ set_log_beamline(BL)
29
30
  set_utils_beamline(BL)
30
31
 
31
32
 
33
+ def attenuator(
34
+ wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
35
+ ) -> ReadOnlyAttenuator:
36
+ """Get a read-only attenuator device for i24, instantiate it if it hasn't already
37
+ been. If this is called when already instantiated in i24, it will return the
38
+ existing object."""
39
+ return device_instantiation(
40
+ ReadOnlyAttenuator,
41
+ "attenuator",
42
+ "-OP-ATTN-01:",
43
+ wait_for_connection,
44
+ fake_with_ophyd_sim,
45
+ )
46
+
47
+
32
48
  def aperture(
33
49
  wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
34
50
  ) -> Aperture:
@@ -0,0 +1,13 @@
1
+ from ophyd_async.core import StandardReadable
2
+ from ophyd_async.epics.motor import Motor
3
+
4
+
5
+ class SimStage(StandardReadable):
6
+ """Simulated Sample Stage for use with the containerised simulated beamline
7
+ https://github.com/epics-containers/example-services"""
8
+
9
+ def __init__(self, prefix: str, name: str = "sim"):
10
+ with self.add_children_as_readables():
11
+ self.x = Motor(prefix + "M1")
12
+ self.y = Motor(prefix + "M2")
13
+ super().__init__(name=name)
@@ -12,10 +12,3 @@ class Aperture(StandardReadable):
12
12
  self.medium = epics_signal_r(float, prefix + "Y:MEDIUM_CALC")
13
13
  self.large = epics_signal_r(float, prefix + "Y:LARGE_CALC")
14
14
  super().__init__(name)
15
-
16
- async def in_position(self):
17
- return (
18
- await self.small.get_value()
19
- or await self.medium.get_value()
20
- or await self.large.get_value()
21
- )
@@ -0,0 +1,243 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+
5
+ from bluesky.protocols import Movable
6
+ from ophyd_async.core import (
7
+ AsyncStatus,
8
+ StandardReadable,
9
+ StandardReadableFormat,
10
+ StrictEnum,
11
+ )
12
+ from pydantic import BaseModel, Field
13
+
14
+ from dodal.common.beamlines.beamline_parameters import GDABeamlineParameters
15
+ from dodal.common.signal_utils import create_hardware_backed_soft_signal
16
+ from dodal.devices.aperture import Aperture
17
+ from dodal.devices.scatterguard import Scatterguard
18
+
19
+
20
+ class InvalidApertureMove(Exception):
21
+ pass
22
+
23
+
24
+ class AperturePosition(BaseModel):
25
+ """
26
+ Represents one of the available positions for the Aperture-Scatterguard.
27
+ Attributes:
28
+ aperture_x: The x position of the aperture component in mm
29
+ aperture_y: The y position of the aperture component in mm
30
+ aperture_z: The z position of the aperture component in mm
31
+ scatterguard_x: The x position of the scatterguard component in mm
32
+ scatterguard_y: The y position of the scatterguard component in mm
33
+ radius: Radius of the selected aperture. When in the Robot Load position, the
34
+ radius is defined to be 0
35
+ """
36
+
37
+ aperture_x: float
38
+ aperture_y: float
39
+ aperture_z: float
40
+ scatterguard_x: float
41
+ scatterguard_y: float
42
+ radius: float = Field(json_schema_extra={"units": "µm"}, default=0.0)
43
+
44
+ @property
45
+ def values(self) -> tuple[float, float, float, float, float]:
46
+ return (
47
+ self.aperture_x,
48
+ self.aperture_y,
49
+ self.aperture_z,
50
+ self.scatterguard_x,
51
+ self.scatterguard_y,
52
+ )
53
+
54
+ @staticmethod
55
+ def tolerances_from_gda_params(
56
+ params: GDABeamlineParameters,
57
+ ) -> AperturePosition:
58
+ return AperturePosition(
59
+ aperture_x=params["miniap_x_tolerance"],
60
+ aperture_y=params["miniap_y_tolerance"],
61
+ aperture_z=params["miniap_z_tolerance"],
62
+ scatterguard_x=params["sg_x_tolerance"],
63
+ scatterguard_y=params["sg_y_tolerance"],
64
+ )
65
+
66
+ @staticmethod
67
+ def from_gda_params(
68
+ name: ApertureValue,
69
+ radius: float,
70
+ params: GDABeamlineParameters,
71
+ ) -> AperturePosition:
72
+ return AperturePosition(
73
+ aperture_x=params[f"miniap_x_{name.value}"],
74
+ aperture_y=params[f"miniap_y_{name.value}"],
75
+ aperture_z=params[f"miniap_z_{name.value}"],
76
+ scatterguard_x=params[f"sg_x_{name.value}"],
77
+ scatterguard_y=params[f"sg_y_{name.value}"],
78
+ radius=radius,
79
+ )
80
+
81
+
82
+ class ApertureValue(StrictEnum):
83
+ """Maps from a short usable name to the value name in the GDA Beamline parameters"""
84
+
85
+ ROBOT_LOAD = "ROBOT_LOAD"
86
+ SMALL = "SMALL_APERTURE"
87
+ MEDIUM = "MEDIUM_APERTURE"
88
+ LARGE = "LARGE_APERTURE"
89
+
90
+
91
+ def load_positions_from_beamline_parameters(
92
+ params: GDABeamlineParameters,
93
+ ) -> dict[ApertureValue, AperturePosition]:
94
+ return {
95
+ ApertureValue.ROBOT_LOAD: AperturePosition.from_gda_params(
96
+ ApertureValue.ROBOT_LOAD, 0, params
97
+ ),
98
+ ApertureValue.SMALL: AperturePosition.from_gda_params(
99
+ ApertureValue.SMALL, 20, params
100
+ ),
101
+ ApertureValue.MEDIUM: AperturePosition.from_gda_params(
102
+ ApertureValue.MEDIUM, 50, params
103
+ ),
104
+ ApertureValue.LARGE: AperturePosition.from_gda_params(
105
+ ApertureValue.LARGE, 100, params
106
+ ),
107
+ }
108
+
109
+
110
+ class ApertureScatterguard(StandardReadable, Movable):
111
+ def __init__(
112
+ self,
113
+ loaded_positions: dict[ApertureValue, AperturePosition],
114
+ tolerances: AperturePosition,
115
+ prefix: str = "",
116
+ name: str = "",
117
+ ) -> None:
118
+ self.aperture = Aperture(prefix + "-MO-MAPT-01:")
119
+ self.scatterguard = Scatterguard(prefix + "-MO-SCAT-01:")
120
+ self.radius = create_hardware_backed_soft_signal(
121
+ float, self._get_current_radius, units="µm"
122
+ )
123
+ self._loaded_positions = loaded_positions
124
+ self._tolerances = tolerances
125
+ self.add_readables(
126
+ [
127
+ self.aperture.x.user_readback,
128
+ self.aperture.y.user_readback,
129
+ self.aperture.z.user_readback,
130
+ self.scatterguard.x.user_readback,
131
+ self.scatterguard.y.user_readback,
132
+ self.radius,
133
+ ],
134
+ )
135
+ with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
136
+ self.selected_aperture = create_hardware_backed_soft_signal(
137
+ ApertureValue, self._get_current_aperture_position
138
+ )
139
+
140
+ super().__init__(name)
141
+
142
+ def get_position_from_gda_aperture_name(
143
+ self, gda_aperture_name: str
144
+ ) -> ApertureValue:
145
+ return ApertureValue(gda_aperture_name)
146
+
147
+ @AsyncStatus.wrap
148
+ async def set(self, value: ApertureValue):
149
+ position = self._loaded_positions[value]
150
+ await self._safe_move_within_datacollection_range(position, value)
151
+
152
+ @AsyncStatus.wrap
153
+ async def _set_raw_unsafe(self, position: AperturePosition):
154
+ """Accept the risks and move in an unsafe way. Collisions possible."""
155
+ aperture_x, aperture_y, aperture_z, scatterguard_x, scatterguard_y = (
156
+ position.values
157
+ )
158
+
159
+ await asyncio.gather(
160
+ self.aperture.x.set(aperture_x),
161
+ self.aperture.y.set(aperture_y),
162
+ self.aperture.z.set(aperture_z),
163
+ self.scatterguard.x.set(scatterguard_x),
164
+ self.scatterguard.y.set(scatterguard_y),
165
+ )
166
+
167
+ async def _get_current_aperture_position(self) -> ApertureValue:
168
+ """
169
+ Returns the current aperture position using readback values
170
+ for SMALL, MEDIUM, LARGE. ROBOT_LOAD position defined when
171
+ mini aperture y <= ROBOT_LOAD.location.aperture_y + tolerance.
172
+ If no position is found then raises InvalidApertureMove.
173
+ """
174
+ current_ap_y = await self.aperture.y.user_readback.get_value(cached=False)
175
+ robot_load_ap_y = self._loaded_positions[ApertureValue.ROBOT_LOAD].aperture_y
176
+ if await self.aperture.large.get_value(cached=False) == 1:
177
+ return ApertureValue.LARGE
178
+ elif await self.aperture.medium.get_value(cached=False) == 1:
179
+ return ApertureValue.MEDIUM
180
+ elif await self.aperture.small.get_value(cached=False) == 1:
181
+ return ApertureValue.SMALL
182
+ elif current_ap_y <= robot_load_ap_y + self._tolerances.aperture_y:
183
+ return ApertureValue.ROBOT_LOAD
184
+
185
+ raise InvalidApertureMove("Current aperture/scatterguard state unrecognised")
186
+
187
+ async def _get_current_radius(self) -> float:
188
+ current_value = await self._get_current_aperture_position()
189
+ return self._loaded_positions[current_value].radius
190
+
191
+ async def _safe_move_within_datacollection_range(
192
+ self, position: AperturePosition, value: ApertureValue
193
+ ):
194
+ """
195
+ Move the aperture and scatterguard combo safely to a new position.
196
+ See https://github.com/DiamondLightSource/hyperion/wiki/Aperture-Scatterguard-Collisions
197
+ for why this is required.
198
+ """
199
+ assert self._loaded_positions is not None
200
+
201
+ ap_z_in_position = await self.aperture.z.motor_done_move.get_value()
202
+ if not ap_z_in_position:
203
+ raise InvalidApertureMove(
204
+ "ApertureScatterguard z is still moving. Wait for it to finish "
205
+ "before triggering another move."
206
+ )
207
+
208
+ current_ap_z = await self.aperture.z.user_readback.get_value()
209
+ diff_on_z = abs(current_ap_z - position.aperture_z)
210
+ if diff_on_z > self._tolerances.aperture_z:
211
+ raise InvalidApertureMove(
212
+ "ApertureScatterguard safe move is not yet defined for positions "
213
+ "outside of LARGE, MEDIUM, SMALL, ROBOT_LOAD. "
214
+ f"Current aperture z ({current_ap_z}), outside of tolerance ({self._tolerances.aperture_z}) from target ({position.aperture_z})."
215
+ )
216
+
217
+ current_ap_y = await self.aperture.y.user_readback.get_value()
218
+
219
+ aperture_x, aperture_y, aperture_z, scatterguard_x, scatterguard_y = (
220
+ position.values
221
+ )
222
+
223
+ if position.aperture_y > current_ap_y:
224
+ await asyncio.gather(
225
+ self.scatterguard.x.set(scatterguard_x),
226
+ self.scatterguard.y.set(scatterguard_y),
227
+ )
228
+ await asyncio.gather(
229
+ self.aperture.x.set(aperture_x),
230
+ self.aperture.y.set(aperture_y),
231
+ self.aperture.z.set(aperture_z),
232
+ )
233
+ else:
234
+ await asyncio.gather(
235
+ self.aperture.x.set(aperture_x),
236
+ self.aperture.y.set(aperture_y),
237
+ self.aperture.z.set(aperture_z),
238
+ )
239
+
240
+ await asyncio.gather(
241
+ self.scatterguard.x.set(scatterguard_x),
242
+ self.scatterguard.y.set(scatterguard_y),
243
+ )
@@ -14,7 +14,20 @@ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal
14
14
  from dodal.log import LOGGER
15
15
 
16
16
 
17
- class Attenuator(StandardReadable, Movable):
17
+ class ReadOnlyAttenuator(StandardReadable):
18
+ """A read-only attenuator class with a minimum set of PVs for reading.
19
+
20
+ The actual_transmission will return a fractional transmission between 0-1.
21
+ """
22
+
23
+ def __init__(self, prefix: str, name: str = "") -> None:
24
+ with self.add_children_as_readables():
25
+ self.actual_transmission = epics_signal_r(float, prefix + "MATCH")
26
+
27
+ super().__init__(name)
28
+
29
+
30
+ class Attenuator(ReadOnlyAttenuator, Movable):
18
31
  """The attenuator will insert filters into the beam to reduce its transmission.
19
32
 
20
33
  This device should be set with:
@@ -42,10 +55,7 @@ class Attenuator(StandardReadable, Movable):
42
55
  self._use_current_energy = epics_signal_x(prefix + "E2WL:USECURRENTENERGY.PROC")
43
56
  self._change = epics_signal_x(prefix + "FANOUT")
44
57
 
45
- with self.add_children_as_readables():
46
- self.actual_transmission = epics_signal_r(float, prefix + "MATCH")
47
-
48
- super().__init__(name)
58
+ super().__init__(prefix, name)
49
59
 
50
60
  @AsyncStatus.wrap
51
61
  async def set(self, value: float):
@@ -1,3 +1,5 @@
1
+ from typing import TypedDict
2
+
1
3
  from ophyd_async.core import (
2
4
  AsyncStatus,
3
5
  Device,
@@ -36,6 +38,12 @@ class MirrorStripe(StrictEnum):
36
38
  PLATINUM = "Platinum"
37
39
 
38
40
 
41
+ class MirrorStripeConfiguration(TypedDict):
42
+ stripe: MirrorStripe
43
+ yaw_mrad: float
44
+ lat_mm: float
45
+
46
+
39
47
  class MirrorVoltageDemand(StrictEnum):
40
48
  N_A = "N/A"
41
49
  OK = "OK"
@@ -173,9 +181,10 @@ class FocusingMirrorWithStripes(FocusingMirror):
173
181
 
174
182
  super().__init__(prefix, name, *args, **kwargs)
175
183
 
176
- def energy_to_stripe(self, energy_kev) -> MirrorStripe:
184
+ def energy_to_stripe(self, energy_kev) -> MirrorStripeConfiguration:
185
+ """Return the stripe, yaw angle and lateral position for the specified energy"""
177
186
  # In future, this should be configurable per-mirror
178
187
  if energy_kev < 7:
179
- return MirrorStripe.BARE
188
+ return {"stripe": MirrorStripe.BARE, "yaw_mrad": 6.2, "lat_mm": 0.0}
180
189
  else:
181
- return MirrorStripe.RHODIUM
190
+ return {"stripe": MirrorStripe.RHODIUM, "yaw_mrad": 0.0, "lat_mm": 10.0}
@@ -61,7 +61,7 @@ class PinTipDetection(StandardReadable):
61
61
  self.triggered_bottom_edge, self._bottom_edge_setter = soft_signal_r_and_setter(
62
62
  Array1D[np.int32], name="triggered_bottom_edge"
63
63
  )
64
- self.array_data = epics_signal_r(Array1D[np.uint8], f"pva://{prefix}PVA:ARRAY")
64
+ self.array_data = epics_signal_r(np.ndarray, f"pva://{prefix}PVA:ARRAY")
65
65
 
66
66
  # Soft parameters for pin-tip detection.
67
67
  self.preprocess_operation = soft_signal_rw(int, 10, name="preprocess")
@@ -99,9 +99,7 @@ class PinTipDetection(StandardReadable):
99
99
  self._top_edge_setter(results.edge_top)
100
100
  self._bottom_edge_setter(results.edge_bottom)
101
101
 
102
- async def _get_tip_and_edge_data(
103
- self, array_data: Array1D[np.uint8]
104
- ) -> SampleLocation:
102
+ async def _get_tip_and_edge_data(self, array_data: np.ndarray) -> SampleLocation:
105
103
  """
106
104
  Gets the location of the pin tip and the top and bottom edges.
107
105
  """
@@ -5,6 +5,7 @@ from ophyd_async.core import AsyncStatus, StandardReadable
5
5
 
6
6
  from dodal.common.beamlines.beamline_parameters import get_beamline_parameters
7
7
 
8
+ from ..log import LOGGER
8
9
  from .dcm import DCM
9
10
  from .undulator import Undulator
10
11
 
@@ -59,3 +60,6 @@ class UndulatorDCM(StandardReadable, Movable):
59
60
  self.dcm.energy_in_kev.set(value, timeout=ENERGY_TIMEOUT_S),
60
61
  self.undulator.set(value),
61
62
  )
63
+ # DCM Perp pitch
64
+ LOGGER.info(f"Adjusting DCM offset to {self.dcm_fixed_offset_mm} mm")
65
+ await self.dcm.offset_in_mm.set(self.dcm_fixed_offset_mm)