dls-dodal 1.69.0__py3-none-any.whl → 2.0.0__py3-none-any.whl

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 (282) hide show
  1. {dls_dodal-1.69.0.dist-info → dls_dodal-2.0.0.dist-info}/METADATA +1 -1
  2. dls_dodal-2.0.0.dist-info/RECORD +354 -0
  3. {dls_dodal-1.69.0.dist-info → dls_dodal-2.0.0.dist-info}/WHEEL +1 -1
  4. dodal/_version.py +2 -2
  5. dodal/beamlines/__init__.py +10 -17
  6. dodal/beamlines/adsim.py +17 -17
  7. dodal/beamlines/b01_1.py +11 -0
  8. dodal/beamlines/b07.py +17 -21
  9. dodal/beamlines/b07_1.py +20 -22
  10. dodal/beamlines/b07_shared.py +12 -0
  11. dodal/beamlines/b16.py +1 -1
  12. dodal/beamlines/b21.py +15 -6
  13. dodal/beamlines/i02_1.py +3 -3
  14. dodal/beamlines/i02_2.py +1 -1
  15. dodal/beamlines/i03.py +4 -4
  16. dodal/beamlines/i04.py +16 -8
  17. dodal/beamlines/i05.py +7 -45
  18. dodal/beamlines/i05_1.py +4 -13
  19. dodal/beamlines/i05_shared.py +51 -0
  20. dodal/beamlines/i06_1.py +7 -5
  21. dodal/beamlines/{i06.py → i06_shared.py} +25 -14
  22. dodal/beamlines/i07.py +14 -16
  23. dodal/beamlines/i09.py +54 -51
  24. dodal/beamlines/i09_1.py +25 -64
  25. dodal/beamlines/i09_1_shared.py +61 -0
  26. dodal/beamlines/i09_2.py +6 -100
  27. dodal/beamlines/i09_2_shared.py +110 -0
  28. dodal/beamlines/i10.py +60 -54
  29. dodal/beamlines/i10_1.py +99 -10
  30. dodal/beamlines/{i10_optics.py → i10_shared.py} +80 -66
  31. dodal/beamlines/i11.py +31 -18
  32. dodal/beamlines/i13_1.py +1 -1
  33. dodal/beamlines/i15.py +6 -6
  34. dodal/beamlines/i15_1.py +6 -6
  35. dodal/beamlines/i17.py +37 -28
  36. dodal/beamlines/i18.py +3 -4
  37. dodal/beamlines/i19_1.py +95 -34
  38. dodal/beamlines/i19_2.py +68 -52
  39. dodal/beamlines/i19_optics.py +26 -13
  40. dodal/beamlines/i20_1.py +6 -14
  41. dodal/beamlines/i21.py +35 -28
  42. dodal/beamlines/i22.py +19 -4
  43. dodal/beamlines/i23.py +1 -2
  44. dodal/beamlines/i24.py +11 -10
  45. dodal/beamlines/k07.py +99 -5
  46. dodal/beamlines/p38.py +3 -3
  47. dodal/beamlines/p60.py +28 -17
  48. dodal/beamlines/p99.py +16 -15
  49. dodal/beamlines/training_rig.py +20 -12
  50. dodal/cli.py +36 -2
  51. dodal/common/beamlines/beamline_parameters.py +2 -1
  52. dodal/common/beamlines/beamline_utils.py +11 -9
  53. dodal/common/beamlines/commissioning_mode.py +6 -3
  54. dodal/common/coordination.py +12 -14
  55. dodal/common/crystal_metadata.py +5 -8
  56. dodal/common/device_utils.py +4 -3
  57. dodal/common/maths.py +28 -40
  58. dodal/common/udc_directory_provider.py +13 -8
  59. dodal/common/visit.py +18 -21
  60. dodal/common/watcher_utils.py +13 -12
  61. dodal/device_manager.py +94 -54
  62. dodal/devices/aperturescatterguard.py +26 -27
  63. dodal/devices/areadetector/plugins/cam.py +1 -3
  64. dodal/devices/areadetector/plugins/mjpg.py +6 -5
  65. dodal/devices/attenuator/attenuator.py +12 -11
  66. dodal/devices/beamlines/b07/__init__.py +3 -0
  67. dodal/devices/{b07_1 → beamlines/b07_1}/__init__.py +2 -2
  68. dodal/devices/{b07_1 → beamlines/b07_1}/ccmc.py +5 -10
  69. dodal/devices/{b16 → beamlines/b16}/detector.py +2 -3
  70. dodal/devices/{i02_1 → beamlines/i02_1}/fast_grid_scan.py +2 -3
  71. dodal/devices/{i02_1 → beamlines/i02_1}/sample_motors.py +1 -1
  72. dodal/devices/{i03 → beamlines/i03}/beamsize.py +11 -7
  73. dodal/devices/{i03 → beamlines/i03}/dcm.py +1 -2
  74. dodal/devices/{i03 → beamlines/i03}/undulator_dcm.py +4 -5
  75. dodal/devices/beamlines/i04/beam_centre.py +151 -0
  76. dodal/devices/{i04 → beamlines/i04}/beamsize.py +11 -7
  77. dodal/devices/{i04 → beamlines/i04}/murko_results.py +5 -5
  78. dodal/devices/{i04 → beamlines/i04}/transfocator.py +10 -15
  79. dodal/devices/beamlines/i05/__init__.py +3 -0
  80. dodal/devices/beamlines/i06_shared/__init__.py +3 -0
  81. dodal/devices/beamlines/i06_shared/i06_enum.py +7 -0
  82. dodal/devices/{i07 → beamlines/i07}/dcm.py +2 -3
  83. dodal/devices/{i07 → beamlines/i07}/id.py +8 -9
  84. dodal/devices/beamlines/i09/__init__.py +3 -0
  85. dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_energy.py +5 -6
  86. dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_undulator_functions.py +19 -16
  87. dodal/devices/{i10 → beamlines/i10}/diagnostics.py +4 -3
  88. dodal/devices/{i10 → beamlines/i10}/i10_apple2.py +31 -45
  89. dodal/devices/{i10 → beamlines/i10}/rasor/rasor_current_amp.py +1 -24
  90. dodal/devices/{i10 → beamlines/i10}/rasor/rasor_motors.py +2 -2
  91. dodal/devices/{i10 → beamlines/i10}/slits.py +5 -3
  92. dodal/devices/beamlines/i10_1/__init__.py +9 -0
  93. dodal/devices/beamlines/i10_1/electromagnet/magnet.py +16 -0
  94. dodal/devices/beamlines/i10_1/electromagnet/stages.py +14 -0
  95. dodal/devices/beamlines/i10_1/scaler_cards.py +13 -0
  96. dodal/devices/{i11 → beamlines/i11}/cyberstar_blower.py +1 -1
  97. dodal/devices/{i11 → beamlines/i11}/diff_stages.py +4 -6
  98. dodal/devices/{i11 → beamlines/i11}/mythen.py +3 -4
  99. dodal/devices/{i11 → beamlines/i11}/nx100robot.py +6 -6
  100. dodal/devices/{i11 → beamlines/i11}/spinner.py +1 -1
  101. dodal/devices/{i13_1 → beamlines/i13_1}/merlin.py +1 -1
  102. dodal/devices/{i15 → beamlines/i15}/dcm.py +1 -2
  103. dodal/devices/{i15 → beamlines/i15}/focussing_mirror.py +5 -5
  104. dodal/devices/{i15 → beamlines/i15}/jack.py +2 -2
  105. dodal/devices/{i15 → beamlines/i15}/multilayer_mirror.py +1 -1
  106. dodal/devices/{i17 → beamlines/i17}/i17_apple2.py +10 -16
  107. dodal/devices/{i18 → beamlines/i18}/diode.py +1 -1
  108. dodal/devices/{i19 → beamlines/i19}/access_controlled/attenuator_motor_squad.py +12 -8
  109. dodal/devices/{i19 → beamlines/i19}/access_controlled/blueapi_device.py +16 -15
  110. dodal/devices/beamlines/i19/access_controlled/piezo_control.py +72 -0
  111. dodal/devices/{i19 → beamlines/i19}/access_controlled/shutter.py +11 -9
  112. dodal/devices/{i19 → beamlines/i19}/backlight.py +3 -1
  113. dodal/devices/{i19 → beamlines/i19}/mapt_configuration.py +2 -1
  114. dodal/devices/{i19 → beamlines/i19}/pin_col_stages.py +11 -8
  115. dodal/devices/beamlines/i19/pin_tip.py +32 -0
  116. dodal/devices/beamlines/i21/__init__.py +3 -0
  117. dodal/devices/{i22 → beamlines/i22}/dcm.py +1 -2
  118. dodal/devices/{i22 → beamlines/i22}/fswitch.py +1 -3
  119. dodal/devices/{i22 → beamlines/i22}/nxsas.py +5 -4
  120. dodal/devices/{i24 → beamlines/i24}/beam_center.py +1 -1
  121. dodal/devices/{i24 → beamlines/i24}/beamstop.py +2 -2
  122. dodal/devices/{i24 → beamlines/i24}/commissioning_jungfrau.py +3 -2
  123. dodal/devices/{i24 → beamlines/i24}/dcm.py +1 -3
  124. dodal/devices/{i24 → beamlines/i24}/dual_backlight.py +3 -3
  125. dodal/devices/{i24 → beamlines/i24}/pmac.py +9 -7
  126. dodal/devices/{p60 → beamlines/p60}/lab_xray_source.py +1 -1
  127. dodal/devices/beamlines/p99/__init__.py +0 -0
  128. dodal/devices/{p99 → beamlines/p99}/andor2_point.py +11 -15
  129. dodal/devices/bimorph_mirror.py +22 -20
  130. dodal/devices/collimation_table.py +3 -2
  131. dodal/devices/common_dcm.py +30 -20
  132. dodal/devices/controllers.py +2 -2
  133. dodal/devices/cryostream.py +8 -0
  134. dodal/devices/current_amplifiers/current_amplifier.py +16 -18
  135. dodal/devices/current_amplifiers/current_amplifier_detector.py +9 -10
  136. dodal/devices/current_amplifiers/femto.py +8 -9
  137. dodal/devices/current_amplifiers/sr570.py +16 -16
  138. dodal/devices/current_amplifiers/struck_scaler_counter.py +5 -5
  139. dodal/devices/detector/det_resolution.py +9 -8
  140. dodal/devices/detector/detector.py +4 -2
  141. dodal/devices/diamond_filter.py +3 -4
  142. dodal/devices/eiger.py +3 -3
  143. dodal/devices/eiger_odin.py +1 -1
  144. dodal/devices/electron_analyser/base/base_controller.py +13 -13
  145. dodal/devices/electron_analyser/base/base_detector.py +15 -20
  146. dodal/devices/electron_analyser/base/base_driver_io.py +39 -46
  147. dodal/devices/electron_analyser/base/base_region.py +27 -30
  148. dodal/devices/electron_analyser/base/base_util.py +18 -16
  149. dodal/devices/electron_analyser/base/energy_sources.py +13 -19
  150. dodal/devices/eurotherm.py +3 -2
  151. dodal/devices/fast_grid_scan.py +31 -34
  152. dodal/devices/fast_shutter.py +24 -21
  153. dodal/devices/flux.py +1 -1
  154. dodal/devices/focusing_mirror.py +29 -11
  155. dodal/devices/hutch_shutter.py +6 -6
  156. dodal/devices/insertion_device/__init__.py +8 -0
  157. dodal/devices/insertion_device/apple2_controller.py +51 -60
  158. dodal/devices/insertion_device/apple2_undulator.py +40 -64
  159. dodal/devices/insertion_device/apple_knot_controller.py +222 -0
  160. dodal/devices/insertion_device/energy.py +100 -27
  161. dodal/devices/insertion_device/energy_motor_lookup.py +20 -27
  162. dodal/devices/insertion_device/lookup_table_models.py +45 -50
  163. dodal/devices/insertion_device/polarisation.py +1 -1
  164. dodal/devices/ipin.py +1 -1
  165. dodal/devices/linkam3.py +7 -5
  166. dodal/devices/motors.py +107 -19
  167. dodal/devices/mx_phase1/beamstop.py +2 -4
  168. dodal/devices/oav/oav_calculations.py +20 -13
  169. dodal/devices/oav/oav_detector.py +28 -23
  170. dodal/devices/oav/oav_parameters.py +4 -9
  171. dodal/devices/oav/oav_to_redis_forwarder.py +22 -18
  172. dodal/devices/oav/pin_image_recognition/__init__.py +4 -6
  173. dodal/devices/oav/pin_image_recognition/manual_test.py +1 -2
  174. dodal/devices/oav/pin_image_recognition/utils.py +30 -32
  175. dodal/devices/oav/snapshots/grid_overlay.py +10 -9
  176. dodal/devices/oav/snapshots/snapshot_image_processing.py +15 -13
  177. dodal/devices/oav/utils.py +9 -12
  178. dodal/devices/p45.py +3 -9
  179. dodal/devices/pgm.py +8 -14
  180. dodal/devices/pressure_jump_cell.py +93 -32
  181. dodal/devices/qbpm.py +1 -3
  182. dodal/devices/robot.py +12 -4
  183. dodal/devices/s4_slit_gaps.py +1 -1
  184. dodal/devices/selectable_source.py +5 -2
  185. dodal/devices/slits.py +2 -5
  186. dodal/devices/smargon.py +2 -3
  187. dodal/devices/temperture_controller/lakeshore/lakeshore.py +38 -64
  188. dodal/devices/temperture_controller/lakeshore/lakeshore_io.py +21 -35
  189. dodal/devices/tetramm.py +7 -7
  190. dodal/devices/turbo_slit.py +8 -7
  191. dodal/devices/undulator.py +42 -56
  192. dodal/devices/util/adjuster_plans.py +2 -3
  193. dodal/devices/util/epics_util.py +10 -10
  194. dodal/devices/util/lookup_tables.py +17 -18
  195. dodal/devices/v2f.py +2 -3
  196. dodal/devices/watsonmarlow323_pump.py +1 -1
  197. dodal/devices/xbpm_feedback.py +3 -2
  198. dodal/devices/xspress3/xspress3.py +8 -11
  199. dodal/devices/xspress3/xspress3_channel.py +3 -6
  200. dodal/devices/zebra/zebra.py +6 -7
  201. dodal/devices/zebra/zebra_constants_mapping.py +11 -7
  202. dodal/devices/zebra/zebra_controlled_shutter.py +2 -1
  203. dodal/devices/zocalo/zocalo_interaction.py +14 -14
  204. dodal/devices/zocalo/zocalo_results.py +33 -33
  205. dodal/log.py +23 -20
  206. dodal/plan_stubs/check_topup.py +15 -15
  207. dodal/plan_stubs/data_session.py +6 -6
  208. dodal/plan_stubs/motor_utils.py +22 -18
  209. dodal/plan_stubs/pressure_jump_cell.py +18 -0
  210. dodal/plan_stubs/wrapped.py +40 -55
  211. dodal/plans/bimorph.py +63 -52
  212. dodal/plans/device_setup_plans/__init__.py +5 -0
  213. dodal/plans/device_setup_plans/setup_pin_tip_params.py +63 -0
  214. dodal/plans/preprocessors/verify_undulator_gap.py +10 -8
  215. dodal/plans/spec_path.py +3 -5
  216. dodal/plans/verify_undulator_gap.py +1 -2
  217. dodal/plans/wrapped.py +4 -3
  218. dodal/testing/electron_analyser/device_factory.py +5 -7
  219. dodal/testing/fixtures/devices/apple2.py +38 -0
  220. dodal/testing/fixtures/run_engine.py +3 -7
  221. dodal/testing/fixtures/utils.py +1 -2
  222. dodal/utils.py +60 -58
  223. dls_dodal-1.69.0.dist-info/RECORD +0 -338
  224. dodal/beamline_specific_utils/i05_shared.py +0 -14
  225. dodal/devices/b07/__init__.py +0 -3
  226. dodal/devices/i04/beam_centre.py +0 -84
  227. dodal/devices/i05/__init__.py +0 -3
  228. dodal/devices/i09/__init__.py +0 -3
  229. dodal/devices/i21/__init__.py +0 -5
  230. {dls_dodal-1.69.0.dist-info → dls_dodal-2.0.0.dist-info}/entry_points.txt +0 -0
  231. {dls_dodal-1.69.0.dist-info → dls_dodal-2.0.0.dist-info}/licenses/LICENSE +0 -0
  232. {dls_dodal-1.69.0.dist-info → dls_dodal-2.0.0.dist-info}/top_level.txt +0 -0
  233. /dodal/{beamline_specific_utils → devices/beamlines}/__init__.py +0 -0
  234. /dodal/devices/{b07 → beamlines/b07}/enums.py +0 -0
  235. /dodal/devices/{b07_1 → beamlines/b07_1}/enums.py +0 -0
  236. /dodal/devices/{b16 → beamlines/b16}/__init__.py +0 -0
  237. /dodal/devices/{i02_1 → beamlines/i02_1}/__init__.py +0 -0
  238. /dodal/devices/{i02_2 → beamlines/i02_2}/__init__.py +0 -0
  239. /dodal/devices/{i03 → beamlines/i03}/__init__.py +0 -0
  240. /dodal/devices/{i03 → beamlines/i03}/constants.py +0 -0
  241. /dodal/devices/{i04 → beamlines/i04}/__init__.py +0 -0
  242. /dodal/devices/{i04 → beamlines/i04}/constants.py +0 -0
  243. /dodal/devices/{i04 → beamlines/i04}/max_pixel.py +0 -0
  244. /dodal/devices/{i05 → beamlines/i05}/enums.py +0 -0
  245. /dodal/devices/{i07 → beamlines/i07}/__init__.py +0 -0
  246. /dodal/devices/{i09 → beamlines/i09}/enums.py +0 -0
  247. /dodal/devices/{i09_1 → beamlines/i09_1}/__init__.py +0 -0
  248. /dodal/devices/{i09_1 → beamlines/i09_1}/enums.py +0 -0
  249. /dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/__init__.py +0 -0
  250. /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/__init__.py +0 -0
  251. /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/i09_apple2.py +0 -0
  252. /dodal/devices/{i10 → beamlines/i10}/__init__.py +0 -0
  253. /dodal/devices/{i10 → beamlines/i10}/i10_setting_data.py +0 -0
  254. /dodal/devices/{i10 → beamlines/i10}/mirrors.py +0 -0
  255. /dodal/devices/{i10 → beamlines/i10}/rasor/__init__.py +0 -0
  256. /dodal/devices/{i10 → beamlines/i10}/rasor/rasor_scaler_cards.py +0 -0
  257. /dodal/devices/{i11 → beamlines/i10_1/electromagnet}/__init__.py +0 -0
  258. /dodal/devices/{i13_1 → beamlines/i11}/__init__.py +0 -0
  259. /dodal/devices/{i15 → beamlines/i13_1}/__init__.py +0 -0
  260. /dodal/devices/{i13_1 → beamlines/i13_1}/merlin_controller.py +0 -0
  261. /dodal/devices/{i17 → beamlines/i15}/__init__.py +0 -0
  262. /dodal/devices/{i15 → beamlines/i15}/laue.py +0 -0
  263. /dodal/devices/{i15 → beamlines/i15}/motors.py +0 -0
  264. /dodal/devices/{i15 → beamlines/i15}/rail.py +0 -0
  265. /dodal/devices/{i18 → beamlines/i17}/__init__.py +0 -0
  266. /dodal/devices/{i19 → beamlines/i18}/__init__.py +0 -0
  267. /dodal/devices/{i18 → beamlines/i18}/kb_mirror.py +0 -0
  268. /dodal/devices/{i19/access_controlled → beamlines/i19}/__init__.py +0 -0
  269. /dodal/devices/{i20_1 → beamlines/i19/access_controlled}/__init__.py +0 -0
  270. /dodal/devices/{i19 → beamlines/i19}/access_controlled/hutch_access.py +0 -0
  271. /dodal/devices/{i19 → beamlines/i19}/beamstop.py +0 -0
  272. /dodal/devices/{i19 → beamlines/i19}/diffractometer.py +0 -0
  273. /dodal/devices/{i22 → beamlines/i20_1}/__init__.py +0 -0
  274. /dodal/devices/{i21 → beamlines/i21}/enums.py +0 -0
  275. /dodal/devices/{i24 → beamlines/i22}/__init__.py +0 -0
  276. /dodal/devices/{p99 → beamlines/i24}/__init__.py +0 -0
  277. /dodal/devices/{i24 → beamlines/i24}/aperture.py +0 -0
  278. /dodal/devices/{i24 → beamlines/i24}/focus_mirrors.py +0 -0
  279. /dodal/devices/{i24 → beamlines/i24}/vgonio.py +0 -0
  280. /dodal/devices/{p60 → beamlines/p60}/__init__.py +0 -0
  281. /dodal/devices/{p60 → beamlines/p60}/enums.py +0 -0
  282. /dodal/devices/{p99 → beamlines/p99}/sample_stage.py +0 -0
@@ -3,11 +3,16 @@ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
3
3
 
4
4
 
5
5
  class LakeshoreControlChannel(Device):
6
- """
7
- Single control channel for a Lakeshore temperature controller.
6
+ """Single control channel for a Lakeshore temperature controller.
7
+
8
+ Provides access to setpoint, ramp rate, ramp enable, heater output, heater output
9
+ range, PID parameters (P, I, D), and manual output for the channel.
8
10
 
9
- Provides access to setpoint, ramp rate, ramp enable, heater output, heater output range,
10
- PID parameters (P, I, D), and manual output for the channel.
11
+ Args:
12
+ prefix (str): The EPICS prefix for the Lakeshore device.
13
+ suffix (str): Suffix for the channel, used to differentiate multiple channels.
14
+ heater_type (SignalDatatypeT): Type of the heater output range.
15
+ name (str, optional): Name for the device.
11
16
  """
12
17
 
13
18
  def __init__(
@@ -17,19 +22,6 @@ class LakeshoreControlChannel(Device):
17
22
  heater_type: type[SignalDatatypeT],
18
23
  name: str = "",
19
24
  ):
20
- """Initialize the LakeshoreControlChannel device.
21
- Parameters
22
- ----------
23
- prefix: str
24
- The EPICS prefix for the Lakeshore device.
25
- suffix: str
26
- Suffix for the channel, used to differentiate multiple channels.
27
- heater_type: SignalDatatypeT
28
- Type of the heater output range.
29
- name: str
30
- Optional name for the device.
31
- """
32
-
33
25
  def channel_rw(channel_type, pv_name):
34
26
  return epics_signal_rw(
35
27
  channel_type,
@@ -53,11 +45,21 @@ class LakeshoreControlChannel(Device):
53
45
  class LakeshoreBaseIO(Device):
54
46
  """Base class for Lakeshore temperature controller IO.
55
47
 
56
- Provides access to control channels and readback channels for setpoint, ramp rate, heater output,
57
- and PID parameters. Supports both single and multiple control channel configurations.
48
+ Provides access to control channels and readback channels for setpoint, ramp rate,
49
+ heater output, and PID parameters. Supports both single and multiple control channel
50
+ configurations.
51
+
58
52
  Note:
59
53
  Almost all models have a controller for each readback channel but some models
60
54
  only has a single controller for multiple readback channels.
55
+
56
+ Args:
57
+ prefix (str): The EPICS prefix for the Lakeshore device.
58
+ num_readback_channel (int): Number of readback channels to create.
59
+ heater_setting (SignalDatatypeT): Type of the heater setting.
60
+ name (str, optional): Name for the device.
61
+ single_control_channel (bool): If True, use a single control channel for
62
+ all readback.
61
63
  """
62
64
 
63
65
  def __init__(
@@ -68,22 +70,6 @@ class LakeshoreBaseIO(Device):
68
70
  name: str = "",
69
71
  single_control_channel: bool = False,
70
72
  ):
71
- """Initialize the LakeshoreBaseIO device.
72
-
73
- Parameters
74
- -----------
75
- prefix: str
76
- The EPICS prefix for the Lakeshore device.
77
- num_readback_channel: int
78
- Number of readback channels to create.
79
- heater_setting: SignalDatatypeT
80
- Type of the heater setting.
81
- name: str
82
- Optional name for the device.
83
- single_control_channel: bool
84
- If True, use a single control channel for all readback.
85
- """
86
-
87
73
  suffixes = (
88
74
  [""]
89
75
  if single_control_channel
dodal/devices/tetramm.py CHANGED
@@ -75,7 +75,7 @@ class TetrammDriver(NDArrayBaseIO):
75
75
 
76
76
 
77
77
  class TetrammController(DetectorController):
78
- """Controller for a TetrAMM current monitor"""
78
+ """Controller for a TetrAMM current monitor."""
79
79
 
80
80
  _supported_trigger_types = {
81
81
  DetectorTrigger.EDGE_TRIGGER: TetrammTrigger.EXT_TRIGGER,
@@ -164,9 +164,8 @@ class TetrammController(DetectorController):
164
164
  sample rate, it will be lowered to the prior multiple ot ensure triggers
165
165
  are not missed.
166
166
 
167
- :param exposure: Desired exposure time.
168
- :type exposure: How long to wait for the exposure time and acquire
169
- period to be set.
167
+ Args:
168
+ exposure (float): Desired exposure time.
170
169
  """
171
170
  sample_time = await self.driver.sample_time.get_value()
172
171
  minimum_samples = self._minimal_values_per_reading[
@@ -189,9 +188,10 @@ class TetrammController(DetectorController):
189
188
  Then, it checks that the DetectorState PV is in DEFAULT_GOOD_STATES,
190
189
  and otherwise raises a ValueError.
191
190
 
192
- :returns AsyncStatus:
193
- An AsyncStatus that can be awaited to set driver.acquire to True and perform
194
- subsequent raising (if applicable) due to detector state.
191
+ Returns:
192
+ AsyncStatus: An AsyncStatus that can be awaited to set driver.acquire to
193
+ True and perform subsequent raising (if applicable) due to detector
194
+ state.
195
195
  """
196
196
  status = await set_and_wait_for_value(
197
197
  self.driver.acquire,
@@ -4,18 +4,19 @@ from ophyd_async.epics.motor import Motor
4
4
 
5
5
 
6
6
  class TurboSlit(StandardReadable, Movable[float]):
7
- """
8
- This collection of motors coordinates time resolved XAS experiments.
7
+ """This collection of motors coordinates time resolved XAS experiments.
9
8
  It selects a beam out of the polychromatic fan.
10
9
  There is a 0.1 degrees beam that can move along a 90-ish degree arc.
11
10
  A turboslit device moves after the beam, so that the gap aligns with the beam.
12
11
  The turboslit gap can be made smaller to increase energy resolution.
13
- The xfine motor can move the slit in x direction at high frequencies for different scans.
12
+ The xfine motor can move the slit in x direction at high frequencies for different
13
+ scans.
14
14
  These slits can be scanned continously or in step mode.
15
15
  The relationship between the three motors is as follows:
16
- - arc - position of the middle of the gap in degrees (coarse/ macro) extension
17
- - gap - width in mm, provides energy resolution
18
- - xfine - main scanning axis in mm, selects the energy as part of the high frequency scan
16
+ - arc - position of the middle of the gap in degrees (coarse/ macro) extension.
17
+ - gap - width in mm, provides energy resolution.
18
+ - xfine - main scanning axis in mm, selects the energy as part of the high
19
+ frequency scan.
19
20
  """
20
21
 
21
22
  def __init__(self, prefix: str, name: str = ""):
@@ -27,5 +28,5 @@ class TurboSlit(StandardReadable, Movable[float]):
27
28
 
28
29
  @AsyncStatus.wrap
29
30
  async def set(self, value: float):
30
- """This will move the default XFINE"""
31
+ """This will move the default XFINE."""
31
32
  await self.xfine.set(value)
@@ -41,9 +41,16 @@ def _get_gap_for_energy(
41
41
 
42
42
 
43
43
  class BaseUndulator(StandardReadable, Movable[float], ABC):
44
- """
45
- Base class for undulator devices providing gap control and access management.
44
+ """Base class for undulator devices providing gap control and access management.
46
45
  This class expects target gap value [mm] passed in set method.
46
+
47
+ Args:
48
+ prefix (str): PV prefix.
49
+ poles (int, optional): Number of magnetic poles built into the undulator.
50
+ length (float, optional): Length of the undulator in meters.
51
+ undulator_period(int, optional): Undulator period.
52
+ baton (Baton, optional): Baton object if provided.
53
+ name (str, optional): Name for device. Defaults to "".
47
54
  """
48
55
 
49
56
  def __init__(
@@ -55,15 +62,6 @@ class BaseUndulator(StandardReadable, Movable[float], ABC):
55
62
  baton: Baton | None = None,
56
63
  name: str = "",
57
64
  ) -> None:
58
- """
59
- Args:
60
- prefix: PV prefix
61
- poles (int, optional): Number of magnetic poles built into the undulator
62
- length (float, optional): Length of the undulator in meters
63
- undulator_period(int, optional): Undulator period
64
- baton (optional): Baton object if provided.
65
- name (str, optional): Name for device. Defaults to "".
66
- """
67
65
  self.baton_ref = Reference(baton) if baton else None
68
66
 
69
67
  with self.add_children_as_readables():
@@ -91,18 +89,16 @@ class BaseUndulator(StandardReadable, Movable[float], ABC):
91
89
  @abstractmethod
92
90
  @AsyncStatus.wrap
93
91
  async def set(self, value: float) -> None:
94
- """
95
- Move undulator to a given position.
92
+ """Move undulator to a given position.
96
93
  Abstract method - must be implemented by subclasses.
97
94
 
98
95
  Args:
99
- value: target position - units depend on implementation
96
+ value (float): Target Position - units depend on implementation.
100
97
  """
101
98
  ...
102
99
 
103
100
  async def _set_gap(self, value: float) -> None:
104
- """
105
- Set the undulator gap to a given value in mm.
101
+ """Set the undulator gap to a given value in mm.
106
102
 
107
103
  Args:
108
104
  value: gap in mm
@@ -129,11 +125,11 @@ class BaseUndulator(StandardReadable, Movable[float], ABC):
129
125
  LOGGER.warning("In test mode, not moving ID gap")
130
126
 
131
127
  async def _check_gap_within_threshold(self, target_gap: float) -> bool:
132
- """
133
- Check if the undulator gap is within the acceptable threshold of the target gap.
128
+ """Check if the undulator gap is within the acceptable threshold of the target gap.
134
129
 
135
130
  Args:
136
131
  target_gap: target gap in mm
132
+
137
133
  Returns:
138
134
  True if the gap is within the threshold, False otherwise
139
135
  """
@@ -142,14 +138,14 @@ class BaseUndulator(StandardReadable, Movable[float], ABC):
142
138
  return abs(target_gap - current_gap) <= tolerance
143
139
 
144
140
  async def _is_commissioning_mode_enabled(self) -> bool | None:
145
- """
146
- Asynchronously checks if commissioning mode is enabled via the baton reference.
141
+ """Asynchronously checks if commissioning mode is enabled via the baton
142
+ reference.
147
143
  """
148
144
  return self.baton_ref and await self.baton_ref().commissioning.get_value()
149
145
 
150
146
  async def raise_if_not_enabled(self) -> AccessError | None:
151
- """
152
- Asynchronously raises AccessError if gap access is disabled and not in commissioning mode.
147
+ """Asynchronously raises AccessError if gap access is disabled and not in
148
+ commissioning mode.
153
149
  """
154
150
  access_level = await self.gap_access.get_value()
155
151
  commissioning_mode = await self._is_commissioning_mode_enabled()
@@ -158,10 +154,19 @@ class BaseUndulator(StandardReadable, Movable[float], ABC):
158
154
 
159
155
 
160
156
  class UndulatorInKeV(BaseUndulator):
161
- """
162
- An Undulator-type insertion device, used to control photon emission at a given beam energy.
157
+ """An Undulator-type insertion device, used to control photon emission at a given
158
+ beam energy.
163
159
  This class expects energy [keV] passed in set method and does conversion to gap
164
160
  internally, for which it requires path to lookup table file in constructor.
161
+
162
+ Args:
163
+ prefix (str): PV prefix.
164
+ id_gap_lookup_table_path (str): Path to a lookup table file.
165
+ poles (int, optional): Number of magnetic poles built into the undulator.
166
+ length (float, optional): Length of the undulator in meters.
167
+ undulator_period(int, optional): Undulator period.
168
+ baton (Baton, optional): Baton object if provided.
169
+ name (str, optional): Name for device. Defaults to "".
165
170
  """
166
171
 
167
172
  def __init__(
@@ -174,18 +179,6 @@ class UndulatorInKeV(BaseUndulator):
174
179
  baton: Baton | None = None,
175
180
  name: str = "",
176
181
  ) -> None:
177
- """Constructor
178
-
179
- Args:
180
- prefix: PV prefix
181
- id_gap_lookup_table_path (str): Path to a lookup table file
182
- poles (int, optional): Number of magnetic poles built into the undulator
183
- length (float, optional): Length of the undulator in meters
184
- undulator_period(int, optional): Undulator period
185
- baton (optional): Baton object if provided.
186
- name (str, optional): Name for device. Defaults to "".
187
- """
188
-
189
182
  self.id_gap_lookup_table_path = id_gap_lookup_table_path
190
183
  super().__init__(
191
184
  prefix=prefix,
@@ -198,11 +191,10 @@ class UndulatorInKeV(BaseUndulator):
198
191
 
199
192
  @AsyncStatus.wrap
200
193
  async def set(self, value: float):
201
- """
202
- Check conditions and Set undulator gap to a given energy in keV
194
+ """Check conditions and Set undulator gap to a given energy in keV.
203
195
 
204
196
  Args:
205
- value: energy in keV
197
+ value (float): Energy in keV.
206
198
  """
207
199
  # Convert energy in keV to gap in mm first
208
200
  target_gap = await self._get_gap_to_match_energy(value)
@@ -212,9 +204,8 @@ class UndulatorInKeV(BaseUndulator):
212
204
  await self._set_gap(target_gap)
213
205
 
214
206
  async def _get_gap_to_match_energy(self, energy_kev: float) -> float:
215
- """
216
- get a 2d np.array from lookup table that
217
- converts energies to undulator gap distance
207
+ """Get a 2d np.array from lookup table that converts energies to undulator gap
208
+ distance.
218
209
  """
219
210
  energy_to_distance_table: np.ndarray = await energy_distance_table(
220
211
  self.id_gap_lookup_table_path
@@ -228,32 +219,27 @@ class UndulatorInKeV(BaseUndulator):
228
219
 
229
220
 
230
221
  class UndulatorInMm(BaseUndulator):
231
- """
232
- An Undulator-type insertion device, used to control photon emission.
222
+ """An Undulator-type insertion device, used to control photon emission.
233
223
  This class expects gap [mm] passed in set method.
224
+
225
+ Args:
226
+ value (float): Value in mm.
234
227
  """
235
228
 
236
229
  @AsyncStatus.wrap
237
230
  async def set(self, value: float):
238
- """
239
- Check conditions and Set undulator gap to a given value in mm
240
-
241
- Args:
242
- value: value in mm
243
- """
244
231
  await self._set_gap(value)
245
232
 
246
233
 
247
234
  class UndulatorOrder(StandardReadable, Locatable[int]):
248
- """
249
- Represents the order of an undulator device. Allows setting and locating the order.
235
+ """Represents the order of an undulator device. Allows setting and locating the
236
+ order.
237
+
238
+ Args:
239
+ name (str): Name for device. Defaults to ""
250
240
  """
251
241
 
252
242
  def __init__(self, name: str = "") -> None:
253
- """
254
- Args:
255
- name: Name for device. Defaults to ""
256
- """
257
243
  with self.add_children_as_readables():
258
244
  self.value = soft_signal_rw(int, initial_value=3)
259
245
  super().__init__(name=name)
@@ -1,5 +1,4 @@
1
- """
2
- All the methods in this module return a bluesky plan generator that adjusts a value
1
+ """All the methods in this module return a bluesky plan generator that adjusts a value
3
2
  according to some criteria either via feedback, preset positions, lookup tables etc.
4
3
  """
5
4
 
@@ -15,7 +14,7 @@ from dodal.log import LOGGER
15
14
  def lookup_table_adjuster(
16
15
  lookup_table: Callable[[float], float], output_device: Motor, input
17
16
  ):
18
- """Returns a callable that adjusts a value according to a lookup table"""
17
+ """Returns a callable that adjusts a value according to a lookup table."""
19
18
 
20
19
  def adjust(group=None) -> Generator[Msg, None, None]:
21
20
  setpoint = lookup_table(input)
@@ -16,7 +16,7 @@ def epics_signal_put_wait(pv_name: str, wait: float = 3.0) -> Component[EpicsSig
16
16
  """Creates a `Component` around an `EpicsSignal` that waits for a callback on a put.
17
17
 
18
18
  Args:
19
- pv_name (str): The name of the PV for the `EpicsSignal`
19
+ pv_name (str): The name of the PV for the `EpicsSignal`.
20
20
  wait (str, optional): The timeout to wait for a callback. Defaults to 3.0.
21
21
 
22
22
  Returns:
@@ -30,24 +30,24 @@ def run_functions_without_blocking(
30
30
  timeout: float = 60.0,
31
31
  associated_obj: OphydDevice | None = None,
32
32
  ) -> Status:
33
- """Creates and initiates an asynchronous chaining of functions which return a status
33
+ """Creates and initiates an asynchronous chaining of functions which return a status.
34
34
 
35
35
  Usage:
36
36
  This function can be used to take a series of status-returning functions and run
37
37
  them all sequentially and in the background by making use of callbacks. It also
38
- ensures exceptions on each returned status are propagated
38
+ ensures exceptions on each returned status are propagated.
39
39
 
40
40
  Args:
41
- functions_to_chain( list(function - > StatusBase) ): A list of functions which each
42
- return a status object
43
- associated_obj (Device | None): The device that should be associated with the
44
- returned status
41
+ functions_to_chain (Sequence(function - > StatusBase)): A list of functions
42
+ which each return a status object.
43
+ timeout (float, optional): The timeout period, defaults to 60.
44
+ associated_obj (OphydDevice, optional): The device that should be associated
45
+ with the returned status.
45
46
 
46
47
  Returns:
47
- Status: A status object which is marked as complete once all of the Status objects
48
- returned by the unwrapped functions have completed.
48
+ Status: A status object which is marked as complete once all of the Status
49
+ objects returned by the unwrapped functions have completed.
49
50
  """
50
-
51
51
  # The returned status - marked as finished at the end of the callback chain. If any
52
52
  # intermediate statuses have an exception, the full_status will timeout.
53
53
  full_status = Status(obj=associated_obj, timeout=timeout)
@@ -1,5 +1,4 @@
1
- """
2
- All the public methods in this module return a lookup table of some kind that
1
+ """All the public methods in this module return a lookup table of some kind that
3
2
  converts the source value s to a target value t for different values of s.
4
3
  """
5
4
 
@@ -18,19 +17,18 @@ async def energy_distance_table(
18
17
  comments: Sequence[str] = ["#", "Units"],
19
18
  skiprows: int = 0,
20
19
  ) -> np.ndarray:
21
- """
22
- Returns a numpy formatted lookup table for required positions of an ID gap to
20
+ """Returns a numpy formatted lookup table for required positions of an ID gap to
23
21
  provide emission at a given beam energy.
24
22
 
25
23
  Args:
26
- lookup_table_path: Path to lookup table
27
- comments: Lines starting with any of these strings will be ignored
28
- skiprows: Number of rows to skip at the start of the file
24
+ lookup_table_path (str): Path to lookup table.
25
+ comments (Sequence[str], optional): Lines starting with any of these strings
26
+ will be ignored.
27
+ skiprows (int, optional): Number of rows to skip at the start of the file.
29
28
 
30
29
  Returns:
31
- ndarray: Lookup table
30
+ ndarray: Lookup table.
32
31
  """
33
-
34
32
  # Slight cheat to make the file IO async, numpy doesn't do any real IO now, just
35
33
  # decodes the text
36
34
  async with aiofiles.open(lookup_table_path) as stream:
@@ -40,7 +38,8 @@ async def energy_distance_table(
40
38
 
41
39
  def parse_lookup_table(filename: str) -> list[Sequence]:
42
40
  """Parse a generic lookup table with a number of columns >= 2 and return a list \
43
- in column major order of the values in it."""
41
+ in column major order of the values in it.
42
+ """
44
43
  LOGGER.info(f"Parsing lookup table file {filename}")
45
44
 
46
45
  lut_vals = zip(*loadtxt(filename, comments=["#", "Units"]), strict=False)
@@ -53,7 +52,8 @@ def linear_interpolation_lut(
53
52
  """Returns a callable that converts values by linear interpolation of lookup table
54
53
  values.
55
54
 
56
- If the value falls outside the lookup table then the closest value will be used."""
55
+ If the value falls outside the lookup table then the closest value will be used.
56
+ """
57
57
  # numpy interp expects x-values to be increasing
58
58
  if not np.all(np.diff(s_values) > 0):
59
59
  LOGGER.info(
@@ -75,17 +75,16 @@ def linear_interpolation_lut(
75
75
  def linear_extrapolation_lut(
76
76
  s_values: Sequence[float], t_values: Sequence[float]
77
77
  ) -> Callable[[float], float]:
78
- """
79
- Return a callable that implements f(s) = t according to the conversion table data
80
- supplied, with linear extrapolation outside that range. Inside the range of the table,
81
- the function is equivalent to that returned by linear_interpolation_lut
78
+ """Return a callable that implements f(s) = t according to the conversion table data
79
+ supplied, with linear extrapolation outside that range. Inside the range of the
80
+ table, the function is equivalent to that returned by linear_interpolation_lut.
82
81
 
83
82
  Args:
84
- s_values: Values of the independent axis
85
- t_values: Values of the dependent axis
83
+ s_values (Sequence[float]): Values of the independent axis.
84
+ t_values (Sequence[float]): Values of the dependent axis.
86
85
 
87
86
  Returns:
88
- A callable that returns t for the given s
87
+ Callable: A callable that returns t for the given s.
89
88
  """
90
89
  assert len(s_values) == len(t_values), (
91
90
  "Lookup table does not have the same number of values for each axis"
dodal/devices/v2f.py CHANGED
@@ -20,9 +20,8 @@ class V2FGain(StrictEnum):
20
20
 
21
21
 
22
22
  class QDV2F(StandardReadable):
23
- """
24
- A Quantum Detectors V2F low noise voltage to frequency converter.
25
- Two channel V2F - 50mHz
23
+ """A Quantum Detectors V2F low noise voltage to frequency converter.
24
+ Two channel V2F - 50mHz.
26
25
  """
27
26
 
28
27
  def __init__(
@@ -18,7 +18,7 @@ class WatsonMarlow323PumpState(StrictEnum):
18
18
 
19
19
 
20
20
  class WatsonMarlow323Pump(StandardReadable):
21
- """Watson Marlow 323 Peristaltic Pump device"""
21
+ """Watson Marlow 323 Peristaltic Pump device."""
22
22
 
23
23
  def __init__(self, prefix: str, name: str = "") -> None:
24
24
  with self.add_children_as_readables():
@@ -13,8 +13,9 @@ class Pause(StrictEnum):
13
13
 
14
14
 
15
15
  class XBPMFeedback(Device, Triggerable):
16
- """The XBPM feedback device is an IOC that moves the DCM, HFM and VFM to automatically
17
- hold the beam into place, as measured by the XBPM sensor."""
16
+ """The XBPM feedback device is an IOC that moves the DCM, HFM and VFM to
17
+ automatically hold the beam into place, as measured by the XBPM sensor.
18
+ """
18
19
 
19
20
  def __init__(self, prefix: str, name: str = "", baton: Baton | None = None) -> None:
20
21
  self.pos_ok = epics_signal_r(float, prefix + "XBPM2POSITION_OK")
@@ -56,19 +56,16 @@ class DetectorState(StrictEnum):
56
56
  class Xspress3(Device, Stageable):
57
57
  """Xpress/XpressMini is a region of interest (ROI) picker that sums the detector
58
58
  output into a scaler with user-defined regions. It is often used as a signal
59
- discriminator to provide better energy resolution and signal to noise in X-ray detection experiments.
59
+ discriminator to provide better energy resolution and signal to noise in X-ray
60
+ detection experiments.
60
61
  This currently only provide staging functionality.
61
62
 
62
- Parameters
63
- ----------
64
- prefix:
65
- Beamline part of PV
66
- name:
67
- Name of the device
68
- num_channels:
69
- Number of channel xspress3 has, default is 1 for mini.
70
- timeout:
71
- How long to wait for before timing out for staging/arming of detector default is 1 sec
63
+ Args:
64
+ prefix (str): Beamline part of PV.
65
+ name (str, optional): Name of the device.
66
+ num_channels (int): Number of channel xspress3 has, default is 1 for mini.
67
+ timeout (float): How long to wait for before timing out for staging/arming of
68
+ detector, the default is 1 sec.
72
69
  """
73
70
 
74
71
  def __init__(
@@ -8,9 +8,8 @@ class AcquireState(StrictEnum):
8
8
 
9
9
 
10
10
  class Xspress3Channel(Device):
11
- """
12
- Xspress3 Channel contains the truncated detector data and its collection conditions
13
- including the definition of ROI(region of interest).
11
+ """Xspress3 Channel contains the truncated detector data and its collection conditions
12
+ including the definition of ROI(region of interest).
14
13
  """
15
14
 
16
15
  def __init__(self, prefix: str, name: str = "") -> None:
@@ -30,9 +29,7 @@ class Xspress3Channel(Device):
30
29
 
31
30
 
32
31
  class Xspress3ROIChannel(Device):
33
- """
34
- This is the Xspress3 multi-channel analyzer range
35
- """
32
+ """This is the Xspress3 multi-channel analyzer range."""
36
33
 
37
34
  def __init__(self, prefix: str, name: str = "") -> None:
38
35
  self.roi_start_x = epics_signal_rw(int, prefix + "MinX")
@@ -60,9 +60,8 @@ class I23Axes:
60
60
 
61
61
 
62
62
  class RotationDirection(StrictEnum):
63
- """
64
- Defines for a swept angle whether the scan width (sweep) is to be added or subtracted from
65
- the initial angle to obtain the final angle.
63
+ """Defines for a swept angle whether the scan width (sweep) is to be added or
64
+ subtracted from the initial angle to obtain the final angle.
66
65
  """
67
66
 
68
67
  POSITIVE = "Positive"
@@ -105,7 +104,8 @@ class InstantArmMock(DeviceMock["ArmingDevice"]):
105
104
  @default_mock_class(InstantArmMock)
106
105
  class ArmingDevice(StandardReadable, Movable[ArmDemand]):
107
106
  """A useful device that can abstract some of the logic of arming.
108
- Allows a user to just call arm.set(ArmDemand.ARM)"""
107
+ Allows a user to just call arm.set(ArmDemand.ARM).
108
+ """
109
109
 
110
110
  TIMEOUT: float = 3
111
111
 
@@ -230,7 +230,7 @@ class LogicGateConfigurer(StandardReadable):
230
230
  """Uses the specified `LogicGateConfiguration` to configure a gate on the Zebra.
231
231
 
232
232
  Args:
233
- type (GateType): The type of gate e.g. AND/OR
233
+ type (GateType): The type of gate e.g. AND/OR.
234
234
  gate_number (int): Which gate to configure.
235
235
  config (LogicGateConfiguration): A configuration for the gate.
236
236
  """
@@ -268,8 +268,7 @@ class LogicGateConfiguration:
268
268
 
269
269
  Args:
270
270
  input_source (int): The source for the input (must be between 0 and 63).
271
- invert (bool, optional): Whether the input should be inverted. Default
272
- False.
271
+ invert (bool, optional): Whether the input should be inverted. Default False.
273
272
 
274
273
  Returns:
275
274
  LogicGateConfiguration: A description of the gate configuration.