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
@@ -41,10 +41,24 @@ class AbstractAnalyserDriverIO(
41
41
  Movable[TAbstractBaseRegion],
42
42
  Generic[TAbstractBaseRegion, TAcquisitionMode, TLensMode, TPsuMode, TPassEnergy],
43
43
  ):
44
- """
45
- Driver device that defines signals and readables that should be common to all
44
+ """Driver device that defines signals and readables that should be common to all
46
45
  electron analysers. Implementations of electron analyser devices should inherit
47
46
  from this class and define additional specialised signals and methods.
47
+
48
+ Args:
49
+ prefix (str): Base PV to connect to EPICS for this device.
50
+ acquisition_mode_type (type[TAcquisitionMode]): Enum that determines the
51
+ available acquisition modes for this device.
52
+ lens_mode_type (type[TLensMode]): Enum that determines the available lens
53
+ mode for this device.
54
+ psu_mode_type (type[TPsuMode]): Enum that determines the available psu modes
55
+ for this device.
56
+ pass_energy_type (type[TPassEnergy]): Can be enum or float, depending on
57
+ electron analyser model. If enum, it determines the available pass
58
+ energies for this device.
59
+ energy_source: Device that can give us the correct excitation energy (in eV)
60
+ and switch sources if applicable.
61
+ name (str, optional): Name of the device.
48
62
  """
49
63
 
50
64
  def __init__(
@@ -56,24 +70,6 @@ class AbstractAnalyserDriverIO(
56
70
  pass_energy_type: type[TPassEnergy],
57
71
  name: str = "",
58
72
  ) -> None:
59
- """
60
- Constructor method for setting up electron analyser.
61
-
62
- Args:
63
- prefix: Base PV to connect to EPICS for this device.
64
- acquisition_mode_type: Enum that determines the available acquisition modes
65
- for this device.
66
- lens_mode_type: Enum that determines the available lens mode for this
67
- device.
68
- psu_mode_type: Enum that determines the available psu modes for this device.
69
- pass_energy_type: Can be enum or float, depends on electron analyser model.
70
- If enum, it determines the available pass energies for
71
- this device.
72
- energy_source: Device that can give us the correct excitation energy and
73
- switch sources if applicable.
74
- (in eV).
75
- name: Name of the device.
76
- """
77
73
  self.acquisition_mode_type = acquisition_mode_type
78
74
  self.lens_mode_type = lens_mode_type
79
75
  self.psu_mode_type = psu_mode_type
@@ -140,33 +136,31 @@ class AbstractAnalyserDriverIO(
140
136
  @abstractmethod
141
137
  @AsyncStatus.wrap
142
138
  async def set(self, epics_region: TAbstractBaseRegion):
143
- """
144
- Move a group of signals defined in a region. Each implementation of this class
145
- is responsible for implementing this method correctly.
139
+ """Move a group of signals defined in a region. Each implementation of this
140
+ class is responsible for implementing this method correctly.
146
141
 
147
142
  Args:
148
- region: Contains the parameters to setup the driver for a scan.
143
+ epics_region (TAbstractBaseRegion): Contains the parameters to setup the
144
+ driver for a scan.
149
145
  """
150
146
 
151
147
  @abstractmethod
152
148
  def _create_angle_axis_signal(self, prefix: str) -> SignalR[Array1D[np.float64]]:
153
- """
154
- The signal that defines the angle axis. Depends on analyser model.
149
+ """The signal that defines the angle axis. Depends on analyser model.
155
150
 
156
151
  Args:
157
- prefix: PV string used for connecting to angle axis.
152
+ prefix (str): PV string used for connecting to angle axis.
158
153
 
159
154
  Returns:
160
- Signal that can give us angle axis array data.
155
+ SignalR that can give us angle axis array data.
161
156
  """
162
157
 
163
158
  @abstractmethod
164
159
  def _create_energy_axis_signal(self, prefix: str) -> SignalR[Array1D[np.float64]]:
165
- """
166
- The signal that defines the energy axis. Depends on analyser model.
160
+ """The signal that defines the energy axis. Depends on analyser model.
167
161
 
168
162
  Args:
169
- prefix: PV string used for connecting to energy axis.
163
+ prefix (str): PV string used for connecting to energy axis.
170
164
 
171
165
  Returns:
172
166
  Signal that can give us energy axis array data.
@@ -178,16 +172,16 @@ class AbstractAnalyserDriverIO(
178
172
  excitation_energy: float,
179
173
  energy_mode: EnergyMode,
180
174
  ) -> Array1D[np.float64]:
181
- """
182
- Calculate the binding energy axis to calibrate the spectra data. Function for a
183
- derived signal.
175
+ """Calculate the binding energy axis to calibrate the spectra data. Function for
176
+ a derived signal.
184
177
 
185
178
  Args:
186
- energy_axis: Array data of the original energy_axis from epics.
187
- excitation_energy: The excitation energy value used for the scan of this
188
- region.
189
- energy_mode: The energy_mode of the region that was used for the scan
190
- of this region.
179
+ energy_axis (Array1D[np.float64]): Array data of the original energy_axis
180
+ from epics.
181
+ excitation_energy (float): The excitation energy value used for the scan of
182
+ this region.
183
+ energy_mode (EnergyMode): The energy_mode of the region that was used for
184
+ the scan of this region.
191
185
 
192
186
  Returns:
193
187
  Array that is the correct axis for the spectra data.
@@ -205,17 +199,16 @@ class AbstractAnalyserDriverIO(
205
199
  def _calculate_total_time(
206
200
  self, total_steps: int, step_time: float, iterations: int
207
201
  ) -> float:
208
- """
209
- Calulcate the total time the scan takes for this region. Function for a derived
210
- signal.
202
+ """Calulcate the total time the scan takes for this region. Function for a
203
+ derived signal.
211
204
 
212
205
  Args:
213
- total_steps: Number of steps for the region.
214
- step_time: Time for each step for the region.
215
- iterations: The number of iterations the region collected data for.
206
+ total_steps (int): Number of steps for the region.
207
+ step_time (float): Time for each step for the region.
208
+ iterations (int): The number of iterations the region collected data for.
216
209
 
217
210
  Returns:
218
- Calculated total time in seconds.
211
+ Float: Calculated total time in seconds.
219
212
  """
220
213
  return total_steps * step_time * iterations
221
214
 
@@ -28,11 +28,13 @@ TPsuMode = TypeVar("TPsuMode", bound=AnyPsuMode)
28
28
 
29
29
 
30
30
  def java_to_python_case(java_str: str) -> str:
31
- """
32
- Convert a camelCase Java-style string to a snake_case Python-style string.
31
+ """Convert a camelCase Java-style string to a snake_case Python-style string.
32
+
33
+ Args:
34
+ java_str (str): The Java-style camelCase string.
33
35
 
34
- :param java_str: The Java-style camelCase string.
35
- :return: The Python-style snake_case string.
36
+ Returns:
37
+ str: The Python-style snake_case string.
36
38
  """
37
39
  new_value = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", java_str)
38
40
  new_value = re.sub("([a-z0-9])([A-Z])", r"\1_\2", new_value).lower()
@@ -67,9 +69,8 @@ class AbstractBaseRegion(
67
69
  JavaToPythonModel,
68
70
  Generic[TAcquisitionMode, TLensMode, TPassEnergy],
69
71
  ):
70
- """
71
- Generic region model that holds the data. Specialised region models should inherit
72
- this to extend functionality. All energy units are assumed to be in eV.
72
+ """Generic region model that holds the data. Specialised region models should
73
+ inherit this to extend functionality. All energy units are assumed to be in eV.
73
74
  """
74
75
 
75
76
  name: str = "New_region"
@@ -89,15 +90,11 @@ class AbstractBaseRegion(
89
90
  energy_mode: EnergyMode = EnergyMode.KINETIC
90
91
 
91
92
  def is_binding_energy(self) -> bool:
92
- """
93
- Returns true if the energy_mode is binding.
94
- """
93
+ """Returns true if the energy_mode is binding."""
95
94
  return self.energy_mode == EnergyMode.BINDING
96
95
 
97
96
  def is_kinetic_energy(self) -> bool:
98
- """
99
- Returns true if the energy_mode is kinetic.
100
- """
97
+ """Returns true if the energy_mode is kinetic."""
101
98
  return self.energy_mode == EnergyMode.KINETIC
102
99
 
103
100
  def switch_energy_mode(
@@ -106,19 +103,18 @@ class AbstractBaseRegion(
106
103
  excitation_energy: float,
107
104
  copy: bool = True,
108
105
  ) -> Self:
109
- """
110
- Get a region with a new energy mode: Kinetic or Binding.
106
+ """Get a region with a new energy mode: Kinetic or Binding.
111
107
  It caculates new values for low_energy, centre_energy, high_energy, via the
112
108
  excitation enerrgy. It doesn't calculate anything if the region is already of
113
109
  the same energy mode.
114
110
 
115
- Parameters:
116
- energy_mode: Mode you want to switch the region to.
117
- excitation_energy: Energy conversion for low_energy, centre_energy, and
118
- high_energy for new energy mode.
119
- copy: Defaults to True. If true, create a copy of this region to alter for
120
- the new energy_mode and return it. If False, alter this region for the
121
- energy_mode and return it self.
111
+ Args:
112
+ energy_mode (EnergyMode): Mode you want to switch the region to.
113
+ excitation_energy (float): Energy conversion for low_energy, centre_energy,
114
+ and high_energy for new energy mode.
115
+ copy (bool, optional): Defaults to True. If true, create a copy of this
116
+ region to alter for the new energy_mode and return it. If False, alter
117
+ this region for the energy_mode and return it self.
122
118
 
123
119
  Returns:
124
120
  Region with selected energy mode and new calculated energy values.
@@ -147,14 +143,16 @@ class AbstractBaseRegion(
147
143
  new values for low_energy, centre_energy, and high_energy while also preserving
148
144
  the original energy mode e.g mode BINDING will stay as BINDING.
149
145
 
150
- Parameters:
151
- excitation_energy: Energy conversion for low_energy, centre_energy, and
152
- high_energy for new energy mode.
153
- copy: Defaults to True. If true, create a copy of this region to alter to
154
- calculate new energy values to return. If false, alter this region.
146
+ Args:
147
+ excitation_energy (float): Energy conversion for low_energy, centre_energy,
148
+ and high_energy for new energy mode.
149
+ copy (bool, optional): Defaults to True. If true, create a copy of this
150
+ region to alter to calculate new energy values to return. If false,
151
+ alter this region.
152
+
155
153
  Returns:
156
154
  Region with selected original energy mode and new calculated KINETIC energy
157
- values for epics.
155
+ values for epics.
158
156
  """
159
157
  original_energy_mode = self.energy_mode
160
158
  r = self.switch_energy_mode(EnergyMode.KINETIC, excitation_energy, copy)
@@ -177,8 +175,7 @@ class AbstractBaseSequence(
177
175
  JavaToPythonModel,
178
176
  Generic[TAbstractBaseRegion],
179
177
  ):
180
- """
181
- Generic sequence model that holds the list of region data. Specialised sequence
178
+ """Generic sequence model that holds the list of region data. Specialised sequence
182
179
  models should inherit this to extend functionality and define type of region to
183
180
  hold.
184
181
  """
@@ -4,15 +4,16 @@ from dodal.devices.electron_analyser.base.base_enums import EnergyMode
4
4
  def to_kinetic_energy(
5
5
  value: float, value_mode: EnergyMode, excitation_energy: float
6
6
  ) -> float:
7
- """
8
- Convert a value that is binding energy to kinetic energy.
9
- Parameters:
10
- value: The value to convert.
11
- value_mode: Energy mode of the value. If it is already kinetic, return the
12
- same value. If it is binding, convert to kinetic.
13
- excitation_energy: Value to calculate the conversion.
7
+ """Convert a value that is binding energy to kinetic energy.
8
+
9
+ Args:
10
+ value (float): The value to convert.
11
+ value_mode (EnergyMode): Energy mode of the value. If it is already kinetic,
12
+ return the same value. If it is binding, convert to kinetic.
13
+ excitation_energy (float): Value to calculate the conversion.
14
+
14
15
  Returns:
15
- Caluclated kinetic energy value
16
+ float: Caluclated kinetic energy value.
16
17
  """
17
18
  return value if value_mode == EnergyMode.KINETIC else excitation_energy - value
18
19
 
@@ -20,14 +21,15 @@ def to_kinetic_energy(
20
21
  def to_binding_energy(
21
22
  value: float, value_mode: EnergyMode, excitation_energy: float
22
23
  ) -> float:
23
- """
24
- Convert a value that is kinetic energy to binding energy.
25
- Parameters:
26
- value: The value to convert.
27
- value_mode: Energy mode of the value. If it is already binding, return the
28
- same value. If it is kinetic, convert to binding.
29
- excitation_energy: Value to calculate the conversion.
24
+ """Convert a value that is kinetic energy to binding energy.
25
+
26
+ Args:
27
+ value (float): The value to convert.
28
+ value_mode (EnergyMode): Energy mode of the value. If it is already binding,
29
+ return the same value. If it is kinetic, convert to binding.
30
+ excitation_energy (float): Value to calculate the conversion.
31
+
30
32
  Returns:
31
- Caluclated binding energy value
33
+ float: Caluclated binding energy value.
32
34
  """
33
35
  return value if value_mode == EnergyMode.BINDING else excitation_energy - value
@@ -14,9 +14,8 @@ from dodal.devices.selectable_source import SelectedSource, get_obj_from_selecte
14
14
 
15
15
 
16
16
  class AbstractEnergySource(StandardReadable):
17
- """
18
- Abstract device that wraps an energy source signal and provides common interface via
19
- a energy signal.
17
+ """Abstract device that wraps an energy source signal and provides common interface
18
+ via a energy signal.
20
19
  """
21
20
 
22
21
  def __init__(self, name: str = "") -> None:
@@ -25,14 +24,11 @@ class AbstractEnergySource(StandardReadable):
25
24
  @property
26
25
  @abstractmethod
27
26
  def energy(self) -> SignalR[float]:
28
- """
29
- Signal to provide the excitation energy value in eV.
30
- """
27
+ """Signal to provide the excitation energy value in eV."""
31
28
 
32
29
 
33
30
  class EnergySource(AbstractEnergySource):
34
- """
35
- Wraps a signal that relates to energy and provides common interface via energy
31
+ """Wraps a signal that relates to energy and provides common interface via energy
36
32
  signal. It provides the name of the wrapped signal as a child signal in the
37
33
  read_configuration via wrapped_device_name and adds the signal as a readable.
38
34
  """
@@ -59,11 +55,17 @@ def get_float_from_selected_source(
59
55
 
60
56
 
61
57
  class DualEnergySource(AbstractEnergySource):
62
- """
63
- Holds two EnergySource devices and provides a signal to read energy depending on
58
+ """Holds two EnergySource devices and provides a signal to read energy depending on
64
59
  which source is selected. The energy is the one that corrosponds to the
65
60
  selected_source signal. For example, selected_source is source1 if selected_source
66
- is at SelectedSource.SOURCE1 and vise versa for source2 and SelectedSource.SOURCE2.
61
+ is at SelectedSource.SOURCE1 and vise versa for source2 and
62
+ SelectedSource.SOURCE2.
63
+
64
+ Args:
65
+ source1 (SignalR): Energy source that corrosponds to SelectedSource.SOURCE1.
66
+ source2 (SignalR): Energy source that corrosponds to SelectedSource.SOURCE2.
67
+ selected_source (SignalRW): Signal that decides the active energy source.
68
+ name (str, optional): Name of this device.
67
69
  """
68
70
 
69
71
  def __init__(
@@ -73,14 +75,6 @@ class DualEnergySource(AbstractEnergySource):
73
75
  selected_source: SignalRW[SelectedSource],
74
76
  name: str = "",
75
77
  ):
76
- """
77
- Args:
78
- source1: Energy source that corrosponds to SelectedSource.SOURCE1.
79
- source2: Energy source that corrosponds to SelectedSource.SOURCE2.
80
- selected_source: Signal that decides the active energy source.
81
- name: Name of this device.
82
- """
83
-
84
78
  self.selected_source_ref = Reference(selected_source)
85
79
  with self.add_children_as_readables():
86
80
  self.source1 = EnergySource(source1)
@@ -37,7 +37,7 @@ _EUROTHERM_RBV: str = ":RBV"
37
37
 
38
38
 
39
39
  class EurothermPID(StandardReadable):
40
- """The class for the Eurotherm PID values"""
40
+ """The class for the Eurotherm PID values."""
41
41
 
42
42
  def __init__(
43
43
  self,
@@ -111,7 +111,8 @@ class UpdatingEurothermGeneral(EurothermGeneral):
111
111
 
112
112
  class EurothermAutotune(StandardReadable):
113
113
  """Newer versions of Eurotherm controllers have the ability to Autotune the
114
- PID values, and this is the device"""
114
+ PID values, and this is the device.
115
+ """
115
116
 
116
117
  def __init__(
117
118
  self,
@@ -44,34 +44,32 @@ class GridAxis:
44
44
  full_steps: int
45
45
 
46
46
  def steps_to_motor_position(self, steps):
47
- """Gives the motor position based on steps, where steps are 0 indexed"""
47
+ """Gives the motor position based on steps, where steps are 0 indexed."""
48
48
  return self.start + self.step_size_mm * steps
49
49
 
50
50
  @property
51
51
  def end(self):
52
- """Gives the point where the final frame is taken"""
52
+ """Gives the point where the final frame is taken."""
53
53
  # Note that full_steps is one indexed e.g. if there is one step then the end is
54
54
  # refering to the first position
55
55
  return self.steps_to_motor_position(self.full_steps - 1)
56
56
 
57
57
  def is_within(self, steps: float):
58
- """
59
- Determine whether a single axis coordinate is within the grid.
58
+ """Determine whether a single axis coordinate is within the grid.
60
59
  The coordinate is from a continuous coordinate space based on the
61
60
  XRC grid where the origin corresponds to the centre of the first grid box.
62
61
 
63
62
  Args:
64
- steps: The coordinate to check
63
+ steps (float): The coordinate to check.
65
64
 
66
65
  Returns:
67
- True if the coordinate falls within the grid.
66
+ bool: True if the coordinate falls within the grid.
68
67
  """
69
68
  return -0.5 <= steps <= self.full_steps - 0.5
70
69
 
71
70
 
72
71
  class GridScanParamsCommon(AbstractExperimentWithBeamParams):
73
- """
74
- Common holder class for the parameters of a grid scan in a similar
72
+ """Common holder class for the parameters of a grid scan in a similar
75
73
  layout to EPICS. The parameters and functions of this class are common
76
74
  to both the zebra and panda triggered fast grid scans in 2d or 3d.
77
75
 
@@ -108,10 +106,12 @@ class GridScanParamsCommon(AbstractExperimentWithBeamParams):
108
106
  to a real motor position.
109
107
 
110
108
  Args:
111
- grid_position: The x, y, z position in grid steps. The origin is at the
112
- centre of the first grid box
109
+ grid_position (ndarray): The x, y, z position in grid steps. The origin is
110
+ at the centre of the first grid box
111
+
113
112
  Returns:
114
- The motor position this corresponds to.
113
+ ndarray: The motor position this corresponds to.
114
+
115
115
  Raises:
116
116
  IndexError if the desired position is outside the grid.
117
117
  """
@@ -133,8 +133,8 @@ class GridScanParamsCommon(AbstractExperimentWithBeamParams):
133
133
  class GridScanParamsThreeD(GridScanParamsCommon):
134
134
  """Additional parameters required to do a 3 dimensional gridscan.
135
135
 
136
- A 3D gridscan works by doing two 2D gridscans. The first of these grids is x_steps by
137
- y_steps. The sample is then rotated by 90 degrees, and then the second grid is
136
+ A 3D gridscan works by doing two 2D gridscans. The first of these grids is x_steps
137
+ by y_steps. The sample is then rotated by 90 degrees, and then the second grid is
138
138
  x_steps by z_steps.
139
139
  """
140
140
 
@@ -173,16 +173,13 @@ class WithDwellTime(BaseModel):
173
173
 
174
174
 
175
175
  class ZebraGridScanParamsThreeD(GridScanParamsThreeD, WithDwellTime):
176
- """
177
- Params for standard Zebra FGS. Adds on the dwell time, which is really the time
176
+ """Params for standard Zebra FGS. Adds on the dwell time, which is really the time
178
177
  between trigger positions.
179
178
  """
180
179
 
181
180
 
182
181
  class PandAGridScanParams(GridScanParamsThreeD):
183
- """
184
- Params for panda constant-motion scan. Adds on the goniometer run-up distance
185
- """
182
+ """Params for panda constant-motion scan. Adds on the goniometer run-up distance."""
186
183
 
187
184
  run_up_distance_mm: float = 0.17
188
185
 
@@ -203,8 +200,8 @@ class FastGridScanCommon(
203
200
  ):
204
201
  """Device containing the minimal signals for a general fast grid scan.
205
202
 
206
- When the motion program is started, the goniometer will move in a snake-like grid trajectory,
207
- with X as the fast axis and Y as the slow axis.
203
+ When the motion program is started, the goniometer will move in a snake-like grid
204
+ trajectory, with X as the fast axis and Y as the slow axis.
208
205
 
209
206
  See ZebraFastGridScanThreeD as an example of how to implement.
210
207
  """
@@ -297,14 +294,14 @@ class FastGridScanCommon(
297
294
 
298
295
  @AsyncStatus.wrap
299
296
  async def prepare(self, value: ParamType):
300
- """
301
- Submit the gridscan parameters to the device for validation prior to
302
- gridscan kickoff
297
+ """Submit the gridscan parameters to the device for validation prior to
298
+ gridscan kickoff.
299
+
303
300
  Args:
304
- value: the gridscan parameters
301
+ value (ParamType): The gridscan parameters.
305
302
 
306
303
  Raises:
307
- GridScanInvalidError: if the gridscan parameters were not valid
304
+ GridScanInvalidError: If the gridscan parameters were not valid.
308
305
  """
309
306
  set_statuses = []
310
307
 
@@ -426,8 +423,8 @@ class FastGridScanThreeD(FastGridScanCommon[ParamType]):
426
423
  class ZebraFastGridScanThreeD(FastGridScanThreeD[ZebraGridScanParamsThreeD]):
427
424
  """Device for standard Zebra 3D FGS.
428
425
 
429
- In this scan, the goniometer's velocity profile follows a parabolic shape between X steps,
430
- with the slowest points occuring at each X step.
426
+ In this scan, the goniometer's velocity profile follows a parabolic shape between X
427
+ steps, with the slowest points occuring at each X step.
431
428
  """
432
429
 
433
430
  def __init__(self, prefix: str, name: str = "") -> None:
@@ -448,8 +445,8 @@ class ZebraFastGridScanThreeD(FastGridScanThreeD[ZebraGridScanParamsThreeD]):
448
445
  class PandAFastGridScan(FastGridScanThreeD[PandAGridScanParams]):
449
446
  """Device for panda constant-motion scan.
450
447
 
451
- In this scan, the goniometer's velocity
452
- is constant through each row. It doesn't slow down when going through trigger points.
448
+ In this scan, the goniometer's velocity is constant through each row. It doesn't
449
+ slow down when going through trigger points.
453
450
  """
454
451
 
455
452
  def __init__(self, prefix: str, name: str = "") -> None:
@@ -475,13 +472,13 @@ class PandAFastGridScan(FastGridScanThreeD[PandAGridScanParams]):
475
472
 
476
473
 
477
474
  def set_fast_grid_scan_params(scan: FastGridScanCommon[ParamType], params: ParamType):
478
- """
479
- Apply the fast grid scan parameters to the grid scan device and validate them
475
+ """Apply the fast grid scan parameters to the grid scan device and validate them.
476
+
480
477
  Args:
481
- scan: The fast grid scan device
482
- params: The parameters to set
478
+ scan (FastGridScancommon[ParamType]): The fast grid scan device.
479
+ params (ParamType): The parameters to set.
483
480
 
484
481
  Raises:
485
- GridScanInvalidError: if the grid scan parameters are not valid
482
+ GridScanInvalidError: if the grid scan parameters are not valid.
486
483
  """
487
484
  yield from prepare(scan, params, wait=True)
@@ -19,15 +19,17 @@ EnumTypesT = TypeVar("EnumTypesT", bound=EnumTypes)
19
19
 
20
20
 
21
21
  class FastShutter(Movable[EnumTypesT], Protocol, Generic[EnumTypesT]):
22
- """
23
- Enum device specialised for a fast shutter with configured open_state and
22
+ """Enum device specialised for a fast shutter with configured open_state and
24
23
  close_state so it is generic enough to be used with any device or plan without
25
24
  knowing the specific enum to use.
26
25
 
27
- For example:
26
+ For example::
27
+
28
28
  await shutter.set(shutter.open_state)
29
29
  await shutter.set(shutter.close_state)
30
- OR
30
+
31
+ OR::
32
+
31
33
  run_engine(bps.mv(shutter, shutter.open_state))
32
34
  run_engine(bps.mv(shutter, shutter.close_state))
33
35
  """
@@ -44,9 +46,16 @@ class FastShutter(Movable[EnumTypesT], Protocol, Generic[EnumTypesT]):
44
46
  class GenericFastShutter(
45
47
  StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]
46
48
  ):
47
- """
48
- Implementation of fast shutter that connects to an epics pv. This pv is an enum that
49
+ """Implementation of fast shutter that connects to an epics pv. This pv is an enum that
49
50
  controls the open and close state of the shutter.
51
+
52
+ Args:
53
+ pv (str): The pv to connect to the shutter device.
54
+ open_state (EnumTypesT): The enum value that corresponds with opening the
55
+ shutter.
56
+ close_state (EnumTypesT): The enum value that corresponds with closing the
57
+ shutter.
58
+ name (str, optional): The name of the shutter.
50
59
  """
51
60
 
52
61
  def __init__(
@@ -56,12 +65,6 @@ class GenericFastShutter(
56
65
  close_state: EnumTypesT,
57
66
  name: str = "",
58
67
  ):
59
- """
60
- Arguments:
61
- pv: The pv to connect to the shutter device.
62
- open_state: The enum value that corresponds with opening the shutter.
63
- close_state: The enum value that corresponds with closing the shutter.
64
- """
65
68
  self.open_state = open_state
66
69
  self.close_state = close_state
67
70
  with self.add_children_as_readables():
@@ -70,12 +73,19 @@ class GenericFastShutter(
70
73
 
71
74
 
72
75
  class DualFastShutter(StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]):
73
- """
74
- A fast shutter device that handles the positions of two other fast shutters. The
76
+ """A fast shutter device that handles the positions of two other fast shutters. The
75
77
  "active" shutter is the one that corrosponds to the selected_shutter signal. For
76
78
  example, active shutter is shutter1 if selected_source is at SelectedSource.SOURCE1
77
79
  and vise versa for shutter2 and SelectedSource.SOURCE2. Whenever a move is done on
78
80
  this device, the inactive shutter is always set to the close_state.
81
+
82
+ Args:
83
+ shutter1 (GenericFastShutter): Active shutter that corrosponds to
84
+ SelectedSource.SOURCE1.
85
+ shutter2 (GenericFastShutter): Active shutter that corrosponds to
86
+ SelectedSource.SOURCE2.
87
+ selected_source (SignalRW): Signal that decides the active shutter.
88
+ name (str, optional): Name of this device.
79
89
  """
80
90
 
81
91
  def __init__(
@@ -85,13 +95,6 @@ class DualFastShutter(StandardReadable, FastShutter[EnumTypesT], Generic[EnumTyp
85
95
  selected_source: SignalRW[SelectedSource],
86
96
  name: str = "",
87
97
  ):
88
- """
89
- Arguments:
90
- shutter1: Active shutter that corrosponds to SelectedSource.SOURCE1.
91
- shutter2: Active shutter that corrosponds to SelectedSource.SOURCE2.
92
- selected_source: Signal that decides the active shutter.
93
- name: Name of this device.
94
- """
95
98
  self._validate_shutter_states(shutter1.open_state, shutter2.open_state)
96
99
  self._validate_shutter_states(shutter1.close_state, shutter2.close_state)
97
100
  self.open_state = shutter1.open_state
dodal/devices/flux.py CHANGED
@@ -6,7 +6,7 @@ from ophyd_async.epics.core import epics_signal_r
6
6
 
7
7
 
8
8
  class Flux(StandardReadable):
9
- """Simple device to get the flux reading"""
9
+ """Simple device to get the flux reading."""
10
10
 
11
11
  def __init__(self, prefix: str, name="") -> None:
12
12
  with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):