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
@@ -43,10 +43,19 @@ class BimorphMirrorChannel(StandardReadable, EpicsDevice):
43
43
  """Collection of PVs comprising a single bimorph channel.
44
44
 
45
45
  Attributes:
46
- target_voltage: Float RW_RBV for target voltage, which can be set using parent mirror's all target proc
47
- output_voltage: Float RW_RBV for current voltage on bimorph
48
- status: BimorphMirrorOnOff readable for ON/OFF status of channel
49
- shift: Float writeable shifting channel voltage
46
+ target_voltage (SignalRW): Float RW_RBV for target voltage, which can be set
47
+ using parent mirror's all target proc.
48
+ output_voltage (SignalRW): Float RW_RBV for current voltage on bimorph.
49
+ status (SignalR): BimorphMirrorOnOff readable for ON/OFF status of channel.
50
+ shift (SignalW): Float writeable shifting channel voltage.
51
+
52
+ Args:
53
+ prefix (str): PV prefix.
54
+ number_of_channels (int): Number of channels on bimorph mirror (can be zero).
55
+ name (str, optional): Name of device.
56
+
57
+ Raises:
58
+ ValueError: number_of_channels is less than zero.
50
59
  """
51
60
 
52
61
  target_voltage: A[SignalRW[float], PvSuffix.rbv("VTRGT"), Format.CONFIG_SIGNAL]
@@ -59,21 +68,14 @@ class BimorphMirror(StandardReadable, Movable[list[float]]):
59
68
  """Class to represent CAENels Bimorph Mirrors.
60
69
 
61
70
  Attributes:
62
- channels: DeviceVector of BimorphMirrorChannel, indexed from 1, for each channel
63
- enabled: Writeable BimorphOnOff
64
- status: Readable BimorphMirrorStatus Busy/Idle status
65
- err: Alarm status"""
71
+ channels (DeviceVector): DeviceVector of BimorphMirrorChannel, indexed from 1,
72
+ for each channel.
73
+ enabled (SignalW): Writeable BimorphOnOff.
74
+ status (SignalR): Readable BimorphMirrorStatus Busy/Idle status.
75
+ err (SignalR): Alarm status.
76
+ """
66
77
 
67
78
  def __init__(self, prefix: str, number_of_channels: int, name=""):
68
- """
69
- Args:
70
- prefix: str PV prefix
71
- number_of_channels: int number of channels on bimorph mirror (can be zero)
72
- name: str name of device
73
-
74
- Raises:
75
- ValueError: number_of_channels is less than zero"""
76
-
77
79
  if number_of_channels < 0:
78
80
  raise ValueError(f"Number of channels is below zero: {number_of_channels}")
79
81
 
@@ -95,11 +97,11 @@ class BimorphMirror(StandardReadable, Movable[list[float]]):
95
97
  """Sets bimorph voltages in parallel via target voltage and all proc.
96
98
 
97
99
  Args:
98
- value: List of float target voltages
100
+ value (list[float]): List of float target voltages.
99
101
 
100
102
  Raises:
101
- ValueError: On set to non-existent channel"""
102
-
103
+ ValueError: On set to non-existent channel.
104
+ """
103
105
  if len(value) != len(self.channels):
104
106
  raise ValueError(
105
107
  f"Length of value input array does not match number of \
@@ -13,8 +13,9 @@ class CollimationTable(StandardReadable):
13
13
  There are 2 physical horizontal motors 1 upstream, 1 downstream. These provide yaw.
14
14
 
15
15
  Table motion is disabled by an object being within the laser curtain area and can be
16
- overridden by use of the dead man's handle device or locking the hutch. The effect of
17
- these disabling systems is to cut power to the motors - signal for this is crate_power
16
+ overridden by use of the dead man's handle device or locking the hutch. The effect
17
+ of these disabling systems is to cut power to the motors - signal for this is
18
+ `crate_power`.
18
19
  """
19
20
 
20
21
  def __init__(self, prefix: str, name: str = ""):
@@ -33,19 +33,23 @@ Xtal_2 = TypeVar("Xtal_2", bound=StationaryCrystal)
33
33
 
34
34
 
35
35
  class DoubleCrystalMonochromatorBase(StandardReadable, Generic[Xtal_1, Xtal_2]):
36
- """
37
- Base device for the double crystal monochromator (DCM), used to select the energy of the beam.
36
+ """Base device for the double crystal monochromator (DCM), used to select the energy
37
+ of the beam.
38
38
 
39
- Features common across all DCM's should include virtual motors to set energy/wavelength and contain two crystals,
40
- each of which can be movable. Some DCM's contain crystals with roll motors, and some contain crystals with roll and pitch motors.
41
- This base device accounts for all combinations of this.
39
+ Features common across all DCM's should include virtual motors to set
40
+ energy/wavelength and contain two crystals, each of which can be movable. Some DCM's
41
+ contain crystals with roll motors, and some contain crystals with roll and pitch
42
+ motors. This base device accounts for all combinations of this.
43
+
44
+ This device should act as a parent for beamline-specific DCM's which do not match
45
+ the standard EPICS interface, it provides only energy and the crystal configuration.
46
+ Most beamlines should use DoubleCrystalMonochromator instead.
42
47
 
43
- This device should act as a parent for beamline-specific DCM's which do not match the standard EPICS interface, it provides
44
- only energy and the crystal configuration. Most beamlines should use DoubleCrystalMonochromator instead
48
+ Bluesky plans using DCM's should be typed to specify which types of crystals are
49
+ required. For example, a plan which only requires one crystal which can roll should
50
+ be typed::
45
51
 
46
- Bluesky plans using DCM's should be typed to specify which types of crystals are required. For example, a plan
47
- which only requires one crystal which can roll should be typed
48
- 'def my_plan(dcm: DoubleCrystalMonochromatorBase[RollCrystal, StationaryCrystal])`
52
+ def my_plan(dcm: DoubleCrystalMonochromatorBase[RollCrystal,StationaryCrystal])
49
53
  """
50
54
 
51
55
  def __init__(
@@ -78,17 +82,23 @@ class DoubleCrystalMonochromatorBase(StandardReadable, Generic[Xtal_1, Xtal_2]):
78
82
  class DoubleCrystalMonochromator(
79
83
  DoubleCrystalMonochromatorBase, Generic[Xtal_1, Xtal_2]
80
84
  ):
81
- """
82
- Common device for the double crystal monochromator (DCM), used to select the energy of the beam.
85
+ """Common device for the double crystal monochromator (DCM), used to select the
86
+ energy of the beam.
83
87
 
84
- Features common across all DCM's should include virtual motors to set energy/wavelength and contain two crystals,
85
- each of which can be movable. Some DCM's contain crystals with roll motors, and some contain crystals with roll and pitch motors.
88
+ Features common across all DCM's should include virtual motors to set
89
+ energy/wavelength and contain two crystals, each of which can be movable. Some DCM's
90
+ contain crystals with roll motors, and some contain crystals with roll and pitch
91
+ motors.
86
92
  This base device accounts for all combinations of this.
87
93
 
88
- This device should act as a parent for beamline-specific DCM's, in which any other missing signals can be added.
94
+ This device should act as a parent for beamline-specific DCM's, in which any other
95
+ missing signals can be added.
96
+
97
+ Bluesky plans using DCM's should be typed to specify which types of crystals are
98
+ required. For example, a plan which only requires one crystal which can roll should
99
+ be typed::
89
100
 
90
- Bluesky plans using DCM's should be typed to specify which types of crystals are required. For example, a plan which only
91
- requires one crystal which can roll should be typed 'def my_plan(dcm: DoubleCrystalMonochromator[RollCrystal, StationaryCrystal])`
101
+ def my_plan(dcm: DoubleCrystalMonochromator[RollCrystal, StationaryCrystal])
92
102
  """
93
103
 
94
104
  def __init__(
@@ -109,9 +119,9 @@ class DoubleCrystalMonochromator(
109
119
  class DoubleCrystalMonochromatorWithDSpacing(
110
120
  DoubleCrystalMonochromator, Generic[Xtal_1, Xtal_2]
111
121
  ):
112
- """
113
- Adds crystal D-spacing metadata to the DoubleCrystalMonochromator class. This should be used in preference to the
114
- DoubleCrystalMonochromator on beamlines which have a "DSPACING:RBV" pv on their DCM.
122
+ """Adds crystal D-spacing metadata to the DoubleCrystalMonochromator class. This
123
+ should be used in preference to the DoubleCrystalMonochromator on beamlines which
124
+ have a "DSPACING:RBV" pv on their DCM.
115
125
  """
116
126
 
117
127
  def __init__(
@@ -6,8 +6,8 @@ ADBaseIOT = TypeVar("ADBaseIOT", bound=ADBaseIO)
6
6
 
7
7
 
8
8
  class ConstantDeadTimeController(ADBaseController[ADBaseIOT]):
9
- """
10
- ADBaseController with a configured constant deadtime for a driver of type ADBaseIO.
9
+ """ADBaseController with a configured constant deadtime for a driver of type
10
+ ADBaseIO.
11
11
  """
12
12
 
13
13
  def __init__(
@@ -87,6 +87,14 @@ class OxfordCryoJet(StandardReadable):
87
87
 
88
88
 
89
89
  class CryoStreamGantry(StandardReadable):
90
+ """Gantry controlling whether the standard Cryostream or the
91
+ HC1 cryostream is in position.
92
+
93
+ Note: this device is currently implemented read-only; moving the gantry without
94
+ adequate checks risks a collision if the gantry is moved while HC1 is selected
95
+ and in the IN position.
96
+ """
97
+
90
98
  def __init__(self, prefix: str, name: str = ""):
91
99
  with self.add_children_as_readables(StandardReadableFormat.CONFIG_SIGNAL):
92
100
  self.cryostream_selector = epics_signal_r(
@@ -9,14 +9,13 @@ from ophyd_async.core import AsyncStatus, StandardReadable
9
9
 
10
10
 
11
11
  class CurrentAmp(ABC, StandardReadable, Movable):
12
- """
13
- Base class for current amplifier, it contains the minimal functionality
14
- a current amplifier needs:
12
+ """Base class for current amplifier, it contains the minimal functionality
13
+ a current amplifier needs:
15
14
 
16
15
  Attributes:
17
16
  gain_conversion_table (Enum): The conversion table between current
18
- and gain setting.
19
- """
17
+ and gain setting.
18
+ """ # noqa D415
20
19
 
21
20
  def __init__(self, gain_conversion_table: type[Enum], name: str = "") -> None:
22
21
  self.gain_conversion_table = gain_conversion_table
@@ -40,7 +39,7 @@ class CurrentAmp(ABC, StandardReadable, Movable):
40
39
 
41
40
  @abstractmethod
42
41
  async def get_gain(self) -> Enum:
43
- """Get the current gain setting
42
+ """Get the current gain setting.
44
43
 
45
44
  Returns:
46
45
  Enum: The member name of the current gain setting in gain_conversion_table.
@@ -48,17 +47,16 @@ class CurrentAmp(ABC, StandardReadable, Movable):
48
47
 
49
48
  @abstractmethod
50
49
  async def get_upperlimit(self) -> float:
51
- """Get the upper limit of the current amplifier"""
50
+ """Get the upper limit of the current amplifier."""
52
51
 
53
52
  @abstractmethod
54
53
  async def get_lowerlimit(self) -> float:
55
- """Get the lower limit of the current amplifier"""
54
+ """Get the lower limit of the current amplifier."""
56
55
 
57
56
 
58
57
  class CurrentAmpCounter(ABC, StandardReadable, Preparable):
59
- """
60
- Base class for current amplifier counter, it contain the minimal implementations
61
- required for a counter/detector to function with CurrentAmpDet:
58
+ """Base class for current amplifier counter, it contain the minimal implementations
59
+ required for a counter/detector to function with CurrentAmpDet.
62
60
 
63
61
  Attributes:
64
62
  count_per_volt (float): The conversion factor between counter output and voltage.
@@ -70,29 +68,29 @@ class CurrentAmpCounter(ABC, StandardReadable, Preparable):
70
68
 
71
69
  @abstractmethod
72
70
  async def get_count(self) -> float:
73
- """ "Get count
71
+ """Get count.
74
72
 
75
73
  Returns:
76
- float: Current count
74
+ float: Current count.
77
75
  """
78
76
 
79
77
  @abstractmethod
80
78
  async def get_count_per_sec(self) -> float:
81
- """Get count per second
79
+ """Get count per second.
82
80
 
83
81
  Returns:
84
- float: Current count per second
82
+ float: Current count per second.
85
83
  """
86
84
 
87
85
  @abstractmethod
88
86
  async def get_voltage_per_sec(self) -> float:
89
- """Get count per second in voltage
87
+ """Get count per second in voltage.
90
88
 
91
89
  Returns:
92
- float: Current count in volt per second
90
+ float: Current count in volt per second.
93
91
  """
94
92
 
95
93
  @abstractmethod
96
94
  @AsyncStatus.wrap
97
95
  async def prepare(self, value: float) -> None:
98
- """Prepare method for setting up the counter"""
96
+ """Prepare method for setting up the counter."""
@@ -18,11 +18,11 @@ from dodal.log import LOGGER
18
18
 
19
19
 
20
20
  class CurrentAmpDet(StandardReadable, Preparable):
21
- """
22
- CurrentAmpDet composed of a CurrentAmp and a CurrentAmpCounter. It provides
23
- the option for automatically changing the CurrentAmp gain to within the optimal
24
- range. It also converts the currentAmp/counter output back into the detector
25
- current output in Amp.
21
+ """CurrentAmpDet composed of a CurrentAmp and a CurrentAmpCounter. It provides
22
+ the option for automatically changing the CurrentAmp gain to within the optimal
23
+ range. It also converts the currentAmp/counter output back into the detector
24
+ current output in Amp.
25
+
26
26
  Attributes:
27
27
  current_amp (currentAmp): Current amplifier type device.
28
28
  counter (CurrentAmpCounter): Counter that capture the current amplifier output.
@@ -48,9 +48,8 @@ class CurrentAmpDet(StandardReadable, Preparable):
48
48
  super().__init__(name)
49
49
 
50
50
  async def read(self) -> dict[str, Reading]:
51
- """
52
- Read is modified so that if auto_mode is true it will optimise gain before
53
- taking the final reading
51
+ """Read is modified so that if auto_mode is true it will optimise gain before
52
+ taking the final reading.
54
53
  """
55
54
  if await self.auto_mode.get_value():
56
55
  LOGGER.info(f"{self.name}-Attempting auto-gain")
@@ -85,8 +84,8 @@ class CurrentAmpDet(StandardReadable, Preparable):
85
84
  within_limits = True
86
85
 
87
86
  async def get_corrected_current(self) -> float:
88
- """
89
- Convert the output(count and gain) back into the read detector output in Amp.
87
+ """Convert the output (count and gain) back into the read detector output in
88
+ Amp.
90
89
  """
91
90
  current_gain, voltage_per_sec = await asyncio.gather(
92
91
  self.current_amp().get_gain(),
@@ -13,7 +13,7 @@ from dodal.log import LOGGER
13
13
 
14
14
 
15
15
  class Femto3xxGainTable(StrictEnum):
16
- """These are the sensitivity setting for Femto 3xx current amplifier"""
16
+ """These are the sensitivity setting for Femto 3xx current amplifier."""
17
17
 
18
18
  SEN_1 = "10^4"
19
19
  SEN_2 = "10^5"
@@ -28,7 +28,7 @@ class Femto3xxGainTable(StrictEnum):
28
28
 
29
29
 
30
30
  class Femto3xxGainToCurrentTable(float, Enum):
31
- """These are the voltage to current setting for Femto 3xx current amplifier"""
31
+ """These are the voltage to current setting for Femto 3xx current amplifier."""
32
32
 
33
33
  SEN_1 = 1e4
34
34
  SEN_2 = 1e5
@@ -43,7 +43,7 @@ class Femto3xxGainToCurrentTable(float, Enum):
43
43
 
44
44
 
45
45
  class Femto3xxRaiseTime(float, Enum):
46
- """These are the gain dependent raise time(s) for Femto 3xx current amplifier"""
46
+ """These are the gain dependent raise time(s) for Femto 3xx current amplifier."""
47
47
 
48
48
  SEN_1 = 0.8e-3
49
49
  SEN_2 = 0.8e-3
@@ -58,10 +58,10 @@ class Femto3xxRaiseTime(float, Enum):
58
58
 
59
59
 
60
60
  class FemtoDDPCA(CurrentAmp):
61
- """
62
- Femto current amplifier device, this class should cover all DDPCA Femto current
63
- amplifiers, As the main different between all the DDPCA Femto is their gain table
64
- and response time table.
61
+ """Femto current amplifier device, this class should cover all DDPCA Femto current
62
+ amplifiers, As the main different between all the DDPCA Femto is their gain table
63
+ and response time table.
64
+
65
65
  Attributes:
66
66
  gain (SignalRW): This is the epic signal that control current amplifier gain.
67
67
  gain_table (strictEnum): The table epic use to set gain.
@@ -69,8 +69,7 @@ class FemtoDDPCA(CurrentAmp):
69
69
  lowerlimit (float): lowerlimit of the current amplifier
70
70
  timeout (float): Maximum waiting time in second for setting gain.
71
71
  raise_timetable (Enum): Table contain the minimum amount of time to wait after
72
- changing gain.
73
-
72
+ changing gain.
74
73
  """
75
74
 
76
75
  def __init__(
@@ -13,7 +13,7 @@ from dodal.log import LOGGER
13
13
 
14
14
 
15
15
  class SR570GainTable(StrictEnum):
16
- """Coarse/unit sensitivity setting for SR570 current amplifier"""
16
+ """Coarse/unit sensitivity setting for SR570 current amplifier."""
17
17
 
18
18
  SEN_1 = "mA/V"
19
19
  SEN_2 = "uA/V"
@@ -22,7 +22,7 @@ class SR570GainTable(StrictEnum):
22
22
 
23
23
 
24
24
  class SR570FineGainTable(StrictEnum):
25
- """Fine sensitivity setting for SR570 current amplifier"""
25
+ """Fine sensitivity setting for SR570 current amplifier."""
26
26
 
27
27
  SEN_1 = "1"
28
28
  SEN_2 = "2"
@@ -36,7 +36,7 @@ class SR570FineGainTable(StrictEnum):
36
36
 
37
37
 
38
38
  class SR570RaiseTimeTable(float, Enum):
39
- """These are the gain dependent raise time(s) for SR570 current amplifier"""
39
+ """These are the gain dependent raise time(s) for SR570 current amplifier."""
40
40
 
41
41
  SEN_1 = 1e-4
42
42
  SEN_2 = 1e-2
@@ -46,7 +46,8 @@ class SR570RaiseTimeTable(float, Enum):
46
46
 
47
47
  class SR570FullGainTable(Enum):
48
48
  """Combined gain table, as each gain step is a combination of both coarse gain and
49
- fine gain setting"""
49
+ fine gain setting.
50
+ """
50
51
 
51
52
  SEN_1 = [SR570GainTable.SEN_1, SR570FineGainTable.SEN_1]
52
53
  SEN_2 = [SR570GainTable.SEN_2, SR570FineGainTable.SEN_9]
@@ -79,7 +80,7 @@ class SR570FullGainTable(Enum):
79
80
 
80
81
 
81
82
  class SR570GainToCurrentTable(float, Enum):
82
- """Conversion table for gain (sensitivity) to current"""
83
+ """Conversion table for gain (sensitivity) to current."""
83
84
 
84
85
  SEN_1 = 1e3
85
86
  SEN_2 = 2e3
@@ -112,10 +113,10 @@ class SR570GainToCurrentTable(float, Enum):
112
113
 
113
114
 
114
115
  class SR570(CurrentAmp):
115
- """
116
- SR570 current amplifier device. This is similar to Femto with the only different
117
- is SR570 has two gain setting fine and coarse, therefore it requires extra
118
- gain tables.
116
+ """SR570 current amplifier device. This is similar to Femto with the only different
117
+ is SR570 has two gain setting fine and coarse, therefore it requires extra
118
+ gain tables.
119
+
119
120
  Attributes:
120
121
  fine_gain (SignalRW): This is the epic signal that control SR570 fine gain.
121
122
  coarse_gain (SignalRW): This is the epic signal that control SR570 coarse gain.
@@ -129,18 +130,17 @@ class SR570(CurrentAmp):
129
130
  setting in gain_conversion_table.
130
131
  upperlimit (float): upperlimit of the current amplifier
131
132
  lowerlimit (float): lowerlimit of the current amplifier
132
-
133
133
  """
134
134
 
135
135
  def __init__(
136
136
  self,
137
137
  prefix: str,
138
- suffix: str,
139
- fine_gain_table: type[StrictEnum],
140
- coarse_gain_table: type[StrictEnum],
141
- combined_table: type[Enum],
142
- gain_to_current_table: type[Enum],
143
- raise_timetable: type[Enum],
138
+ suffix: str = "SENS:SEL",
139
+ fine_gain_table: type[StrictEnum] = SR570FineGainTable,
140
+ coarse_gain_table: type[StrictEnum] = SR570GainTable,
141
+ combined_table: type[Enum] = SR570FullGainTable,
142
+ gain_to_current_table: type[Enum] = SR570GainToCurrentTable,
143
+ raise_timetable: type[Enum] = SR570RaiseTimeTable,
144
144
  upperlimit: float = 4.8,
145
145
  lowerlimit: float = 0.4,
146
146
  timeout: float = 1,
@@ -25,11 +25,11 @@ COUNT_PER_VOLTAGE = 100000
25
25
 
26
26
 
27
27
  class StruckScaler(CurrentAmpCounter):
28
- """
29
- StruckScaler is a counting card that record the output signal from a wide
30
- range of detectors. This class contains the basic control to run the struckscaler
31
- card together with a current amplifier. It has functions that provide conversion
32
- between count and voltage.
28
+ """StruckScaler is a counting card that record the output signal from a wide
29
+ range of detectors. This class contains the basic control to run the struckscaler
30
+ card together with a current amplifier. It has functions that provide conversion
31
+ between count and voltage.
32
+
33
33
  Attributes:
34
34
  readout(SignalR): Scaler card output.
35
35
  count_mode (SignalR[CountMode]): Counting card setting.
@@ -47,17 +47,18 @@ def _calc_useful_radius(detector_radius_mm, beam_x_mm, beam_y_mm):
47
47
 
48
48
 
49
49
  def _calc_res_at_angle(wavelength_angstroms, angular_shift_radians):
50
- """Base definition of maximum resolution (from Bragg's Law with n=1)"""
50
+ """Base definition of maximum resolution (from Bragg's Law with n=1)."""
51
51
  return 0.5 * wavelength_angstroms / sin(angular_shift_radians)
52
52
 
53
53
 
54
54
  def _calc_res_off_axis_detector(
55
55
  wavelength_angstroms, usable_radius, det_distance_mm, two_theta_radians
56
56
  ):
57
- """
58
- Calculate maximum resolution given detector distance and extent (radius) that detector face extends
59
- No correction for position of beam centre on detector face at twoTheta=0
60
- Here radius and distance parameters can be in any length unit, provided it is the same, millimetres is the convention
57
+ """Calculate maximum resolution given detector distance and extent (radius) that
58
+ detector face extends.
59
+ No correction for position of beam centre on detector face at twoTheta=0.
60
+ Here radius and distance parameters can be in any length unit, provided it is the
61
+ same, millimetres is the convention.
61
62
  """
62
63
  angular_shift_radians = atan(usable_radius / det_distance_mm)
63
64
  return _calc_res_at_angle(
@@ -68,9 +69,9 @@ def _calc_res_off_axis_detector(
68
69
  def _max_res_for_mx(
69
70
  wavelength_angstroms, detector_radius_mm, det_distance_mm, beam_x_mm, beam_y_mm
70
71
  ):
71
- """
72
- Calculate maximum resolution given MX Use Case (detector at twoTheta=0) and beam centre on detector face
73
- Correct the radius for position of beam centre on detector face at twoTheta=0
72
+ """Calculate maximum resolution given MX Use Case (detector at twoTheta=0) and beam
73
+ centre on detector face.
74
+ Correct the radius for position of beam centre on detector face at twoTheta=0.
74
75
  """
75
76
  usable_radius = _calc_useful_radius(detector_radius_mm, beam_x_mm, beam_y_mm)
76
77
  return _calc_res_off_axis_detector(
@@ -19,7 +19,8 @@ from dodal.utils import get_run_number
19
19
 
20
20
  class TriggerMode(Enum):
21
21
  """In set frames the number of frames is known at arm time. In free run they are
22
- not known until the detector is unstaged."""
22
+ not known until the detector is unstaged.
23
+ """
23
24
 
24
25
  SET_FRAMES = auto()
25
26
  FREE_RUN = auto()
@@ -27,7 +28,8 @@ class TriggerMode(Enum):
27
28
 
28
29
  class DetectorParams(BaseModel):
29
30
  """Holds parameters for the detector. Provides access to a list of Dectris detector
30
- sizes and a converter for distance to beam centre."""
31
+ sizes and a converter for distance to beam centre.
32
+ """
31
33
 
32
34
  # https://github.com/pydantic/pydantic/issues/8379
33
35
  # Must use model_dump(by_alias=True) if serialising!
@@ -26,9 +26,8 @@ T = TypeVar("T", bound=_Filters)
26
26
 
27
27
 
28
28
  class DiamondFilter(Positioner1D[T]):
29
- """
30
- A filter set that is used to reduce the heat load on the monochromator.
29
+ """A filter set that is used to reduce the heat load on the monochromator.
31
30
 
32
- It has 4 slots that can contain filters of different thickness. Changing the thickness
33
- signal will move the filter set to select this filter.
31
+ It has 4 slots that can contain filters of different thickness. Changing the
32
+ thickness signal will move the filter set to select this filter.
34
33
  """
dodal/devices/eiger.py CHANGED
@@ -4,6 +4,7 @@ from enum import Enum
4
4
  from bluesky.protocols import Stageable
5
5
  from ophyd import Component, Device, EpicsSignalRO, Signal
6
6
  from ophyd.areadetector.cam import EigerDetectorCam
7
+ from ophyd.signal import AttributeSignal
7
8
  from ophyd.status import AndStatus, Status, StatusBase, SubscriptionStatus
8
9
 
9
10
  from dodal.devices.detector import DetectorParams, TriggerMode
@@ -55,7 +56,6 @@ class EigerDetector(Device, Stageable):
55
56
 
56
57
  stale_params = Component(EpicsSignalRO, "CAM:StaleParameters_RBV")
57
58
  bit_depth = Component(EpicsSignalRO, "CAM:BitDepthImage_RBV")
58
-
59
59
  filewriters_finished: StatusBase
60
60
 
61
61
  detector_params: DetectorParams | None = None
@@ -63,9 +63,24 @@ class EigerDetector(Device, Stageable):
63
63
  arming_status = Status()
64
64
  arming_status.set_finished()
65
65
 
66
- def __init__(self, beamline: str = "i03", *args, **kwargs):
66
+ def __init__(
67
+ self,
68
+ beamline: str = "i03",
69
+ ispyb_detector_id: int | None = None,
70
+ *args,
71
+ **kwargs,
72
+ ):
67
73
  super().__init__(*args, **kwargs)
68
74
  self.beamline = beamline
75
+
76
+ self.detector_id = ispyb_detector_id
77
+ self.ispyb_detector_id = AttributeSignal(
78
+ attr="detector_id",
79
+ parent=self,
80
+ name="eiger-ispyb_detector_id",
81
+ write_access=False,
82
+ )
83
+
69
84
  # using i03 timeouts as default
70
85
  self.timeouts = AVAILABLE_TIMEOUTS.get(beamline, AVAILABLE_TIMEOUTS["i03"])
71
86
  self.disarming_status = None
@@ -74,10 +89,11 @@ class EigerDetector(Device, Stageable):
74
89
  def with_params(
75
90
  cls,
76
91
  params: DetectorParams,
77
- name: str = "EigerDetector",
78
92
  beamline: str = "i03",
93
+ ispyb_detector_id: int | None = None,
94
+ name: str = "EigerDetector",
79
95
  ):
80
- det = cls(name=name, beamline=beamline)
96
+ det = cls(name=name, beamline=beamline, ispyb_detector_id=ispyb_detector_id)
81
97
  det.set_detector_parameters(params)
82
98
  return det
83
99
 
@@ -286,36 +302,35 @@ class EigerDetector(Device, Stageable):
286
302
  beam_x_pixels, beam_y_pixels = self.detector_params.get_beam_position_pixels(
287
303
  self.detector_params.detector_distance
288
304
  )
289
- status = self.cam.beam_center_x.set(
305
+ self.cam.beam_center_x.set(
290
306
  beam_x_pixels, timeout=self.timeouts.general_status_timeout
291
- )
292
- status &= self.cam.beam_center_y.set(
307
+ ).wait(timeout=self.timeouts.general_status_timeout)
308
+ self.cam.beam_center_y.set(
293
309
  beam_y_pixels, timeout=self.timeouts.general_status_timeout
294
- )
295
- status &= self.cam.det_distance.set(
310
+ ).wait(timeout=self.timeouts.general_status_timeout)
311
+ self.cam.det_distance.set(
296
312
  self.detector_params.detector_distance,
297
313
  timeout=self.timeouts.general_status_timeout,
298
- )
299
- status &= self.cam.omega_start.set(
314
+ ).wait(timeout=self.timeouts.general_status_timeout)
315
+ self.cam.omega_start.set(
300
316
  self.detector_params.omega_start,
301
317
  timeout=self.timeouts.general_status_timeout,
302
- )
303
- status &= self.cam.omega_incr.set(
318
+ ).wait(timeout=self.timeouts.general_status_timeout)
319
+ status = self.cam.omega_incr.set(
304
320
  self.detector_params.omega_increment,
305
321
  timeout=self.timeouts.general_status_timeout,
306
322
  )
307
-
308
323
  return status
309
324
 
310
325
  def set_detector_threshold(self, energy: float, tolerance: float = 0.1) -> Status:
311
- """Ensures the energy threshold on the detector is set to the specified energy (in eV),
312
- within the specified tolerance.
326
+ """Ensures the energy threshold on the detector is set to the specified energy
327
+ (in eV), within the specified tolerance.
328
+
313
329
  Args:
314
330
  energy (float): The energy to set (in eV)
315
331
  tolerance (float, optional): If the energy is already set to within
316
332
  this tolerance it is not set again. Defaults to 0.1eV.
317
333
  """
318
-
319
334
  current_energy = float(self.cam.photon_energy.get())
320
335
  if abs(current_energy - energy) > tolerance:
321
336
  LOGGER.info(f"Setting detector threshold to {energy}")
@@ -167,7 +167,7 @@ class EigerOdin(Device):
167
167
  return not error_strings, "\n".join(error_strings)
168
168
 
169
169
  def stop(self) -> StatusBase:
170
- """Stop odin manually"""
170
+ """Stop odin manually."""
171
171
  LOGGER.info("Stopping Odin...")
172
172
  status = self.file_writer.capture.set(0)
173
173
  status &= self.meta.stop_writing.set(1)