dls-dodal 1.68.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 (292) hide show
  1. {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/METADATA +1 -31
  2. dls_dodal-2.0.0.dist-info/RECORD +354 -0
  3. {dls_dodal-1.68.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 +40 -33
  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 +17 -45
  14. dodal/beamlines/i02_2.py +6 -12
  15. dodal/beamlines/i03.py +8 -5
  16. dodal/beamlines/i03_supervisor.py +19 -0
  17. dodal/beamlines/i04.py +87 -184
  18. dodal/beamlines/i05.py +9 -39
  19. dodal/beamlines/i05_1.py +4 -13
  20. dodal/beamlines/i05_shared.py +51 -0
  21. dodal/beamlines/i06_1.py +26 -0
  22. dodal/beamlines/{i06.py → i06_shared.py} +25 -14
  23. dodal/beamlines/i07.py +14 -16
  24. dodal/beamlines/i09.py +76 -29
  25. dodal/beamlines/i09_1.py +25 -56
  26. dodal/beamlines/i09_1_shared.py +61 -0
  27. dodal/beamlines/i09_2.py +6 -100
  28. dodal/beamlines/i09_2_shared.py +110 -0
  29. dodal/beamlines/i10.py +60 -54
  30. dodal/beamlines/i10_1.py +99 -10
  31. dodal/beamlines/{i10_optics.py → i10_shared.py} +80 -66
  32. dodal/beamlines/i11.py +31 -18
  33. dodal/beamlines/i13_1.py +1 -1
  34. dodal/beamlines/i15.py +6 -6
  35. dodal/beamlines/i15_1.py +6 -6
  36. dodal/beamlines/i16.py +11 -0
  37. dodal/beamlines/i17.py +37 -28
  38. dodal/beamlines/i18.py +3 -4
  39. dodal/beamlines/i19_1.py +95 -34
  40. dodal/beamlines/i19_2.py +68 -52
  41. dodal/beamlines/i19_optics.py +26 -13
  42. dodal/beamlines/i20_1.py +17 -11
  43. dodal/beamlines/i21.py +44 -29
  44. dodal/beamlines/i22.py +19 -4
  45. dodal/beamlines/i23.py +20 -27
  46. dodal/beamlines/i24.py +64 -113
  47. dodal/beamlines/k07.py +99 -5
  48. dodal/beamlines/p38.py +3 -3
  49. dodal/beamlines/p60.py +35 -14
  50. dodal/beamlines/p99.py +16 -15
  51. dodal/beamlines/training_rig.py +20 -12
  52. dodal/cli.py +36 -2
  53. dodal/common/__init__.py +2 -1
  54. dodal/common/beamlines/beamline_parameters.py +2 -1
  55. dodal/common/beamlines/beamline_utils.py +11 -9
  56. dodal/common/beamlines/commissioning_mode.py +6 -3
  57. dodal/common/coordination.py +12 -14
  58. dodal/common/crystal_metadata.py +5 -8
  59. dodal/common/device_utils.py +4 -3
  60. dodal/common/maths.py +87 -19
  61. dodal/common/udc_directory_provider.py +13 -8
  62. dodal/common/visit.py +18 -21
  63. dodal/common/watcher_utils.py +13 -12
  64. dodal/device_manager.py +94 -54
  65. dodal/devices/aperturescatterguard.py +26 -27
  66. dodal/devices/areadetector/plugins/cam.py +1 -3
  67. dodal/devices/areadetector/plugins/mjpg.py +6 -5
  68. dodal/devices/attenuator/attenuator.py +12 -11
  69. dodal/devices/beamlines/b07/__init__.py +3 -0
  70. dodal/devices/{b07_1 → beamlines/b07_1}/__init__.py +2 -2
  71. dodal/devices/{b07_1 → beamlines/b07_1}/ccmc.py +5 -10
  72. dodal/devices/{b16 → beamlines/b16}/detector.py +2 -3
  73. dodal/devices/{i02_1 → beamlines/i02_1}/fast_grid_scan.py +2 -3
  74. dodal/devices/{i02_1 → beamlines/i02_1}/sample_motors.py +1 -1
  75. dodal/devices/{i03 → beamlines/i03}/beamsize.py +11 -7
  76. dodal/devices/{i03 → beamlines/i03}/dcm.py +1 -2
  77. dodal/devices/{i03 → beamlines/i03}/undulator_dcm.py +4 -5
  78. dodal/devices/beamlines/i04/beam_centre.py +151 -0
  79. dodal/devices/{i04 → beamlines/i04}/beamsize.py +11 -7
  80. dodal/devices/beamlines/i04/max_pixel.py +25 -0
  81. dodal/devices/{i04 → beamlines/i04}/murko_results.py +23 -8
  82. dodal/devices/{i04 → beamlines/i04}/transfocator.py +10 -15
  83. dodal/devices/beamlines/i05/__init__.py +3 -0
  84. dodal/devices/beamlines/i06_shared/__init__.py +3 -0
  85. dodal/devices/beamlines/i06_shared/i06_enum.py +7 -0
  86. dodal/devices/{i07 → beamlines/i07}/dcm.py +2 -3
  87. dodal/devices/{i07 → beamlines/i07}/id.py +8 -9
  88. dodal/devices/beamlines/i09/__init__.py +3 -0
  89. dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_energy.py +5 -6
  90. dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/hard_undulator_functions.py +19 -16
  91. dodal/devices/{i10 → beamlines/i10}/diagnostics.py +4 -3
  92. dodal/devices/{i10 → beamlines/i10}/i10_apple2.py +37 -51
  93. dodal/devices/{i10 → beamlines/i10}/rasor/rasor_current_amp.py +1 -24
  94. dodal/devices/{i10 → beamlines/i10}/rasor/rasor_motors.py +2 -2
  95. dodal/devices/{i10 → beamlines/i10}/slits.py +5 -3
  96. dodal/devices/beamlines/i10_1/__init__.py +9 -0
  97. dodal/devices/beamlines/i10_1/electromagnet/magnet.py +16 -0
  98. dodal/devices/beamlines/i10_1/electromagnet/stages.py +14 -0
  99. dodal/devices/beamlines/i10_1/scaler_cards.py +13 -0
  100. dodal/devices/{i11 → beamlines/i11}/cyberstar_blower.py +1 -1
  101. dodal/devices/{i11 → beamlines/i11}/diff_stages.py +4 -6
  102. dodal/devices/{i11 → beamlines/i11}/mythen.py +3 -4
  103. dodal/devices/{i11 → beamlines/i11}/nx100robot.py +6 -6
  104. dodal/devices/{i11 → beamlines/i11}/spinner.py +1 -1
  105. dodal/devices/{i13_1 → beamlines/i13_1}/merlin.py +1 -1
  106. dodal/devices/{i15 → beamlines/i15}/dcm.py +1 -2
  107. dodal/devices/{i15 → beamlines/i15}/focussing_mirror.py +5 -5
  108. dodal/devices/{i15 → beamlines/i15}/jack.py +2 -2
  109. dodal/devices/{i15 → beamlines/i15}/multilayer_mirror.py +1 -1
  110. dodal/devices/{i17 → beamlines/i17}/i17_apple2.py +16 -22
  111. dodal/devices/{i18 → beamlines/i18}/diode.py +1 -1
  112. dodal/devices/{i19 → beamlines/i19}/access_controlled/attenuator_motor_squad.py +12 -8
  113. dodal/devices/{i19 → beamlines/i19}/access_controlled/blueapi_device.py +16 -15
  114. dodal/devices/beamlines/i19/access_controlled/piezo_control.py +72 -0
  115. dodal/devices/{i19 → beamlines/i19}/access_controlled/shutter.py +11 -9
  116. dodal/devices/{i19 → beamlines/i19}/backlight.py +3 -1
  117. dodal/devices/{i19 → beamlines/i19}/mapt_configuration.py +2 -1
  118. dodal/devices/{i19 → beamlines/i19}/pin_col_stages.py +11 -8
  119. dodal/devices/beamlines/i19/pin_tip.py +32 -0
  120. dodal/devices/beamlines/i21/__init__.py +3 -0
  121. dodal/devices/{i22 → beamlines/i22}/dcm.py +1 -2
  122. dodal/devices/{i22 → beamlines/i22}/fswitch.py +1 -3
  123. dodal/devices/{i22 → beamlines/i22}/nxsas.py +5 -4
  124. dodal/devices/{i24 → beamlines/i24}/beam_center.py +1 -1
  125. dodal/devices/{i24 → beamlines/i24}/beamstop.py +2 -2
  126. dodal/devices/{i24 → beamlines/i24}/commissioning_jungfrau.py +12 -12
  127. dodal/devices/{i24 → beamlines/i24}/dcm.py +1 -3
  128. dodal/devices/{i24 → beamlines/i24}/dual_backlight.py +3 -3
  129. dodal/devices/{i24 → beamlines/i24}/pmac.py +9 -7
  130. dodal/devices/{p60 → beamlines/p60}/lab_xray_source.py +1 -1
  131. dodal/devices/beamlines/p99/__init__.py +0 -0
  132. dodal/devices/{p99 → beamlines/p99}/andor2_point.py +11 -15
  133. dodal/devices/bimorph_mirror.py +22 -20
  134. dodal/devices/collimation_table.py +3 -2
  135. dodal/devices/common_dcm.py +30 -20
  136. dodal/devices/controllers.py +2 -2
  137. dodal/devices/cryostream.py +8 -0
  138. dodal/devices/current_amplifiers/current_amplifier.py +16 -18
  139. dodal/devices/current_amplifiers/current_amplifier_detector.py +9 -10
  140. dodal/devices/current_amplifiers/femto.py +8 -9
  141. dodal/devices/current_amplifiers/sr570.py +16 -16
  142. dodal/devices/current_amplifiers/struck_scaler_counter.py +5 -5
  143. dodal/devices/detector/det_resolution.py +9 -8
  144. dodal/devices/detector/detector.py +4 -2
  145. dodal/devices/diamond_filter.py +3 -4
  146. dodal/devices/eiger.py +32 -17
  147. dodal/devices/eiger_odin.py +1 -1
  148. dodal/devices/electron_analyser/base/__init__.py +3 -3
  149. dodal/devices/electron_analyser/base/base_controller.py +32 -21
  150. dodal/devices/electron_analyser/base/base_detector.py +15 -20
  151. dodal/devices/electron_analyser/base/base_driver_io.py +39 -46
  152. dodal/devices/electron_analyser/base/base_enums.py +0 -5
  153. dodal/devices/electron_analyser/base/base_region.py +29 -31
  154. dodal/devices/electron_analyser/base/base_util.py +18 -16
  155. dodal/devices/electron_analyser/base/energy_sources.py +35 -40
  156. dodal/devices/electron_analyser/specs/specs_detector.py +7 -6
  157. dodal/devices/electron_analyser/vgscienta/vgscienta_detector.py +7 -6
  158. dodal/devices/eurotherm.py +3 -2
  159. dodal/devices/fast_grid_scan.py +31 -34
  160. dodal/devices/fast_shutter.py +125 -39
  161. dodal/devices/flux.py +1 -1
  162. dodal/devices/focusing_mirror.py +29 -11
  163. dodal/devices/hutch_shutter.py +6 -6
  164. dodal/devices/insertion_device/__init__.py +20 -8
  165. dodal/devices/insertion_device/apple2_controller.py +371 -0
  166. dodal/devices/insertion_device/apple2_undulator.py +184 -587
  167. dodal/devices/insertion_device/apple_knot_controller.py +222 -0
  168. dodal/devices/insertion_device/energy.py +161 -0
  169. dodal/devices/insertion_device/energy_motor_lookup.py +21 -28
  170. dodal/devices/insertion_device/lookup_table_models.py +47 -52
  171. dodal/devices/insertion_device/polarisation.py +36 -0
  172. dodal/devices/ipin.py +1 -1
  173. dodal/devices/linkam3.py +7 -5
  174. dodal/devices/motors.py +107 -19
  175. dodal/devices/mx_phase1/beamstop.py +2 -4
  176. dodal/devices/oav/oav_calculations.py +20 -13
  177. dodal/devices/oav/oav_detector.py +92 -22
  178. dodal/devices/oav/oav_parameters.py +4 -9
  179. dodal/devices/oav/oav_to_redis_forwarder.py +22 -18
  180. dodal/devices/oav/pin_image_recognition/__init__.py +4 -6
  181. dodal/devices/oav/pin_image_recognition/manual_test.py +1 -2
  182. dodal/devices/oav/pin_image_recognition/utils.py +30 -32
  183. dodal/devices/oav/snapshots/grid_overlay.py +10 -9
  184. dodal/devices/oav/snapshots/snapshot_image_processing.py +15 -13
  185. dodal/devices/oav/utils.py +20 -6
  186. dodal/devices/p45.py +3 -9
  187. dodal/devices/pgm.py +8 -14
  188. dodal/devices/pressure_jump_cell.py +93 -32
  189. dodal/devices/qbpm.py +1 -3
  190. dodal/devices/robot.py +45 -20
  191. dodal/devices/s4_slit_gaps.py +1 -1
  192. dodal/devices/selectable_source.py +41 -0
  193. dodal/devices/slits.py +2 -5
  194. dodal/devices/smargon.py +2 -3
  195. dodal/devices/temperture_controller/lakeshore/lakeshore.py +38 -64
  196. dodal/devices/temperture_controller/lakeshore/lakeshore_io.py +21 -35
  197. dodal/devices/tetramm.py +7 -7
  198. dodal/devices/turbo_slit.py +8 -7
  199. dodal/devices/undulator.py +42 -56
  200. dodal/devices/util/adjuster_plans.py +2 -3
  201. dodal/devices/util/epics_util.py +10 -10
  202. dodal/devices/util/lookup_tables.py +17 -18
  203. dodal/devices/v2f.py +2 -3
  204. dodal/devices/watsonmarlow323_pump.py +1 -1
  205. dodal/devices/xbpm_feedback.py +3 -2
  206. dodal/devices/xspress3/xspress3.py +8 -11
  207. dodal/devices/xspress3/xspress3_channel.py +3 -6
  208. dodal/devices/zebra/zebra.py +21 -7
  209. dodal/devices/zebra/zebra_constants_mapping.py +12 -7
  210. dodal/devices/zebra/zebra_controlled_shutter.py +2 -1
  211. dodal/devices/zocalo/zocalo_interaction.py +14 -14
  212. dodal/devices/zocalo/zocalo_results.py +33 -33
  213. dodal/log.py +23 -20
  214. dodal/plan_stubs/check_topup.py +15 -15
  215. dodal/plan_stubs/data_session.py +6 -6
  216. dodal/plan_stubs/motor_utils.py +22 -18
  217. dodal/plan_stubs/pressure_jump_cell.py +18 -0
  218. dodal/plan_stubs/wrapped.py +40 -55
  219. dodal/plans/bimorph.py +63 -52
  220. dodal/plans/configure_arm_trigger_and_disarm_detector.py +0 -1
  221. dodal/plans/device_setup_plans/__init__.py +5 -0
  222. dodal/plans/device_setup_plans/setup_pin_tip_params.py +63 -0
  223. dodal/plans/preprocessors/verify_undulator_gap.py +10 -8
  224. dodal/plans/spec_path.py +3 -5
  225. dodal/plans/verify_undulator_gap.py +1 -2
  226. dodal/plans/wrapped.py +4 -3
  227. dodal/testing/__init__.py +0 -0
  228. dodal/testing/electron_analyser/device_factory.py +5 -7
  229. dodal/testing/fixtures/devices/apple2.py +38 -0
  230. dodal/testing/fixtures/run_engine.py +3 -7
  231. dodal/testing/fixtures/utils.py +1 -2
  232. dodal/utils.py +60 -58
  233. dls_dodal-1.68.0.dist-info/RECORD +0 -330
  234. dodal/beamline_specific_utils/i05_shared.py +0 -14
  235. dodal/devices/b07/__init__.py +0 -3
  236. dodal/devices/i04/max_pixel.py +0 -38
  237. dodal/devices/i05/__init__.py +0 -3
  238. dodal/devices/i09/__init__.py +0 -3
  239. dodal/devices/i21/__init__.py +0 -5
  240. {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/entry_points.txt +0 -0
  241. {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/licenses/LICENSE +0 -0
  242. {dls_dodal-1.68.0.dist-info → dls_dodal-2.0.0.dist-info}/top_level.txt +0 -0
  243. /dodal/{beamline_specific_utils → devices/beamlines}/__init__.py +0 -0
  244. /dodal/devices/{b07 → beamlines/b07}/enums.py +0 -0
  245. /dodal/devices/{b07_1 → beamlines/b07_1}/enums.py +0 -0
  246. /dodal/devices/{b16 → beamlines/b16}/__init__.py +0 -0
  247. /dodal/devices/{i02_1 → beamlines/i02_1}/__init__.py +0 -0
  248. /dodal/devices/{i02_2 → beamlines/i02_2}/__init__.py +0 -0
  249. /dodal/devices/{i03 → beamlines/i03}/__init__.py +0 -0
  250. /dodal/devices/{i03 → beamlines/i03}/constants.py +0 -0
  251. /dodal/devices/{i04 → beamlines/i04}/__init__.py +0 -0
  252. /dodal/devices/{i04 → beamlines/i04}/constants.py +0 -0
  253. /dodal/devices/{i05 → beamlines/i05}/enums.py +0 -0
  254. /dodal/devices/{i07 → beamlines/i07}/__init__.py +0 -0
  255. /dodal/devices/{i09 → beamlines/i09}/enums.py +0 -0
  256. /dodal/devices/{i09_1 → beamlines/i09_1}/__init__.py +0 -0
  257. /dodal/devices/{i09_1 → beamlines/i09_1}/enums.py +0 -0
  258. /dodal/devices/{i09_1_shared → beamlines/i09_1_shared}/__init__.py +0 -0
  259. /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/__init__.py +0 -0
  260. /dodal/devices/{i09_2_shared → beamlines/i09_2_shared}/i09_apple2.py +0 -0
  261. /dodal/devices/{i10 → beamlines/i10}/__init__.py +0 -0
  262. /dodal/devices/{i10 → beamlines/i10}/i10_setting_data.py +0 -0
  263. /dodal/devices/{i10 → beamlines/i10}/mirrors.py +0 -0
  264. /dodal/devices/{i10 → beamlines/i10}/rasor/__init__.py +0 -0
  265. /dodal/devices/{i10 → beamlines/i10}/rasor/rasor_scaler_cards.py +0 -0
  266. /dodal/devices/{i11 → beamlines/i10_1/electromagnet}/__init__.py +0 -0
  267. /dodal/devices/{i13_1 → beamlines/i11}/__init__.py +0 -0
  268. /dodal/devices/{i15 → beamlines/i13_1}/__init__.py +0 -0
  269. /dodal/devices/{i13_1 → beamlines/i13_1}/merlin_controller.py +0 -0
  270. /dodal/devices/{i17 → beamlines/i15}/__init__.py +0 -0
  271. /dodal/devices/{i15 → beamlines/i15}/laue.py +0 -0
  272. /dodal/devices/{i15 → beamlines/i15}/motors.py +0 -0
  273. /dodal/devices/{i15 → beamlines/i15}/rail.py +0 -0
  274. /dodal/devices/{i18 → beamlines/i17}/__init__.py +0 -0
  275. /dodal/devices/{i19 → beamlines/i18}/__init__.py +0 -0
  276. /dodal/devices/{i18 → beamlines/i18}/kb_mirror.py +0 -0
  277. /dodal/devices/{i19/access_controlled → beamlines/i19}/__init__.py +0 -0
  278. /dodal/devices/{i20_1 → beamlines/i19/access_controlled}/__init__.py +0 -0
  279. /dodal/devices/{i19 → beamlines/i19}/access_controlled/hutch_access.py +0 -0
  280. /dodal/devices/{i19 → beamlines/i19}/beamstop.py +0 -0
  281. /dodal/devices/{i19 → beamlines/i19}/diffractometer.py +0 -0
  282. /dodal/devices/{i22 → beamlines/i20_1}/__init__.py +0 -0
  283. /dodal/devices/{i21 → beamlines/i21}/enums.py +0 -0
  284. /dodal/devices/{i24 → beamlines/i22}/__init__.py +0 -0
  285. /dodal/devices/{p99 → beamlines/i24}/__init__.py +0 -0
  286. /dodal/devices/{i24 → beamlines/i24}/aperture.py +0 -0
  287. /dodal/devices/{i24 → beamlines/i24}/focus_mirrors.py +0 -0
  288. /dodal/devices/{i24 → beamlines/i24}/vgonio.py +0 -0
  289. /dodal/devices/{p60 → beamlines/p60}/__init__.py +0 -0
  290. /dodal/devices/{p60 → beamlines/p60}/enums.py +0 -0
  291. /dodal/devices/{p99 → beamlines/p99}/sample_stage.py +0 -0
  292. /dodal/devices/insertion_device/{id_enum.py → enum.py} +0 -0
@@ -5,15 +5,14 @@ from dodal.devices.electron_analyser.base.base_controller import (
5
5
  )
6
6
  from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector
7
7
  from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode
8
- from dodal.devices.electron_analyser.base.energy_sources import (
9
- DualEnergySource,
10
- EnergySource,
11
- )
8
+ from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource
12
9
  from dodal.devices.electron_analyser.specs.specs_driver_io import SpecsAnalyserDriverIO
13
10
  from dodal.devices.electron_analyser.specs.specs_region import (
14
11
  SpecsRegion,
15
12
  SpecsSequence,
16
13
  )
14
+ from dodal.devices.fast_shutter import FastShutter
15
+ from dodal.devices.selectable_source import SourceSelector
17
16
 
18
17
 
19
18
  class SpecsDetector(
@@ -29,7 +28,9 @@ class SpecsDetector(
29
28
  prefix: str,
30
29
  lens_mode_type: type[TLensMode],
31
30
  psu_mode_type: type[TPsuMode],
32
- energy_source: DualEnergySource | EnergySource,
31
+ energy_source: AbstractEnergySource,
32
+ shutter: FastShutter | None = None,
33
+ source_selector: SourceSelector | None = None,
33
34
  name: str = "",
34
35
  ):
35
36
  # Save to class so takes part with connect()
@@ -39,7 +40,7 @@ class SpecsDetector(
39
40
 
40
41
  controller = ElectronAnalyserController[
41
42
  SpecsAnalyserDriverIO[TLensMode, TPsuMode], SpecsRegion[TLensMode, TPsuMode]
42
- ](self.driver, energy_source, 0)
43
+ ](self.driver, energy_source, shutter, source_selector)
43
44
 
44
45
  sequence_class = SpecsSequence[lens_mode_type, psu_mode_type]
45
46
 
@@ -5,10 +5,7 @@ from dodal.devices.electron_analyser.base.base_controller import (
5
5
  )
6
6
  from dodal.devices.electron_analyser.base.base_detector import ElectronAnalyserDetector
7
7
  from dodal.devices.electron_analyser.base.base_region import TLensMode, TPsuMode
8
- from dodal.devices.electron_analyser.base.energy_sources import (
9
- DualEnergySource,
10
- EnergySource,
11
- )
8
+ from dodal.devices.electron_analyser.base.energy_sources import AbstractEnergySource
12
9
  from dodal.devices.electron_analyser.vgscienta.vgscienta_driver_io import (
13
10
  VGScientaAnalyserDriverIO,
14
11
  )
@@ -17,6 +14,8 @@ from dodal.devices.electron_analyser.vgscienta.vgscienta_region import (
17
14
  VGScientaRegion,
18
15
  VGScientaSequence,
19
16
  )
17
+ from dodal.devices.fast_shutter import FastShutter
18
+ from dodal.devices.selectable_source import SourceSelector
20
19
 
21
20
 
22
21
  class VGScientaDetector(
@@ -33,7 +32,9 @@ class VGScientaDetector(
33
32
  lens_mode_type: type[TLensMode],
34
33
  psu_mode_type: type[TPsuMode],
35
34
  pass_energy_type: type[TPassEnergyEnum],
36
- energy_source: DualEnergySource | EnergySource,
35
+ energy_source: AbstractEnergySource,
36
+ shutter: FastShutter | None = None,
37
+ source_selector: SourceSelector | None = None,
37
38
  name: str = "",
38
39
  ):
39
40
  # Save to class so takes part with connect()
@@ -44,7 +45,7 @@ class VGScientaDetector(
44
45
  controller = ElectronAnalyserController[
45
46
  VGScientaAnalyserDriverIO[TLensMode, TPsuMode, TPassEnergyEnum],
46
47
  VGScientaRegion[TLensMode, TPassEnergyEnum],
47
- ](self.driver, energy_source, 0)
48
+ ](self.driver, energy_source, shutter, source_selector)
48
49
 
49
50
  sequence_class = VGScientaSequence[
50
51
  lens_mode_type, psu_mode_type, pass_energy_type
@@ -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)
@@ -1,69 +1,155 @@
1
- from typing import TypeVar
1
+ from typing import Generic, Protocol, TypeVar
2
2
 
3
3
  from bluesky.protocols import Movable
4
4
  from ophyd_async.core import (
5
5
  AsyncStatus,
6
6
  EnumTypes,
7
+ Reference,
8
+ SignalRW,
7
9
  StandardReadable,
10
+ StandardReadableFormat,
11
+ derived_signal_rw,
12
+ soft_signal_r_and_setter,
8
13
  )
9
14
  from ophyd_async.epics.core import epics_signal_rw
10
15
 
11
- StrictEnumT = TypeVar("StrictEnumT", bound=EnumTypes)
16
+ from dodal.devices.selectable_source import SelectedSource, get_obj_from_selected_source
12
17
 
18
+ EnumTypesT = TypeVar("EnumTypesT", bound=EnumTypes)
13
19
 
14
- class GenericFastShutter(StandardReadable, Movable[StrictEnumT]):
15
- """
16
- Basic enum device specialised for a fast shutter with configured open_state and
20
+
21
+ class FastShutter(Movable[EnumTypesT], Protocol, Generic[EnumTypesT]):
22
+ """Enum device specialised for a fast shutter with configured open_state and
17
23
  close_state so it is generic enough to be used with any device or plan without
18
24
  knowing the specific enum to use.
19
25
 
20
- For example:
26
+ For example::
27
+
21
28
  await shutter.set(shutter.open_state)
22
29
  await shutter.set(shutter.close_state)
23
- OR
30
+
31
+ OR::
32
+
24
33
  run_engine(bps.mv(shutter, shutter.open_state))
25
34
  run_engine(bps.mv(shutter, shutter.close_state))
26
35
  """
27
36
 
37
+ open_state: EnumTypesT
38
+ close_state: EnumTypesT
39
+ shutter_state: SignalRW[EnumTypesT]
40
+
41
+ @AsyncStatus.wrap
42
+ async def set(self, state: EnumTypesT):
43
+ await self.shutter_state.set(state)
44
+
45
+
46
+ class GenericFastShutter(
47
+ StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]
48
+ ):
49
+ """Implementation of fast shutter that connects to an epics pv. This pv is an enum that
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.
59
+ """
60
+
28
61
  def __init__(
29
62
  self,
30
63
  pv: str,
31
- open_state: StrictEnumT,
32
- close_state: StrictEnumT,
64
+ open_state: EnumTypesT,
65
+ close_state: EnumTypesT,
33
66
  name: str = "",
34
67
  ):
35
- """
36
- Arguments:
37
- pv: The pv to connect to the shutter device.
38
- open_state: The enum value that corresponds with opening the shutter.
39
- close_state: The enum value that corresponds with closing the shutter.
40
- """
41
68
  self.open_state = open_state
42
69
  self.close_state = close_state
43
70
  with self.add_children_as_readables():
44
- self.state = epics_signal_rw(type(self.open_state), pv)
71
+ self.shutter_state = epics_signal_rw(type(self.open_state), pv)
45
72
  super().__init__(name)
46
73
 
47
- @AsyncStatus.wrap
48
- async def set(self, value: StrictEnumT) -> None:
49
- await self.state.set(value)
50
-
51
- async def is_open(self) -> bool:
52
- """
53
- Checks to see if shutter is in open_state. Should not be used directly inside a
54
- plan. A user should use the following instead in a plan:
55
-
56
- from bluesky import plan_stubs as bps
57
- is_open = yield from bps.rd(shutter.state) == shutter.open_state
58
- """
59
- return await self.state.get_value() == self.open_state
60
-
61
- async def is_closed(self) -> bool:
62
- """
63
- Checks to see if shutter is in close_state. Should not be used directly inside a
64
- plan. A user should use the following instead in a plan:
65
-
66
- from bluesky import plan_stubs as bps
67
- is_closed = yield from bps.rd(shutter.state) == shutter.close_state
68
- """
69
- return await self.state.get_value() == self.close_state
74
+
75
+ class DualFastShutter(StandardReadable, FastShutter[EnumTypesT], Generic[EnumTypesT]):
76
+ """A fast shutter device that handles the positions of two other fast shutters. The
77
+ "active" shutter is the one that corrosponds to the selected_shutter signal. For
78
+ example, active shutter is shutter1 if selected_source is at SelectedSource.SOURCE1
79
+ and vise versa for shutter2 and SelectedSource.SOURCE2. Whenever a move is done on
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.
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ shutter1: GenericFastShutter[EnumTypesT],
94
+ shutter2: GenericFastShutter[EnumTypesT],
95
+ selected_source: SignalRW[SelectedSource],
96
+ name: str = "",
97
+ ):
98
+ self._validate_shutter_states(shutter1.open_state, shutter2.open_state)
99
+ self._validate_shutter_states(shutter1.close_state, shutter2.close_state)
100
+ self.open_state = shutter1.open_state
101
+ self.close_state = shutter1.close_state
102
+
103
+ self._shutter1_ref = Reference(shutter1)
104
+ self._shutter2_ref = Reference(shutter2)
105
+ self._selected_shutter_ref = Reference(selected_source)
106
+
107
+ with self.add_children_as_readables():
108
+ self.shutter_state = derived_signal_rw(
109
+ self._read_shutter_state,
110
+ self._set_shutter_state,
111
+ selected_shutter=selected_source,
112
+ shutter1=shutter1.shutter_state,
113
+ shutter2=shutter2.shutter_state,
114
+ )
115
+
116
+ with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
117
+ self.shutter1_device_name, _ = soft_signal_r_and_setter(
118
+ str, initial_value=shutter1.name
119
+ )
120
+ self.shutter2_device_name, _ = soft_signal_r_and_setter(
121
+ str, initial_value=shutter2.name
122
+ )
123
+
124
+ self.add_readables([shutter1, shutter2, selected_source])
125
+
126
+ super().__init__(name)
127
+
128
+ def _validate_shutter_states(self, state1: EnumTypesT, state2: EnumTypesT) -> None:
129
+ if state1 is not state2:
130
+ raise ValueError(
131
+ f"{state1} is not same value as {state2}. They must be the same to be compatible."
132
+ )
133
+
134
+ def _read_shutter_state(
135
+ self,
136
+ selected_shutter: SelectedSource,
137
+ shutter1: EnumTypesT,
138
+ shutter2: EnumTypesT,
139
+ ) -> EnumTypesT:
140
+ return get_obj_from_selected_source(selected_shutter, shutter1, shutter2)
141
+
142
+ async def _set_shutter_state(self, value: EnumTypesT):
143
+ selected_shutter = await self._selected_shutter_ref().get_value()
144
+ active_shutter = get_obj_from_selected_source(
145
+ selected_shutter,
146
+ self._shutter1_ref(),
147
+ self._shutter2_ref(),
148
+ )
149
+ inactive_shutter = get_obj_from_selected_source(
150
+ selected_shutter,
151
+ self._shutter2_ref(),
152
+ self._shutter1_ref(),
153
+ )
154
+ await inactive_shutter.set(inactive_shutter.close_state)
155
+ await active_shutter.set(value)
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):
@@ -27,7 +27,7 @@ DEFAULT_SETTLE_TIME_S = 60
27
27
 
28
28
 
29
29
  class MirrorType(StrictEnum):
30
- """See https://manual.nexusformat.org/classes/base_classes/NXmirror.html"""
30
+ """See https://manual.nexusformat.org/classes/base_classes/NXmirror.html."""
31
31
 
32
32
  SINGLE = "single"
33
33
  MULTI = "multi"
@@ -53,8 +53,9 @@ class MirrorVoltageDemand(StrictEnum):
53
53
 
54
54
 
55
55
  class SingleMirrorVoltage(Device):
56
- """Abstract the bimorph mirror voltage PVs into a single device that can be set asynchronously and returns when
57
- the demanded voltage setpoint is accepted, without blocking the caller as this process can take significant time.
56
+ """Abstract the bimorph mirror voltage PVs into a single device that can be set
57
+ asynchronously and returns when the demanded voltage setpoint is accepted, without
58
+ blocking the caller as this process can take significant time.
58
59
  """
59
60
 
60
61
  def __init__(self, prefix: str, name: str = ""):
@@ -66,11 +67,14 @@ class SingleMirrorVoltage(Device):
66
67
  @AsyncStatus.wrap
67
68
  async def set(self, value, *args, **kwargs):
68
69
  """Combine the following operations into a single set:
69
- 1. apply the value to the setpoint PV
70
- 3. Wait until demand is accepted
71
- 4. When either demand is accepted or DEFAULT_SETTLE_TIME expires, signal the result on the Status
72
- """
73
70
 
71
+ 1. apply the value to the setpoint PV.
72
+
73
+ 3. Wait until demand is accepted.
74
+
75
+ 4. When either demand is accepted or DEFAULT_SETTLE_TIME expires, signal the
76
+ result on the Status.
77
+ """ # noqa D415
74
78
  setpoint_v = self._setpoint_v
75
79
  demand_accepted = self._demand_accepted
76
80
 
@@ -136,7 +140,7 @@ class MirrorVoltages(StandardReadable):
136
140
 
137
141
 
138
142
  class SimpleMirror(XYPitchStage):
139
- """Simple Focusing Mirror"""
143
+ """Simple Focusing Mirror."""
140
144
 
141
145
  def __init__(
142
146
  self,
@@ -165,7 +169,7 @@ class SimpleMirror(XYPitchStage):
165
169
 
166
170
 
167
171
  class FocusingMirror(StandardReadable):
168
- """Focusing Mirror"""
172
+ """Focusing Mirror."""
169
173
 
170
174
  def __init__(
171
175
  self,
@@ -202,7 +206,8 @@ class FocusingMirror(StandardReadable):
202
206
 
203
207
  class FocusingMirrorWithStripes(FocusingMirror):
204
208
  """A focusing mirror where the stripe material can be changed. This is usually done
205
- based on the energy of the beamline."""
209
+ based on the energy of the beamline.
210
+ """
206
211
 
207
212
  def __init__(self, prefix: str, name: str = "", *args, **kwargs):
208
213
  self.stripe = epics_signal_rw(MirrorStripe, prefix + "STRP:DVAL")
@@ -212,9 +217,22 @@ class FocusingMirrorWithStripes(FocusingMirror):
212
217
  super().__init__(prefix, name, *args, **kwargs)
213
218
 
214
219
  def energy_to_stripe(self, energy_kev) -> MirrorStripeConfiguration:
215
- """Return the stripe, yaw angle and lateral position for the specified energy"""
220
+ """Return the stripe, yaw angle and lateral position for the specified energy."""
216
221
  # In future, this should be configurable per-mirror
217
222
  if energy_kev < 7:
218
223
  return {"stripe": MirrorStripe.BARE, "yaw_mrad": 6.2, "lat_mm": 0.0}
219
224
  else:
220
225
  return {"stripe": MirrorStripe.RHODIUM, "yaw_mrad": 0.0, "lat_mm": 10.0}
226
+
227
+
228
+ class FocusingMirrorWithPiezo(FocusingMirror):
229
+ """A focusing mirror which also has a piezoelectric actuator.
230
+ A voltage can be applied to the piezo to steer the beam by making the material
231
+ shrink or expand.
232
+ """
233
+
234
+ def __init__(self, prefix: str, name: str = "", *args, **kwargs):
235
+ with self.add_children_as_readables():
236
+ self.piezo = epics_signal_rw(float, f"{prefix}AOFPITCH")
237
+ self.piezo_rbv = epics_signal_r(float, f"{prefix}AOFPITCH:RBV")
238
+ super().__init__(prefix, name, *args, **kwargs)
@@ -58,14 +58,14 @@ class HutchInterlock(StandardReadable):
58
58
  class HutchShutter(StandardReadable, Movable[ShutterDemand]):
59
59
  """Device to operate the hutch shutter.
60
60
 
61
- When a demand is sent, the device should first check the hutch status \
62
- and raise an error if it's not interlocked (searched and locked), meaning it's not \
61
+ When a demand is sent, the device should first check the hutch status
62
+ and raise an error if it's not interlocked (searched and locked), meaning it's not
63
63
  safe to operate the shutter.
64
64
 
65
- If the requested shutter position is "Open", the shutter control PV should first \
66
- go to "Reset" and then move to "Open". This is because before opening the hutch \
67
- shutter, the interlock status PV (`-PS-SHTR-01:ILKSTA`) will show as `failed` until \
68
- the hutch shutter is reset. This will set the interlock status to `OK`, allowing \
65
+ If the requested shutter position is "Open", the shutter control PV should first
66
+ go to "Reset" and then move to "Open". This is because before opening the hutch
67
+ shutter, the interlock status PV (`-PS-SHTR-01:ILKSTA`) will show as `failed` until
68
+ the hutch shutter is reset. This will set the interlock status to `OK`, allowing
69
69
  for shutter operations. Until this step is done, the hutch shutter can't be opened.
70
70
  The reset is not needed for closing the shutter.
71
71
  """
@@ -1,38 +1,48 @@
1
- from .apple2_undulator import (
2
- DEFAULT_MOTOR_MIN_TIMEOUT,
1
+ from .apple2_controller import (
3
2
  MAXIMUM_MOVE_TIME,
4
- Apple2,
5
3
  Apple2Controller,
6
4
  Apple2EnforceLHMoveController,
5
+ Apple2Type,
6
+ EnergyMotorConvertor,
7
+ )
8
+ from .apple2_undulator import (
9
+ DEFAULT_MOTOR_MIN_TIMEOUT,
10
+ Apple2,
7
11
  Apple2LockedPhasesVal,
8
12
  Apple2PhasesVal,
9
13
  Apple2Val,
10
- BeamEnergy,
11
14
  EnabledDisabledUpper,
12
- EnergyMotorConvertor,
13
- InsertionDeviceEnergy,
14
- InsertionDevicePolarisation,
15
15
  UndulatorGap,
16
16
  UndulatorJawPhase,
17
17
  UndulatorLockedPhaseAxes,
18
18
  UndulatorPhaseAxes,
19
+ UnstoppableMotor,
20
+ )
21
+ from .apple_knot_controller import (
22
+ AppleKnotController,
23
+ AppleKnotPathFinder,
19
24
  )
25
+ from .energy import BeamEnergy, InsertionDeviceEnergy, InsertionDeviceEnergyBase
20
26
  from .energy_motor_lookup import (
21
27
  ConfigServerEnergyMotorLookup,
22
28
  EnergyMotorLookup,
23
29
  )
24
- from .id_enum import Pol, UndulatorGateStatus
30
+ from .enum import Pol, UndulatorGateStatus
25
31
  from .lookup_table_models import (
26
32
  EnergyCoverage,
27
33
  LookupTable,
28
34
  LookupTableColumnConfig,
29
35
  convert_csv_to_lookup,
30
36
  )
37
+ from .polarisation import InsertionDevicePolarisation
31
38
 
32
39
  __all__ = [
33
40
  "Apple2",
41
+ "Apple2Type",
34
42
  "Apple2Controller",
35
43
  "Apple2EnforceLHMoveController",
44
+ "AppleKnotController",
45
+ "AppleKnotPathFinder",
36
46
  "UndulatorGap",
37
47
  "UndulatorPhaseAxes",
38
48
  "UndulatorJawPhase",
@@ -55,4 +65,6 @@ __all__ = [
55
65
  "EnergyMotorLookup",
56
66
  "ConfigServerEnergyMotorLookup",
57
67
  "EnergyMotorConvertor",
68
+ "UnstoppableMotor",
69
+ "InsertionDeviceEnergyBase",
58
70
  ]