dls-dodal 1.29.2__tar.gz → 1.29.4__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 (297) hide show
  1. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/PKG-INFO +3 -3
  2. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/pyproject.toml +2 -2
  3. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/PKG-INFO +3 -3
  4. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/SOURCES.txt +1 -1
  5. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/requires.txt +2 -2
  6. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/_version.py +2 -2
  7. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i24.py +14 -0
  8. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/areadetector/plugins/MJPG.py +0 -4
  9. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/attenuator.py +4 -4
  10. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/detector.py +3 -2
  11. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/eiger.py +12 -8
  12. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/eiger_odin.py +3 -3
  13. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/focusing_mirror.py +62 -62
  14. dls_dodal-1.29.4/src/dodal/devices/i24/dcm.py +42 -0
  15. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/oav_detector.py +1 -0
  16. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/pin_image_recognition/__init__.py +13 -11
  17. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/utils.py +1 -15
  18. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/robot.py +2 -1
  19. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/util/epics_util.py +2 -2
  20. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/webcam.py +1 -6
  21. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/utils.py +9 -4
  22. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/beamlines/test_beamline_utils.py +1 -1
  23. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/conftest.py +5 -12
  24. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/detector/test_detector.py +28 -12
  25. dls_dodal-1.29.4/tests/devices/unit_tests/test_focusing_mirror.py +271 -0
  26. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_oav.py +1 -6
  27. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_utils.py +2 -4
  28. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_webcam.py +4 -10
  29. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_xbpm_feedback.py +1 -1
  30. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_zebra.py +4 -5
  31. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/preprocessors/test_filesystem_metadata.py +2 -4
  32. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_utils.py +13 -0
  33. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/unit_tests/test_log.py +7 -6
  34. dls_dodal-1.29.2/tests/devices/unit_tests/oav/test_oav_utils.py +0 -15
  35. dls_dodal-1.29.2/tests/devices/unit_tests/test_focusing_mirror.py +0 -144
  36. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.devcontainer/devcontainer.json +0 -0
  37. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/CONTRIBUTING.rst +0 -0
  38. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/ISSUE_TEMPLATE/issue_template.md +0 -0
  39. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/actions/install_requirements/action.yml +0 -0
  40. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/dependabot.yml +0 -0
  41. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/pages/index.html +0 -0
  42. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/pages/make_switcher.py +0 -0
  43. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/workflows/code.yml +0 -0
  44. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/workflows/docs.yml +0 -0
  45. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/workflows/docs_clean.yml +0 -0
  46. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.github/workflows/linkcheck.yml +0 -0
  47. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.gitignore +0 -0
  48. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.pre-commit-config.yaml +0 -0
  49. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.vscode/extensions.json +0 -0
  50. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.vscode/launch.json +0 -0
  51. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.vscode/settings.json +0 -0
  52. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/.vscode/tasks.json +0 -0
  53. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/Dockerfile +0 -0
  54. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/LICENSE +0 -0
  55. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/README.rst +0 -0
  56. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/_templates/autosummary/class.rst +0 -0
  57. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/_templates/autosummary/module.rst +0 -0
  58. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/assets/zocalo.png +0 -0
  59. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/conf.py +0 -0
  60. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
  61. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
  62. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/explanations/decisions.rst +0 -0
  63. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/build-docs.rst +0 -0
  64. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/contribute.rst +0 -0
  65. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/create-beamline.rst +0 -0
  66. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/lint.rst +0 -0
  67. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/make-new-ophyd-async-device.rst +0 -0
  68. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/make-release.rst +0 -0
  69. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/move-code.rst +0 -0
  70. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/run-tests.rst +0 -0
  71. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/static-analysis.rst +0 -0
  72. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/update-tools.rst +0 -0
  73. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/how-to/zocalo.rst +0 -0
  74. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/index.rst +0 -0
  75. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/reference/device-standards.rst +0 -0
  76. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/reference/standards.rst +0 -0
  77. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/developer/tutorials/dev-install.rst +0 -0
  78. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/genindex.rst +0 -0
  79. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/images/dls-favicon.ico +0 -0
  80. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/images/dls-logo.svg +0 -0
  81. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/index.rst +0 -0
  82. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/user/explanations/docs-structure.rst +0 -0
  83. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/user/index.rst +0 -0
  84. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/user/reference/api.rst +0 -0
  85. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/user/tutorials/get_started.rst +0 -0
  86. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/docs/user/tutorials/installation.rst +0 -0
  87. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/pull_request_template.md +0 -0
  88. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/setup.cfg +0 -0
  89. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/__init__.py +0 -0
  90. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/dependency_links.txt +0 -0
  91. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/entry_points.txt +0 -0
  92. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dls_dodal.egg-info/top_level.txt +0 -0
  93. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/__init__.py +0 -0
  94. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/__main__.py +0 -0
  95. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/adsim.py +0 -0
  96. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamline_specific_utils/__init__.py +0 -0
  97. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamline_specific_utils/i03.py +0 -0
  98. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/README.md +0 -0
  99. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/__init__.py +0 -0
  100. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i03.py +0 -0
  101. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i04.py +0 -0
  102. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i04_1.py +0 -0
  103. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i20_1.py +0 -0
  104. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i22.py +0 -0
  105. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/i23.py +0 -0
  106. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/p38.py +0 -0
  107. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/beamlines/p45.py +0 -0
  108. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/cli.py +0 -0
  109. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/__init__.py +0 -0
  110. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/beamlines/__init__.py +0 -0
  111. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/beamlines/beamline_parameters.py +0 -0
  112. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/beamlines/beamline_utils.py +0 -0
  113. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/beamlines/device_helpers.py +0 -0
  114. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/coordination.py +0 -0
  115. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/maths.py +0 -0
  116. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/types.py +0 -0
  117. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/udc_directory_provider.py +0 -0
  118. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/common/visit.py +0 -0
  119. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/CTAB.py +0 -0
  120. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/__init__.py +0 -0
  121. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/adsim.py +0 -0
  122. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/aperture.py +0 -0
  123. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/aperturescatterguard.py +0 -0
  124. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/areadetector/__init__.py +0 -0
  125. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/areadetector/adaravis.py +0 -0
  126. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/areadetector/adsim.py +0 -0
  127. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/areadetector/adutils.py +0 -0
  128. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/backlight.py +0 -0
  129. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/beamstop.py +0 -0
  130. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/cryostream.py +0 -0
  131. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/dcm.py +0 -0
  132. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/__init__.py +0 -0
  133. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/det_dim_constants.py +0 -0
  134. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/det_dist_to_beam_converter.py +0 -0
  135. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/det_resolution.py +0 -0
  136. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/detector/detector_motion.py +0 -0
  137. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/fast_grid_scan.py +0 -0
  138. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/fluorescence_detector_motion.py +0 -0
  139. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/flux.py +0 -0
  140. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/hutch_shutter.py +0 -0
  141. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i03/__init__.py +0 -0
  142. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i04/transfocator.py +0 -0
  143. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i20_1/__init__.py +0 -0
  144. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i22/dcm.py +0 -0
  145. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i22/fswitch.py +0 -0
  146. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i22/nxsas.py +0 -0
  147. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/I24_detector_motion.py +0 -0
  148. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/__init__.py +0 -0
  149. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/aperture.py +0 -0
  150. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/beamstop.py +0 -0
  151. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/dual_backlight.py +0 -0
  152. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/i24_vgonio.py +0 -0
  153. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/i24/pmac.py +0 -0
  154. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/ipin.py +0 -0
  155. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/linkam3.py +0 -0
  156. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/logging_ophyd_device.py +0 -0
  157. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/motors.py +0 -0
  158. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/__init__.py +0 -0
  159. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/grid_overlay.py +0 -0
  160. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/microns_for_zoom_levels.json +0 -0
  161. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/oav_calculations.py +0 -0
  162. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/oav_errors.py +0 -0
  163. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/oav_parameters.py +0 -0
  164. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/pin_image_recognition/manual_test.py +0 -0
  165. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/oav/pin_image_recognition/utils.py +0 -0
  166. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/p45.py +0 -0
  167. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/qbpm1.py +0 -0
  168. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/s4_slit_gaps.py +0 -0
  169. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/scatterguard.py +0 -0
  170. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/scintillator.py +0 -0
  171. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/slits.py +0 -0
  172. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/smargon.py +0 -0
  173. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/status.py +0 -0
  174. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/synchrotron.py +0 -0
  175. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/tetramm.py +0 -0
  176. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/thawer.py +0 -0
  177. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/turbo_slit.py +0 -0
  178. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/undulator.py +0 -0
  179. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/undulator_dcm.py +0 -0
  180. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/util/__init__.py +0 -0
  181. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/util/adjuster_plans.py +0 -0
  182. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/util/lookup_tables.py +0 -0
  183. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/util/motor_utils.py +0 -0
  184. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/xbpm_feedback.py +0 -0
  185. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/xspress3/xspress3.py +0 -0
  186. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/xspress3/xspress3_channel.py +0 -0
  187. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/zebra.py +0 -0
  188. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/zebra_controlled_shutter.py +0 -0
  189. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/zocalo/__init__.py +0 -0
  190. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/zocalo/zocalo_interaction.py +0 -0
  191. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/devices/zocalo/zocalo_results.py +0 -0
  192. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/log.py +0 -0
  193. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/parameters/experiment_parameter_base.py +0 -0
  194. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/plans/check_topup.py +0 -0
  195. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/src/dodal/plans/data_session_metadata.py +0 -0
  196. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/__init__.py +0 -0
  197. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/beamlines/__init__.py +0 -0
  198. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/beamlines/unit_tests/__init__.py +0 -0
  199. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/beamlines/unit_tests/test_i03.py +0 -0
  200. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/beamlines/unit_tests/test_i24.py +0 -0
  201. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/beamlines/unit_tests/test_mapping.py +0 -0
  202. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/__init__.py +0 -0
  203. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/beamlines/__init__.py +0 -0
  204. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/beamlines/test_beamline_parameters.py +0 -0
  205. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/beamlines/test_device_helpers.py +0 -0
  206. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/beamlines/test_device_instantiation.py +0 -0
  207. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/test_coordination.py +0 -0
  208. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/test_maths.py +0 -0
  209. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/common/test_udc_directory_provider.py +0 -0
  210. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/__init__.py +0 -0
  211. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/i04/__init__.py +0 -0
  212. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/i04/test_transfocator.py +0 -0
  213. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/i22/test_dcm.py +0 -0
  214. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/i22/test_fswitch.py +0 -0
  215. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/i22/test_metadataholder.py +0 -0
  216. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/__init__.py +0 -0
  217. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_aperturescatterguard_system.py +0 -0
  218. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_eiger_system.py +0 -0
  219. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_gridscan_system.py +0 -0
  220. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_oav_system.py +0 -0
  221. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_slit_gaps_system.py +0 -0
  222. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_smargon_system.py +0 -0
  223. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_synchrotron_system.py +0 -0
  224. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_undulator_system.py +0 -0
  225. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_zebra_system.py +0 -0
  226. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/system_tests/test_zocalo_results.py +0 -0
  227. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/__init__.py +0 -0
  228. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/areadetector/plugins/test_MJPG.py +0 -0
  229. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/conftest.py +0 -0
  230. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/detector/test_det_dim_constants.py +0 -0
  231. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/detector/test_det_resolution.py +0 -0
  232. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/i24/__init__.py +0 -0
  233. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/i24/test_dual_backlight.py +0 -0
  234. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/i24/test_pmac.py +0 -0
  235. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/oav/__init__.py +0 -0
  236. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect.py +0 -0
  237. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect_utils.py +0 -0
  238. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/oav/test_oav.py +0 -0
  239. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/oav/test_oav_parameters.py +0 -0
  240. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_OAVCentring.json +0 -0
  241. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_aperture.py +0 -0
  242. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_aperture_scatterguard.py +0 -0
  243. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_attenuator.py +0 -0
  244. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_backlight.py +0 -0
  245. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_bart_robot.py +0 -0
  246. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_beam_converter.py +0 -0
  247. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_beamline_undulator_to_gap_lookup_table.txt +0 -0
  248. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_daq_configuration/domain/beamlineParameters +0 -0
  249. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Pitch_converter.txt +0 -0
  250. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_daq_configuration/lookup/BeamLineEnergy_DCM_Roll_converter.txt +0 -0
  251. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_dcm.py +0 -0
  252. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_display.configuration +0 -0
  253. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_eiger.py +0 -0
  254. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_grid_overlay.py +0 -0
  255. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_gridscan.py +0 -0
  256. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_hutch_shutter.py +0 -0
  257. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_jCameraManZoomLevels.xml +0 -0
  258. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_linkam3.py +0 -0
  259. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_lookup_table.txt +0 -0
  260. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_lookup_table_2.txt +0 -0
  261. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_odin.py +0 -0
  262. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_shutter.py +0 -0
  263. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_slits.py +0 -0
  264. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_smargon.py +0 -0
  265. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_status.py +0 -0
  266. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_synchrotron.py +0 -0
  267. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_tetramm.py +0 -0
  268. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_thawer.py +0 -0
  269. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_undulator.py +0 -0
  270. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_undulator_dcm.py +0 -0
  271. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_xspress3.py +0 -0
  272. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_zocalo_interaction.py +0 -0
  273. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/test_zocalo_results.py +0 -0
  274. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/util/__init__.py +0 -0
  275. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/util/test_adjuster_plans.py +0 -0
  276. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/util/test_beamline_specific_utils.py +0 -0
  277. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/devices/unit_tests/util/test_lookup_tables.py +0 -0
  278. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline.py +0 -0
  279. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline_all_devices_raise_exception.py +0 -0
  280. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline_dependencies.py +0 -0
  281. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline_disordered_dependencies.py +0 -0
  282. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline_misbehaving_builtins.py +0 -0
  283. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_beamline_some_devices_working.py +0 -0
  284. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_zocalo/README.rst +0 -0
  285. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_zocalo/__init__.py +0 -0
  286. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_zocalo/__main__.py +0 -0
  287. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/fake_zocalo/dls_start_fake_zocalo.sh +0 -0
  288. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/plans/test_topup_plan.py +0 -0
  289. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/bad_beamlineParameters +0 -0
  290. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/i04_beamlineParameters +0 -0
  291. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/test_beamline_dcm_roll_converter.txt +0 -0
  292. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/test_beamline_dcm_roll_converter_non_monotonic.txt +0 -0
  293. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/test_beamline_dcm_roll_converter_reversed.txt +0 -0
  294. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/test_beamline_parameters.txt +0 -0
  295. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/test_data/test_det_dist_converter.txt +0 -0
  296. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/unit_tests/__init__.py +0 -0
  297. {dls_dodal-1.29.2 → dls_dodal-1.29.4}/tests/unit_tests/test_cli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.29.2
3
+ Version: 1.29.4
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
@@ -215,12 +215,12 @@ Description-Content-Type: text/x-rst
215
215
  License-File: LICENSE
216
216
  Requires-Dist: click
217
217
  Requires-Dist: ophyd
218
- Requires-Dist: ophyd-async>=0.3.1
218
+ Requires-Dist: ophyd-async<0.4.0
219
219
  Requires-Dist: bluesky
220
220
  Requires-Dist: pyepics
221
221
  Requires-Dist: dataclasses-json
222
222
  Requires-Dist: pillow
223
- Requires-Dist: zocalo
223
+ Requires-Dist: zocalo>=0.32.0
224
224
  Requires-Dist: requests
225
225
  Requires-Dist: graypy
226
226
  Requires-Dist: pydantic
@@ -14,12 +14,12 @@ description = "Ophyd devices and other utils that could be used across DLS beaml
14
14
  dependencies = [
15
15
  "click",
16
16
  "ophyd",
17
- "ophyd-async>=0.3.1",
17
+ "ophyd-async<0.4.0", # Need to pin to <0.4.0 as this requires pydantic>2.0 see https://github.com/DiamondLightSource/dodal/issues/679
18
18
  "bluesky",
19
19
  "pyepics",
20
20
  "dataclasses-json",
21
21
  "pillow",
22
- "zocalo",
22
+ "zocalo>=0.32.0",
23
23
  "requests",
24
24
  "graypy",
25
25
  "pydantic",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dls-dodal
3
- Version: 1.29.2
3
+ Version: 1.29.4
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
@@ -215,12 +215,12 @@ Description-Content-Type: text/x-rst
215
215
  License-File: LICENSE
216
216
  Requires-Dist: click
217
217
  Requires-Dist: ophyd
218
- Requires-Dist: ophyd-async>=0.3.1
218
+ Requires-Dist: ophyd-async<0.4.0
219
219
  Requires-Dist: bluesky
220
220
  Requires-Dist: pyepics
221
221
  Requires-Dist: dataclasses-json
222
222
  Requires-Dist: pillow
223
- Requires-Dist: zocalo
223
+ Requires-Dist: zocalo>=0.32.0
224
224
  Requires-Dist: requests
225
225
  Requires-Dist: graypy
226
226
  Requires-Dist: pydantic
@@ -149,6 +149,7 @@ src/dodal/devices/i24/I24_detector_motion.py
149
149
  src/dodal/devices/i24/__init__.py
150
150
  src/dodal/devices/i24/aperture.py
151
151
  src/dodal/devices/i24/beamstop.py
152
+ src/dodal/devices/i24/dcm.py
152
153
  src/dodal/devices/i24/dual_backlight.py
153
154
  src/dodal/devices/i24/i24_vgonio.py
154
155
  src/dodal/devices/i24/pmac.py
@@ -265,7 +266,6 @@ tests/devices/unit_tests/i24/test_pmac.py
265
266
  tests/devices/unit_tests/oav/__init__.py
266
267
  tests/devices/unit_tests/oav/test_oav.py
267
268
  tests/devices/unit_tests/oav/test_oav_parameters.py
268
- tests/devices/unit_tests/oav/test_oav_utils.py
269
269
  tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect.py
270
270
  tests/devices/unit_tests/oav/image_recognition/test_pin_tip_detect_utils.py
271
271
  tests/devices/unit_tests/test_daq_configuration/domain/beamlineParameters
@@ -1,11 +1,11 @@
1
1
  click
2
2
  ophyd
3
- ophyd-async>=0.3.1
3
+ ophyd-async<0.4.0
4
4
  bluesky
5
5
  pyepics
6
6
  dataclasses-json
7
7
  pillow
8
- zocalo
8
+ zocalo>=0.32.0
9
9
  requests
10
10
  graypy
11
11
  pydantic
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.29.2'
16
- __version_tuple__ = version_tuple = (1, 29, 2)
15
+ __version__ = version = '1.29.4'
16
+ __version_tuple__ = version_tuple = (1, 29, 4)
@@ -5,6 +5,7 @@ from dodal.devices.eiger import EigerDetector
5
5
  from dodal.devices.hutch_shutter import HutchShutter
6
6
  from dodal.devices.i24.aperture import Aperture
7
7
  from dodal.devices.i24.beamstop import Beamstop
8
+ from dodal.devices.i24.dcm import DCM
8
9
  from dodal.devices.i24.dual_backlight import DualBacklight
9
10
  from dodal.devices.i24.I24_detector_motion import DetectorMotion
10
11
  from dodal.devices.i24.i24_vgonio import VGonio
@@ -82,6 +83,19 @@ def detector_motion(
82
83
  )
83
84
 
84
85
 
86
+ def dcm(wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False) -> DCM:
87
+ """Get the i24 DCM device, instantiate it if it hasn't already been.
88
+ If this is called when already instantiated in i24, it will return the existing object.
89
+ """
90
+ return device_instantiation(
91
+ device_factory=DCM,
92
+ name="dcm",
93
+ prefix="",
94
+ wait=wait_for_connection,
95
+ fake=fake_with_ophyd_sim,
96
+ )
97
+
98
+
85
99
  @skip_device(lambda: BL == "s24")
86
100
  def eiger(
87
101
  wait_for_connection: bool = True,
@@ -8,7 +8,6 @@ from ophyd import Component, Device, DeviceStatus, EpicsSignal, EpicsSignalRO, S
8
8
  from PIL import Image, ImageDraw
9
9
 
10
10
  from dodal.devices.oav.oav_parameters import OAVConfigParams
11
- from dodal.devices.oav.utils import save_thumbnail
12
11
  from dodal.log import LOGGER
13
12
 
14
13
 
@@ -50,9 +49,6 @@ class MJPG(Device, ABC):
50
49
 
51
50
  LOGGER.info(f"Saving image to {path}")
52
51
  image.save(path)
53
-
54
- save_thumbnail(Path(path), image)
55
-
56
52
  self.last_saved_path.put(path)
57
53
 
58
54
  def trigger(self):
@@ -48,7 +48,7 @@ class Attenuator(StandardReadable, Movable):
48
48
  super().__init__(name)
49
49
 
50
50
  @AsyncStatus.wrap
51
- async def set(self, transmission: float):
51
+ async def set(self, value: float):
52
52
  """Set the transmission to the fractional (0-1) value given.
53
53
 
54
54
  The attenuator IOC will then insert filters to reach the desired transmission for
@@ -58,8 +58,8 @@ class Attenuator(StandardReadable, Movable):
58
58
 
59
59
  LOGGER.debug("Using current energy ")
60
60
  await self._use_current_energy.trigger()
61
- LOGGER.info(f"Setting desired transmission to {transmission}")
62
- await self._desired_transmission.set(transmission)
61
+ LOGGER.info(f"Setting desired transmission to {value}")
62
+ await self._desired_transmission.set(value)
63
63
  LOGGER.debug("Sending change filter command")
64
64
  await self._change.trigger()
65
65
 
@@ -67,7 +67,7 @@ class Attenuator(StandardReadable, Movable):
67
67
  *[
68
68
  wait_for_value(
69
69
  self._filters_in_position[i],
70
- await self._calculated_filter_states[i].get_value(),
70
+ bool(await self._calculated_filter_states[i].get_value()),
71
71
  None,
72
72
  )
73
73
  for i in range(16)
@@ -54,13 +54,14 @@ class DetectorParams(BaseModel):
54
54
  DetectorSizeConstants: lambda d: d.det_type_string,
55
55
  }
56
56
 
57
- @root_validator(pre=True, skip_on_failure=True) # type: ignore # should be replaced with model_validator once move to pydantic 2 is complete
57
+ # should be replaced with model_validator once move to pydantic 2 is complete
58
+ @root_validator(pre=True)
58
59
  def create_beamxy_and_runnumber(cls, values: dict[str, Any]) -> dict[str, Any]:
59
60
  values["beam_xy_converter"] = DetectorDistanceToBeamXYConverter(
60
61
  values["det_dist_to_beam_converter_path"]
61
62
  )
62
63
  if values.get("run_number") is None:
63
- values["run_number"] = get_run_number(values["directory"])
64
+ values["run_number"] = get_run_number(values["directory"], values["prefix"])
64
65
  return values
65
66
 
66
67
  @validator("detector_size_constants", pre=True)
@@ -2,7 +2,7 @@ from enum import Enum
2
2
 
3
3
  from ophyd import Component, Device, EpicsSignalRO, Signal
4
4
  from ophyd.areadetector.cam import EigerDetectorCam
5
- from ophyd.status import AndStatus, Status, SubscriptionStatus
5
+ from ophyd.status import AndStatus, Status, StatusBase
6
6
 
7
7
  from dodal.devices.detector import DetectorParams, TriggerMode
8
8
  from dodal.devices.eiger_odin import EigerOdin
@@ -27,6 +27,7 @@ class InternalEigerTriggerMode(Enum):
27
27
  class EigerDetector(Device):
28
28
  class ArmingSignal(Signal):
29
29
  def set(self, value, *, timeout=None, settle_time=None, **kwargs):
30
+ assert isinstance(self.parent, EigerDetector)
30
31
  return self.parent.async_stage()
31
32
 
32
33
  do_arm = Component(ArmingSignal)
@@ -38,10 +39,12 @@ class EigerDetector(Device):
38
39
 
39
40
  STALE_PARAMS_TIMEOUT = 60
40
41
  GENERAL_STATUS_TIMEOUT = 10
42
+ # Long timeout for meta file to compensate for filesystem issues
43
+ META_FILE_READY_TIMEOUT = 30
41
44
  ALL_FRAMES_TIMEOUT = 120
42
45
  ARMING_TIMEOUT = 60
43
46
 
44
- filewriters_finished: SubscriptionStatus
47
+ filewriters_finished: StatusBase
45
48
 
46
49
  detector_params: DetectorParams | None = None
47
50
 
@@ -155,7 +158,7 @@ class EigerDetector(Device):
155
158
  def enable_roi_mode(self):
156
159
  return self.change_roi_mode(True)
157
160
 
158
- def change_roi_mode(self, enable: bool) -> Status:
161
+ def change_roi_mode(self, enable: bool) -> StatusBase:
159
162
  assert self.detector_params is not None
160
163
  detector_dimensions = (
161
164
  self.detector_params.detector_size_constants.roi_size_pixels
@@ -206,7 +209,7 @@ class EigerDetector(Device):
206
209
  )
207
210
  return status
208
211
 
209
- def set_odin_pvs(self) -> Status:
212
+ def set_odin_pvs(self) -> StatusBase:
210
213
  assert self.detector_params is not None
211
214
  file_prefix = self.detector_params.full_filename
212
215
  status = self.odin.file_writer.file_path.set(
@@ -264,7 +267,7 @@ class EigerDetector(Device):
264
267
  status.set_finished()
265
268
  return status
266
269
 
267
- def set_num_triggers_and_captures(self) -> Status:
270
+ def set_num_triggers_and_captures(self) -> StatusBase:
268
271
  """Sets the number of triggers and the number of images for the Eiger to capture
269
272
  during the datacollection. The number of images is the number of images per
270
273
  trigger.
@@ -295,7 +298,7 @@ class EigerDetector(Device):
295
298
 
296
299
  return status
297
300
 
298
- def _wait_for_odin_status(self) -> Status:
301
+ def _wait_for_odin_status(self) -> StatusBase:
299
302
  self.forward_bit_depth_to_filewriter()
300
303
  await_value(self.odin.meta.active, 1).wait(self.GENERAL_STATUS_TIMEOUT)
301
304
 
@@ -304,11 +307,11 @@ class EigerDetector(Device):
304
307
  )
305
308
  LOGGER.info("Eiger staging: awaiting odin metadata")
306
309
  status &= await_value(
307
- self.odin.meta.ready, 1, timeout=self.GENERAL_STATUS_TIMEOUT
310
+ self.odin.meta.ready, 1, timeout=self.META_FILE_READY_TIMEOUT
308
311
  )
309
312
  return status
310
313
 
311
- def _wait_fan_ready(self) -> Status:
314
+ def _wait_fan_ready(self) -> StatusBase:
312
315
  self.filewriters_finished = self.odin.create_finished_status()
313
316
  LOGGER.info("Eiger staging: awaiting odin fan ready")
314
317
  return await_value(self.odin.fan.ready, 1, self.GENERAL_STATUS_TIMEOUT)
@@ -332,6 +335,7 @@ class EigerDetector(Device):
332
335
 
333
336
  def do_arming_chain(self) -> Status:
334
337
  functions_to_do_arm = []
338
+ assert self.detector_params
335
339
  detector_params: DetectorParams = self.detector_params
336
340
  if detector_params.use_roi_mode:
337
341
  functions_to_do_arm.append(self.enable_roi_mode)
@@ -3,7 +3,7 @@ from typing import List, Tuple
3
3
  from ophyd import Component, Device, EpicsSignal, EpicsSignalRO, EpicsSignalWithRBV
4
4
  from ophyd.areadetector.plugins import HDF5Plugin_V22
5
5
  from ophyd.sim import NullStatus
6
- from ophyd.status import Status, SubscriptionStatus
6
+ from ophyd.status import StatusBase
7
7
 
8
8
  from dodal.devices.status import await_value
9
9
 
@@ -120,7 +120,7 @@ class EigerOdin(Device):
120
120
  meta = Component(OdinMetaListener, "OD:META:")
121
121
  nodes = Component(OdinNodesStatus, "")
122
122
 
123
- def create_finished_status(self) -> SubscriptionStatus:
123
+ def create_finished_status(self) -> StatusBase:
124
124
  writing_finished = await_value(self.meta.ready, 0)
125
125
  for node_pv in self.nodes.nodes:
126
126
  writing_finished &= await_value(node_pv.writing, 0)
@@ -157,7 +157,7 @@ class EigerOdin(Device):
157
157
 
158
158
  return not errors, "\n".join(errors)
159
159
 
160
- def stop(self) -> Status:
160
+ def stop(self) -> StatusBase:
161
161
  """Stop odin manually"""
162
162
  status = self.file_writer.capture.set(0)
163
163
  status &= self.meta.stop_writing.set(1)
@@ -1,12 +1,16 @@
1
- from enum import Enum, IntEnum
2
- from typing import Any
3
-
4
- from ophyd import Component, Device, EpicsSignal
5
- from ophyd.status import Status, StatusBase
6
- from ophyd_async.core import StandardReadable
1
+ from enum import Enum
2
+
3
+ from ophyd_async.core import (
4
+ AsyncStatus,
5
+ Device,
6
+ DeviceVector,
7
+ StandardReadable,
8
+ observe_value,
9
+ )
7
10
  from ophyd_async.core.signal import soft_signal_r_and_setter
8
11
  from ophyd_async.epics.motion import Motor
9
12
  from ophyd_async.epics.signal import (
13
+ epics_signal_r,
10
14
  epics_signal_rw,
11
15
  epics_signal_x,
12
16
  )
@@ -32,11 +36,11 @@ class MirrorStripe(str, Enum):
32
36
  PLATINUM = "Platinum"
33
37
 
34
38
 
35
- class MirrorVoltageDemand(IntEnum):
36
- N_A = 0
37
- OK = 1
38
- FAIL = 2
39
- SLEW = 3
39
+ class MirrorVoltageDemand(str, Enum):
40
+ N_A = "N/A"
41
+ OK = "OK"
42
+ FAIL = "FAIL"
43
+ SLEW = "SLEW"
40
44
 
41
45
 
42
46
  class MirrorVoltageDevice(Device):
@@ -44,14 +48,16 @@ class MirrorVoltageDevice(Device):
44
48
  the demanded voltage setpoint is accepted, without blocking the caller as this process can take significant time.
45
49
  """
46
50
 
47
- _actual_v: EpicsSignal = Component(EpicsSignal, "R")
48
- _setpoint_v: EpicsSignal = Component(EpicsSignal, "D")
49
- _demand_accepted: EpicsSignal = Component(EpicsSignal, "DSEV")
51
+ def __init__(self, name: str = "", prefix: str = ""):
52
+ self._actual_v = epics_signal_r(int, prefix + "R")
53
+ self._setpoint_v = epics_signal_rw(int, prefix + "D")
54
+ self._demand_accepted = epics_signal_r(MirrorVoltageDemand, prefix + "DSEV")
55
+ super().__init__(name=name)
50
56
 
51
- def set(self, value, *args, **kwargs) -> StatusBase:
57
+ @AsyncStatus.wrap
58
+ async def set(self, value, *args, **kwargs):
52
59
  """Combine the following operations into a single set:
53
60
  1. apply the value to the setpoint PV
54
- 2. Return to the caller with a Status future
55
61
  3. Wait until demand is accepted
56
62
  4. When either demand is accepted or DEFAULT_SETTLE_TIME expires, signal the result on the Status
57
63
  """
@@ -59,66 +65,60 @@ class MirrorVoltageDevice(Device):
59
65
  setpoint_v = self._setpoint_v
60
66
  demand_accepted = self._demand_accepted
61
67
 
62
- if demand_accepted.get() != MirrorVoltageDemand.OK:
68
+ if await demand_accepted.get_value() != MirrorVoltageDemand.OK:
63
69
  raise AssertionError(
64
70
  f"Attempted to set {setpoint_v.name} when demand is not accepted."
65
71
  )
66
72
 
67
- if setpoint_v.get() == value:
73
+ if await setpoint_v.get_value() == value:
68
74
  LOGGER.debug(f"{setpoint_v.name} already at {value} - skipping set")
69
- return Status(success=True, done=True)
75
+ return
70
76
 
71
77
  LOGGER.debug(f"setting {setpoint_v.name} to {value}")
72
- demand_accepted_status = Status(self, DEFAULT_SETTLE_TIME_S)
73
-
74
- subscription: dict[str, Any] = {"handle": None}
75
78
 
76
- def demand_check_callback(old_value, value, **kwargs):
77
- LOGGER.debug(f"Got event old={old_value} new={value} for {setpoint_v.name}")
78
- if old_value != MirrorVoltageDemand.OK and value == MirrorVoltageDemand.OK:
79
- LOGGER.debug(f"Demand accepted for {setpoint_v.name}")
80
- subs_handle = subscription.pop("handle", None)
81
- if subs_handle is None:
82
- raise AssertionError("Demand accepted before set attempted")
83
- demand_accepted.unsubscribe(subs_handle)
84
-
85
- demand_accepted_status.set_finished()
86
- # else timeout handled by parent demand_accepted_status
79
+ # Register an observer up front to ensure we don't miss events after we
80
+ # perform the set
81
+ demand_accepted_iterator = observe_value(
82
+ demand_accepted, timeout=DEFAULT_SETTLE_TIME_S
83
+ )
84
+ # discard the current value (OK) so we can await a subsequent change
85
+ await anext(demand_accepted_iterator)
86
+ await setpoint_v.set(value)
87
+
88
+ # The set should always change to SLEW regardless of whether we are
89
+ # already at the set point, then change back to OK/FAIL depending on
90
+ # success
91
+ accepted_value = await anext(demand_accepted_iterator)
92
+ assert accepted_value == MirrorVoltageDemand.SLEW
93
+ LOGGER.debug(
94
+ f"Demand not accepted for {setpoint_v.name}, waiting for acceptance..."
95
+ )
96
+ while MirrorVoltageDemand.SLEW == (
97
+ accepted_value := await anext(demand_accepted_iterator)
98
+ ):
99
+ pass
87
100
 
88
- subscription["handle"] = demand_accepted.subscribe(demand_check_callback)
89
- setpoint_status = setpoint_v.set(value)
90
- status = setpoint_status & demand_accepted_status
91
- return status
101
+ if accepted_value != MirrorVoltageDemand.OK:
102
+ raise AssertionError(
103
+ f"Voltage slew failed for {setpoint_v.name}, new state={accepted_value}"
104
+ )
92
105
 
93
106
 
94
- class VFMMirrorVoltages(Device):
95
- def __init__(self, *args, daq_configuration_path: str, **kwargs):
96
- super().__init__(*args, **kwargs)
107
+ class VFMMirrorVoltages(StandardReadable):
108
+ def __init__(
109
+ self, name: str, prefix: str, *args, daq_configuration_path: str, **kwargs
110
+ ):
97
111
  self.voltage_lookup_table_path = (
98
112
  daq_configuration_path + "/json/mirrorFocus.json"
99
113
  )
100
-
101
- _channel14_voltage_device = Component(MirrorVoltageDevice, "BM:V14")
102
- _channel15_voltage_device = Component(MirrorVoltageDevice, "BM:V15")
103
- _channel16_voltage_device = Component(MirrorVoltageDevice, "BM:V16")
104
- _channel17_voltage_device = Component(MirrorVoltageDevice, "BM:V17")
105
- _channel18_voltage_device = Component(MirrorVoltageDevice, "BM:V18")
106
- _channel19_voltage_device = Component(MirrorVoltageDevice, "BM:V19")
107
- _channel20_voltage_device = Component(MirrorVoltageDevice, "BM:V20")
108
- _channel21_voltage_device = Component(MirrorVoltageDevice, "BM:V21")
109
-
110
- @property
111
- def voltage_channels(self) -> list[MirrorVoltageDevice]:
112
- return [
113
- self._channel14_voltage_device,
114
- self._channel15_voltage_device,
115
- self._channel16_voltage_device,
116
- self._channel17_voltage_device,
117
- self._channel18_voltage_device,
118
- self._channel19_voltage_device,
119
- self._channel20_voltage_device,
120
- self._channel21_voltage_device,
121
- ]
114
+ with self.add_children_as_readables():
115
+ self.voltage_channels = DeviceVector(
116
+ {
117
+ i - 14: MirrorVoltageDevice(prefix=f"{prefix}BM:V{i}")
118
+ for i in range(14, 22)
119
+ }
120
+ )
121
+ super().__init__(*args, name=name, **kwargs)
122
122
 
123
123
 
124
124
  class FocusingMirror(StandardReadable):
@@ -0,0 +1,42 @@
1
+ from ophyd_async.core import StandardReadable
2
+ from ophyd_async.epics.motion import Motor
3
+ from ophyd_async.epics.signal import epics_signal_r
4
+
5
+
6
+ class DCM(StandardReadable):
7
+ """
8
+ A double crystal monocromator device, used to select the beam energy.
9
+ """
10
+
11
+ def __init__(self, prefix: str, name: str = "") -> None:
12
+ with self.add_children_as_readables():
13
+ # Motors
14
+ self.bragg_in_degrees = Motor(prefix + "-MO-DCM-01:BRAGG")
15
+ self.x_translation_in_mm = Motor(prefix + "-MO-DCM-01:X")
16
+ self.offset_in_mm = Motor(prefix + "-MO-DCM-01:OFFSET")
17
+ self.gap_in_mm = Motor(prefix + "-MO-DCM-01:GAP")
18
+ self.energy_in_kev = Motor(prefix + "-MO-DCM-01:ENERGY")
19
+ self.xtal1_roll = Motor(prefix + "-MO-DCM-01:XTAL1:ROLL")
20
+ self.xtal2_roll = Motor(prefix + "-MO-DCM-01:XTAL2:ROLL")
21
+ self.xtal2_pitch = Motor(prefix + "-MO-DCM-01:XTAL2:PITCH")
22
+
23
+ # Wavelength is calculated in epics from the energy
24
+ self.wavelength_in_a = epics_signal_r(float, prefix + "-MO-DCM-01:LAMBDA")
25
+
26
+ # Temperatures
27
+ self.xtal1_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-1")
28
+ self.xtal1_heater_temp = epics_signal_r(
29
+ float, prefix + "-DI-DCM-01:PT100-2"
30
+ )
31
+ self.xtal2_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-4")
32
+ self.xtal2_heater_temp = epics_signal_r(
33
+ float, prefix + "-DI-DCM-01:PT100-5"
34
+ )
35
+
36
+ self.roll_plate_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-3")
37
+ self.pitch_plate_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-6")
38
+ self.backplate_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-7")
39
+ self.b1_plate_temp = epics_signal_r(float, prefix + "-DI-DCM-01:PT100-7")
40
+ self.gap_temp = epics_signal_r(float, prefix + "-DI-DCM-01:TC-1")
41
+
42
+ super().__init__(name)
@@ -46,6 +46,7 @@ class ZoomController(Device):
46
46
  sxst = Component(EpicsSignal, "MP:SELECT.SXST")
47
47
 
48
48
  def set_flatfield_on_zoom_level_one(self, value):
49
+ self.parent: "OAV"
49
50
  flat_applied = self.parent.proc.port_name.get()
50
51
  no_flat_applied = self.parent.cam.port_name.get()
51
52
  return self.parent.grid_snapshot.input_plugin.set(
@@ -50,11 +50,13 @@ class PinTipDetection(StandardReadable):
50
50
  self._prefix: str = prefix
51
51
  self._name = name
52
52
 
53
- self.triggered_tip, _ = soft_signal_r_and_setter(Tip, name="triggered_tip")
54
- self.triggered_top_edge, _ = soft_signal_r_and_setter(
53
+ self.triggered_tip, self._tip_setter = soft_signal_r_and_setter(
54
+ Tip, name="triggered_tip"
55
+ )
56
+ self.triggered_top_edge, self._top_edge_setter = soft_signal_r_and_setter(
55
57
  NDArray[np.uint32], name="triggered_top_edge"
56
58
  )
57
- self.triggered_bottom_edge, _ = soft_signal_r_and_setter(
59
+ self.triggered_bottom_edge, self._bottom_edge_setter = soft_signal_r_and_setter(
58
60
  NDArray[np.uint32], name="triggered_bottom_edge"
59
61
  )
60
62
  self.array_data = epics_signal_r(NDArray[np.uint8], f"pva://{prefix}PVA:ARRAY")
@@ -85,14 +87,14 @@ class PinTipDetection(StandardReadable):
85
87
 
86
88
  super().__init__(name=name)
87
89
 
88
- async def _set_triggered_values(self, results: SampleLocation):
90
+ def _set_triggered_values(self, results: SampleLocation):
89
91
  tip = (results.tip_x, results.tip_y)
90
92
  if tip == self.INVALID_POSITION:
91
93
  raise InvalidPinException
92
94
  else:
93
- await self.triggered_tip._backend.put(tip)
94
- await self.triggered_top_edge._backend.put(results.edge_top)
95
- await self.triggered_bottom_edge._backend.put(results.edge_bottom)
95
+ self._tip_setter(tip)
96
+ self._top_edge_setter(results.edge_top)
97
+ self._bottom_edge_setter(results.edge_bottom)
96
98
 
97
99
  async def _get_tip_and_edge_data(
98
100
  self, array_data: NDArray[np.uint8]
@@ -150,7 +152,7 @@ class PinTipDetection(StandardReadable):
150
152
  async for value in observe_value(self.array_data):
151
153
  try:
152
154
  location = await self._get_tip_and_edge_data(value)
153
- await self._set_triggered_values(location)
155
+ self._set_triggered_values(location)
154
156
  except Exception as e:
155
157
  LOGGER.warn(
156
158
  f"Failed to detect pin-tip location, will retry with next image: {e}"
@@ -166,6 +168,6 @@ class PinTipDetection(StandardReadable):
166
168
  LOGGER.error(
167
169
  f"No tip found in {await self.validity_timeout.get_value()} seconds."
168
170
  )
169
- await self.triggered_tip._backend.put(self.INVALID_POSITION)
170
- await self.triggered_bottom_edge._backend.put(np.array([]))
171
- await self.triggered_top_edge._backend.put(np.array([]))
171
+ self._tip_setter(self.INVALID_POSITION)
172
+ self._bottom_edge_setter(np.array([]))
173
+ self._top_edge_setter(np.array([]))
@@ -1,17 +1,14 @@
1
1
  from enum import IntEnum
2
- from pathlib import Path
3
2
  from typing import Generator, Tuple
4
3
 
5
4
  import bluesky.plan_stubs as bps
6
5
  import numpy as np
7
6
  from bluesky.utils import Msg
8
- from PIL.Image import Image
9
7
 
10
8
  from dodal.devices.oav.oav_calculations import camera_coordinates_to_xyz
11
- from dodal.devices.oav.oav_parameters import OAVConfigParams
9
+ from dodal.devices.oav.oav_detector import OAVConfigParams
12
10
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
13
11
  from dodal.devices.smargon import Smargon
14
- from dodal.log import LOGGER
15
12
 
16
13
  Pixel = Tuple[int, int]
17
14
 
@@ -110,14 +107,3 @@ def wait_for_tip_to_be_found(
110
107
  raise PinNotFoundException(f"No pin found after {timeout} seconds")
111
108
 
112
109
  return found_tip # type: ignore
113
-
114
-
115
- def save_thumbnail(full_file_path: Path, full_image: Image, new_height=192):
116
- """Scales an image down to have the height specified in new_height and saves it
117
- to the same location as the full image with a t appended to the filename"""
118
- thumbnail_path = full_file_path.with_stem(full_file_path.stem + "t")
119
- LOGGER.info(f"Saving thumbnail to {thumbnail_path}")
120
- full_size = full_image.size
121
- new_width = (new_height / full_size[1]) * full_size[0]
122
- full_image.thumbnail((new_width, new_height))
123
- full_image.save(thumbnail_path.as_posix())
@@ -60,7 +60,8 @@ class BartRobot(StandardReadable, Movable):
60
60
  self.program_running = epics_signal_r(bool, prefix + "PROGRAM_RUNNING")
61
61
  self.program_name = epics_signal_r(str, prefix + "PROGRAM_NAME")
62
62
  self.error_str = epics_signal_r(str, prefix + "PRG_ERR_MSG")
63
- self.error_code = epics_signal_r(int, prefix + "PRG_ERR_CODE")
63
+ # Change error_code to int type when https://github.com/bluesky/ophyd-async/issues/280 released
64
+ self.error_code = epics_signal_r(float, prefix + "PRG_ERR_CODE")
64
65
  super().__init__(name=name)
65
66
 
66
67
  async def pin_mounted_or_no_pin_found(self):
@@ -1,5 +1,5 @@
1
1
  from functools import partial
2
- from typing import Callable
2
+ from typing import Callable, Sequence
3
3
 
4
4
  from bluesky.protocols import Movable
5
5
  from ophyd import Component, EpicsSignal
@@ -26,7 +26,7 @@ def epics_signal_put_wait(pv_name: str, wait: float = 3.0) -> Component[EpicsSig
26
26
 
27
27
 
28
28
  def run_functions_without_blocking(
29
- functions_to_chain: list[Callable[[], StatusBase]],
29
+ functions_to_chain: Sequence[Callable[[], StatusBase]],
30
30
  timeout: float = 60.0,
31
31
  associated_obj: OphydDevice | None = None,
32
32
  ) -> Status: