dls-dodal 1.40.0__py3-none-any.whl → 1.41.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dls-dodal
3
- Version: 1.40.0
3
+ Version: 1.41.0
4
4
  Summary: Ophyd devices and other utils that could be used across DLS beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>
6
6
  License: Apache License
@@ -238,6 +238,7 @@ Provides-Extra: dev
238
238
  Requires-Dist: black; extra == "dev"
239
239
  Requires-Dist: diff-cover; extra == "dev"
240
240
  Requires-Dist: import-linter; extra == "dev"
241
+ Requires-Dist: ispyb; extra == "dev"
241
242
  Requires-Dist: mypy; extra == "dev"
242
243
  Requires-Dist: myst-parser; extra == "dev"
243
244
  Requires-Dist: ophyd_async[sim]; extra == "dev"
@@ -245,10 +246,11 @@ Requires-Dist: pipdeptree; extra == "dev"
245
246
  Requires-Dist: pre-commit; extra == "dev"
246
247
  Requires-Dist: psutil; extra == "dev"
247
248
  Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
248
- Requires-Dist: pyright; extra == "dev"
249
+ Requires-Dist: pyright==1.1.394; extra == "dev"
249
250
  Requires-Dist: pytest; extra == "dev"
250
251
  Requires-Dist: pytest-asyncio; extra == "dev"
251
252
  Requires-Dist: pytest-cov; extra == "dev"
253
+ Requires-Dist: pytest-json-report; extra == "dev"
252
254
  Requires-Dist: pytest-random-order; extra == "dev"
253
255
  Requires-Dist: ruff; extra == "dev"
254
256
  Requires-Dist: sphinx<7.4.6; extra == "dev"
@@ -1,9 +1,9 @@
1
1
  dodal/__init__.py,sha256=Ksms_WJF8LTkbm38gEpm1jBpGqcQ8NGvmb2ZJlOE1j8,198
2
2
  dodal/__main__.py,sha256=kP2S2RPitnOWpNGokjZ1Yq-1umOtp5sNOZk2B3tBPLM,111
3
- dodal/_version.py,sha256=OZahUNEA3xgbZje9FKlSoVRqeVZRytC_0_3XfHXmWYo,413
3
+ dodal/_version.py,sha256=vzwCPJLAKjDDFO5dFLzh88htG2LcsTvkffw3I3imiBo,513
4
4
  dodal/cli.py,sha256=NieWNUgLUxyck1rHoFAPJjX1xXLzHNdQ-s4wvxYFfps,3757
5
5
  dodal/log.py,sha256=ry8WMq1S4WMIAPqtqGeKuegMRN7Jy3qdVTJlkpKXkL8,9503
6
- dodal/utils.py,sha256=2Qh0jItUUsOCJhVaM6Sm6nIKXGL5DNQ5hg8XO1fg_Bc,19868
6
+ dodal/utils.py,sha256=nZ_gilv1KErYKnTmknFYaE-JnCC-RxZWQ975cchklFA,19790
7
7
  dodal/beamline_specific_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  dodal/beamline_specific_utils/i03.py,sha256=P6Ls4FoVtcacH0RJM3v6ZwwGx27oMppcBdW0la-ohTY,377
9
9
  dodal/beamlines/README.md,sha256=K9MkL_GomxlsoTB7Mz-_dJA5NNSbmCfMiutchGg3C8o,404
@@ -20,9 +20,9 @@ dodal/beamlines/i19_1.py,sha256=I5vz64UsVUkDDT7itdpGVFuYq8zkmPECB0rCbCVUkAY,2325
20
20
  dodal/beamlines/i19_2.py,sha256=DihbYZ27rCdF7fvBclyhZ6Rf0YRSs2rc7hmDNtEr6cA,1939
21
21
  dodal/beamlines/i20_1.py,sha256=7ZZhPfjjKAhGjdXOI6mu2FPbMbsSjFHJOPa1toZRa0U,1725
22
22
  dodal/beamlines/i22.py,sha256=XCAVBkZxN9cmxfpGoWaCvo77lu8hVIJ_e3BUc_qxdu0,7664
23
- dodal/beamlines/i23.py,sha256=2j5qLoqE_hg9ETHqNkOVu7LLkVB8qalgXeORnVYKN_I,1075
23
+ dodal/beamlines/i23.py,sha256=Qnu3Rk9gb2BD3YolMqUXiupt0ehxw5rVnfPJXBWFoCU,973
24
24
  dodal/beamlines/i24.py,sha256=9rBQMCWGdKiRnFbcVvmjiBWiC9WJIJCtLh5m6LkHUtU,7096
25
- dodal/beamlines/p38.py,sha256=hz-njuiP82LpsTlG0s9dy-CCszJtVmJNzy3bCWLAjE0,8772
25
+ dodal/beamlines/p38.py,sha256=MwxBqYe_rUIj-MCRIFZpHJmR0JtA22bSFKfBpoDI9P0,5777
26
26
  dodal/beamlines/p45.py,sha256=0mQ_AEURczc7yzfJzR9QK9i-b6rBGIjGZ4xCIdLNfdI,3031
27
27
  dodal/beamlines/p99.py,sha256=k24QhYpoOHBd0188Fu3wvmpT6dsu8okiIVqVVckdBkw,1063
28
28
  dodal/beamlines/training_rig.py,sha256=8u1TulTFgvu28sfo6vFY-uo_VBAYKT66ENXTqegw3y0,1940
@@ -42,29 +42,29 @@ dodal/devices/CTAB.py,sha256=5_261Ox6NG2cJIzzwnjWz289BG0nZoE0wKOaI5V5jqM,1998
42
42
  dodal/devices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  dodal/devices/adsim.py,sha256=vCexraF4zLssHdjfPod-XuQGJE_sWoCttFdx__HDS8w,488
44
44
  dodal/devices/aperture.py,sha256=yyw2ei3gM_lmZWDQ6VTbydB58RCDTen_nqBZyoTP2IM,583
45
- dodal/devices/aperturescatterguard.py,sha256=Md5dDlA8Ua6GpQ0kTwDtz14Y3wKtLUW7Xh-4_7VYgGU,12407
46
- dodal/devices/apple2_undulator.py,sha256=WUmaBAMv1xVDHDUk7sTFb5tobl5BnJlEaS7ZlJBXS-g,20731
47
- dodal/devices/backlight.py,sha256=nQIr3J-I-OXnOUoWmr3ruy3nhq_q2US1KXC4NrGG_2U,1634
48
- dodal/devices/bimorph_mirror.py,sha256=kG9waIdTkKglUrvY_wD9w533oKPqa7fct1-wa_GCFW0,4797
45
+ dodal/devices/aperturescatterguard.py,sha256=kkBAS10HjZG0tOLM1R2ciaNJxdMGk_Mg5HJaFXDEWEU,12422
46
+ dodal/devices/apple2_undulator.py,sha256=R4KDgA4HcFj9zg1rPAEP9E0mKVzE06bhyxNRUrsi3Sw,20826
47
+ dodal/devices/backlight.py,sha256=RcgeA1hE3Z_5jA-jH8S8uLMpBfZjenRLz1lx6HTYeAo,1653
48
+ dodal/devices/bimorph_mirror.py,sha256=D5PkrOggJRVAnv38lTdy8rErKLu_O2juLEvSqwcotxY,4825
49
49
  dodal/devices/cryostream.py,sha256=K-ldpredpeDTzNt4qtQMg99nKJNjBYoXBbK0WJGexzw,656
50
50
  dodal/devices/dcm.py,sha256=JbyxLnrS68nnnv39l9XEWgJgXUBqxX6aFo19MZnL36E,2574
51
51
  dodal/devices/diamond_filter.py,sha256=A--RHd7WuH-IBhvCyENcRCTP4K-mm_Kqpa0pojpHZow,1098
52
52
  dodal/devices/eiger.py,sha256=n9-rCrIdRnmDNdAz6sCKTYLhiglwlDTmKuMkLUdIWZg,15832
53
53
  dodal/devices/eiger_odin.py,sha256=ytUH_18YuM1nJDhplS6OTdtADloYvHpO6ppENjVd4jU,7411
54
- dodal/devices/fast_grid_scan.py,sha256=N5tNSxNpnwLi7NgCHIqgArIUo8qbtVagIW-AIonZiJE,11630
54
+ dodal/devices/fast_grid_scan.py,sha256=SJTolz-LHlkxWA3Fb0lHa90CH8IjyJ1v2vkaaCURGpU,12044
55
55
  dodal/devices/fluorescence_detector_motion.py,sha256=-1qCSvW0PdT0m6BcoLxrtc0OJ5UDIBsEe11EOLr-gFw,501
56
56
  dodal/devices/flux.py,sha256=1CDsq9yU2-ho8MfYBl50Tl9ABZwpUBHnV486PQXKNoQ,462
57
57
  dodal/devices/focusing_mirror.py,sha256=vdUPkwyCAZBSR3LQ-EojDOoxVy1ZmOaD_nevETbj7BA,6592
58
- dodal/devices/hutch_shutter.py,sha256=oEYrV9V6HLk51_z4bl7H0JYlxrAAZIFF67Fq3lfzI-k,3844
58
+ dodal/devices/hutch_shutter.py,sha256=UvGpsiIQcNW8IGd8ZA8Omus30bSNcVFE1poqO3yK9TE,3859
59
59
  dodal/devices/ipin.py,sha256=eq5jlKw7WGQi8VLrAWpaAIsZmfiVf-5Q0td_B22H6A4,473
60
60
  dodal/devices/linkam3.py,sha256=2sf-_heIsDg4qmqae-w9C2Py8pG8bPB3mT0TFPQIzd0,3869
61
61
  dodal/devices/logging_ophyd_device.py,sha256=dUVE-XhWA56WUXez0mrc4sf322CXY3MVLreTycO5j_A,668
62
62
  dodal/devices/motors.py,sha256=K1df9Pn1ThvsW-g7LrfKWOFaiaQXXUAf2BtbRehzUc4,1108
63
63
  dodal/devices/p45.py,sha256=hNCfWb8xubuHO8uJ5MpHPurp-r1ss7JMgbZQwHVJg-w,1743
64
64
  dodal/devices/pgm.py,sha256=am-AST9iTqma1PkGOKLozqAokZWbJUbM3TNcqXzB-6A,1132
65
- dodal/devices/pressure_jump_cell.py,sha256=LZbHqvClIe4oYX6SU1Rg7WVPjyKZOtGqOFmr3l3mvYg,10251
65
+ dodal/devices/pressure_jump_cell.py,sha256=h5nMNtr2PMG_AKM6nOB7qNTYT70GRuiGBwC-Ol2Yby0,10548
66
66
  dodal/devices/qbpm.py,sha256=FfrWWAHHtYv3fGRT1qljyPpAwoHJYfbooT9CfKg-oXI,465
67
- dodal/devices/robot.py,sha256=5Y5lNkAbXooIAkSWHwDKyeKKzlqMeH3TuLHzCsw2FPI,5993
67
+ dodal/devices/robot.py,sha256=4jiWZnPBz3DmvJJdEG6mKIrrWHty2a6bdbCv8KOn1HE,6009
68
68
  dodal/devices/s4_slit_gaps.py,sha256=4KdarIQoRqX4ry3LUS1Km7fkjUFahA0VuTd2DvYEqQ8,446
69
69
  dodal/devices/scatterguard.py,sha256=jx03in9QgaThWxD4t1S8_Llent2kWrn_hThJ9KkUWTk,330
70
70
  dodal/devices/scintillator.py,sha256=PlD6cnJ39PTB_e7QrRspPliLYE4kL_K7ziJURzuxgdA,365
@@ -73,16 +73,16 @@ dodal/devices/smargon.py,sha256=tOHb9fjI8ZCIrboiC4OzS2j1QJDOKkAlQ2SORbBmaGo,4708
73
73
  dodal/devices/status.py,sha256=hVrJS1yooQo6PRumRACoIEh-SKBUKxvBlQl-MtLFUMQ,327
74
74
  dodal/devices/synchrotron.py,sha256=wLfClZ1lYQWA_D--UsM3NnKLG8bY8mvVsRYER6ob-Ew,2026
75
75
  dodal/devices/tetramm.py,sha256=1lNXtWlmq0Pc_gVGD77XrV3ECe38TornDJUXkq3H1i0,8524
76
- dodal/devices/thawer.py,sha256=4t4yF4VDIrT_tQ8RwjmXe_hDMwVjR8A-4rDkPx19b28,1672
76
+ dodal/devices/thawer.py,sha256=mYrO9klUPYcSbpoUuJ4ZuZZEPcHWWaZ2px5jh8XNQ9Y,1675
77
77
  dodal/devices/turbo_slit.py,sha256=2k5ipQOFpDG-E_bYv4Mf7lOUJg0eIBJXEYNsFU6SV7g,1209
78
- dodal/devices/undulator.py,sha256=rQjDhrvgf4uXUEO17CiLopNDEagWOgkmpa02BarozDE,5295
79
- dodal/devices/undulator_dcm.py,sha256=zulVn1wvu4-WEpf0BgLiDet58IsaKV7KW6qruAdRR_s,2391
78
+ dodal/devices/undulator.py,sha256=ZTjdD0bGp4gkfh0uZmA8FsATLCOsGt14gwPwqLezh1M,5302
79
+ dodal/devices/undulator_dcm.py,sha256=olg8FrIKWqGmhJMuzuvJXH-LQTGhKytvXHPso3Br7C0,2398
80
80
  dodal/devices/watsonmarlow323_pump.py,sha256=rwU94YE6esgGLYdh-pe8nBo_3tvgp6brrrbPDrqp5_M,1406
81
81
  dodal/devices/webcam.py,sha256=mef075ynDbzZ4pNAjfxR_9tdTTqF_rM7hAOVEEOV-Do,2408
82
82
  dodal/devices/xbpm_feedback.py,sha256=j8MHhhE0feoe6R54zPKqS5EbQ0bEDR-nOpLHzHhnHHQ,1156
83
83
  dodal/devices/areadetector/plugins/CAM.py,sha256=sZzJm5Ez3eWfXZi_EB67wluhZmMQm1UyOc2bJFfzd1U,964
84
84
  dodal/devices/areadetector/plugins/MJPG.py,sha256=QTsxCoWbofNpLMGPoOR2hWoM33KyntuLepbF0YmX0KE,3031
85
- dodal/devices/attenuator/attenuator.py,sha256=eHJpM-E4XQfzy1mxGRk754y3n9q6i3youkCqQg_6SUM,3986
85
+ dodal/devices/attenuator/attenuator.py,sha256=Vq9Zsyf56S5fePHGeluImTUtxdwEqttBa2YBIdU5tJU,3993
86
86
  dodal/devices/attenuator/filter.py,sha256=ZoPsTWXjllyMtKBdSIFLB7Cbc88rGof5k3ymL13VczE,422
87
87
  dodal/devices/attenuator/filter_selections.py,sha256=lcmTprCXgSggp2L6uQ6YU0xLMljXvbspAug-WWKCXks,1410
88
88
  dodal/devices/current_amplifiers/__init__.py,sha256=-MhT-t-GJ83rrvTDBCoWub_NKYkRtu4sEj8-y5XZBP0,782
@@ -100,7 +100,7 @@ dodal/devices/detector/detector_motion.py,sha256=UGDQriDWRluDZOZh1mDX9w_fPjMD-_B
100
100
  dodal/devices/i03/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
101
  dodal/devices/i03/beamstop.py,sha256=D1-QeGNpNlUE1qtFz-XxgzQGZbvM5bdb09f69yDB7U0,2802
102
102
  dodal/devices/i04/transfocator.py,sha256=sVI4Bgv-2-DH4-F1nIXMp5Aktevrm3agZnCA-WgjmW8,3780
103
- dodal/devices/i10/i10_apple2.py,sha256=pEZes8wVCPHiOOcuVhEtqPvtnyphMxqbdp39mDp6xXQ,13165
103
+ dodal/devices/i10/i10_apple2.py,sha256=ErObNNE59NuYssde6ojWJb8wo3SVohkQsvK0Bjnf1T8,13192
104
104
  dodal/devices/i10/i10_setting_data.py,sha256=69XWgE-YNTiW7C3t67MNcTL5JDDhOo7h-X7DCTpFE5g,164
105
105
  dodal/devices/i10/mirrors.py,sha256=E0M5keGI3LGaDHyXQkCCyj6xmixNY1xTSkIaaYwtnP8,794
106
106
  dodal/devices/i10/slits.py,sha256=4X50bGiJhTIHxhsOrv-8DATBkQPwQgEaFMNa2OsPrFY,1201
@@ -116,7 +116,7 @@ dodal/devices/i18/diode.py,sha256=q8ddVYT7yDXwURzxw5gfXlGT1tFirNfHBmiKnpvvXHk,40
116
116
  dodal/devices/i18/table.py,sha256=f6OtVSqCFIpXyoHX97CPLpaVDVXUNc2EvgSFP3qVFKo,446
117
117
  dodal/devices/i18/thor_labs_stage.py,sha256=I9JSKY-UqTjN-yBxQWL4CycTNNkUj3vknRrXjA6KZR8,364
118
118
  dodal/devices/i19/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
- dodal/devices/i19/shutter.py,sha256=9KmS4NBwvifgJ4FF_FeXIfSEAV7ZkBAfutiu_0SLrAs,2196
119
+ dodal/devices/i19/shutter.py,sha256=RASOmpVaFBPVkCfPR0fddqrGTEWK-VLPIrqJcObHwNE,2211
120
120
  dodal/devices/i20_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
121
  dodal/devices/i22/dcm.py,sha256=SQDh-Sj1OvplHZ9yTWblJwv8PJrUqxseDPupZOWmcLo,4701
122
122
  dodal/devices/i22/fswitch.py,sha256=LSMoo9aDkH0SLcojbUh2NxTWIpUXHZxauTqThc3XtSk,3073
@@ -130,12 +130,12 @@ dodal/devices/i24/dual_backlight.py,sha256=CbQ9mYUNhhozVdNXqR5ac73tEIAWT2RnEpRwX
130
130
  dodal/devices/i24/focus_mirrors.py,sha256=HO3B4yjV-HMvjkgFd2xTvXft75Qj4lN8d0RNg6HJ4Lo,1857
131
131
  dodal/devices/i24/i24_detector_motion.py,sha256=_HgdsZqFYY0tKqUgMzViHaPEUFXL3WlXXioGvDehRUw,364
132
132
  dodal/devices/i24/pilatus_metadata.py,sha256=fV8AQSBYGx1Qc91Rqj8VhcFPqPLqLCePNpDdmhcrTYM,1827
133
- dodal/devices/i24/pmac.py,sha256=lz9FYU_8YN8cC51ddTzdxcUA7MCVTA_ho3P0CHJ9zCo,6837
133
+ dodal/devices/i24/pmac.py,sha256=pghm0jM24N1GZ1EOazPEoSxcn6zyizp6E4H28jnUn1s,6862
134
134
  dodal/devices/i24/vgonio.py,sha256=sxSmcYZayVJPJz_D_91j9PmNor7Tbl1RGQFRrdtESlw,533
135
135
  dodal/devices/oav/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
136
  dodal/devices/oav/microns_for_zoom_levels.json,sha256=kJTkbu2v6_Ccc_cDy7FRTX-gRhXxfYskjVqwBCZIqCQ,1209
137
137
  dodal/devices/oav/oav_calculations.py,sha256=tr3Z2pFT7v_enAiNuSZV0esPsiHfRGrj7t0-g_Ix5Do,2363
138
- dodal/devices/oav/oav_detector.py,sha256=jdlgXuxEi0Ojjpt-Bz1KOjYlyQyaWfm0XLRw6-MxsFQ,4325
138
+ dodal/devices/oav/oav_detector.py,sha256=uF-5OAoFZYJwBUJkTTQtB89k3g7nj-XKU8IgheP2I0Q,4330
139
139
  dodal/devices/oav/oav_parameters.py,sha256=gGN73TQGUiRzlIO5YKiqCRkjpTKsV6LFGo7Eu4Vs82g,6074
140
140
  dodal/devices/oav/oav_to_redis_forwarder.py,sha256=pfhaW6Uo_1wDNfywyPkS5UTrY8yhkerhjgJfRMqrJRA,6259
141
141
  dodal/devices/oav/utils.py,sha256=3IvSTw6Ygkaz4Hzoz0eU2l6mljpq0NO57M15e-K4jOE,3182
@@ -151,16 +151,16 @@ dodal/devices/training_rig/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
151
151
  dodal/devices/training_rig/sample_stage.py,sha256=jktTp837ij8wor5LidE3AajCk95L7DebJotMlO7QwTE,355
152
152
  dodal/devices/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
153
  dodal/devices/util/adjuster_plans.py,sha256=XpJ1YJKoOCFzj2sonkZYJAdewi3jRaok_2gOmNsfeS0,956
154
- dodal/devices/util/epics_util.py,sha256=A8iNL79PnxntuxPTKA9oLGaDRKhnXaaeAVJwS6FNAWA,4687
154
+ dodal/devices/util/epics_util.py,sha256=3_d0m7BTvN19WIKvz2XSMvoPdTdccg9Z2gOAL-52q4s,4692
155
155
  dodal/devices/util/lookup_tables.py,sha256=3gU9cOBhHBu1S6XqXHWNjCNkV7F4Z-eDlDfesvKbMg4,2185
156
156
  dodal/devices/util/motor_utils.py,sha256=pNY-aUk9LxaIWeDr5rpMS6udiB9j19wcCXkNDLp1uA0,257
157
157
  dodal/devices/util/test_utils.py,sha256=x0QVKVeST4T-wpsVSSm-169MyNRXlmybVWnPTefv1as,565
158
158
  dodal/devices/xspress3/xspress3.py,sha256=75RdPuHpES4Xi-Lcywz0XUhaN2G3vZSoc-dzgcxfNvs,4636
159
159
  dodal/devices/xspress3/xspress3_channel.py,sha256=w8tAx2lz5kJ_LeJ_eb_4o--Dtt8MRijsYNgDG6oEIVg,1626
160
160
  dodal/devices/zebra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
- dodal/devices/zebra/zebra.py,sha256=_OA34T9CcgwXxyajVKai2jz4nHVDaEvMkb5eG5eAYKw,9192
161
+ dodal/devices/zebra/zebra.py,sha256=UPryxnhvEb9Y2hefYWbTZShmVKULghftHyO1LVJRLpI,9248
162
162
  dodal/devices/zebra/zebra_constants_mapping.py,sha256=DCWMvBFvmN90rBpZ4aOVF_hbKm4K6QWubsG811R-MK8,4170
163
- dodal/devices/zebra/zebra_controlled_shutter.py,sha256=5-SH5HoXp_6P-xAtfDFJKQq6mBDwreubuCULSz78fgw,1852
163
+ dodal/devices/zebra/zebra_controlled_shutter.py,sha256=tcBq2WQxST9g2VrjVWu-tOomFX-zGLHLNDhYhL0DtHc,1871
164
164
  dodal/devices/zocalo/__init__.py,sha256=dRAZ9o7B9TACqyE7aanT3yzvqWtt019YgV5ZJY7Ylso,517
165
165
  dodal/devices/zocalo/zocalo_constants.py,sha256=vu7Xjz7UNEpBUWEEBxDvP4bVFkZIN6NLGfQDpWbCjH8,98
166
166
  dodal/devices/zocalo/zocalo_interaction.py,sha256=GFukU9xqagQtVSDg5BrL23jxl1w8wjs4b4NLLqdFfpk,3584
@@ -170,14 +170,14 @@ dodal/plan_stubs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
170
170
  dodal/plan_stubs/check_topup.py,sha256=3gyLHfHNQBCgEWuAg4QE-ONx7y2Do1vVv5HP8ss0Z1I,5371
171
171
  dodal/plan_stubs/data_session.py,sha256=33wPwbs0mtMnle0H76mH_RNTc5omld7gNSJ9BvRdUnM,1570
172
172
  dodal/plan_stubs/motor_utils.py,sha256=4c93U_WgjfmX12uNiztVW2oKxGVWa_SKQdJYCUNmsGU,4653
173
- dodal/plan_stubs/wrapped.py,sha256=nriHKX4BF010CmrhdoUhY3-txClW5W8TPLz64kE_AXU,4533
173
+ dodal/plan_stubs/wrapped.py,sha256=kC8HH7bx3-sLYu2oieY_502tAdT2OECF8n-fqoL5Bfc,4266
174
174
  dodal/plans/__init__.py,sha256=nH1jNxw3DzDMg9O8Uda0kqKIalRVEWBrq07OLY6Ey38,93
175
175
  dodal/plans/save_panda.py,sha256=1fumH7Ih8uDIv8ahAtgQ_vUuR3dz0sfUs4n9TEtEbSs,3053
176
176
  dodal/plans/scanspec.py,sha256=Q0AcvTKRT401iGMRDSqK-D523UX5_ofiVMZ_rNXKOx8,2074
177
177
  dodal/plans/wrapped.py,sha256=BPMw__RcWvk9v5XnhMsi9_k4KsDEbmXogzD2n1ecbUg,2098
178
- dls_dodal-1.40.0.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
179
- dls_dodal-1.40.0.dist-info/METADATA,sha256=PnQZPtkcDPvFdDHEHuhmiUv-n7hULVI-_Rlao38WIuo,16696
180
- dls_dodal-1.40.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
181
- dls_dodal-1.40.0.dist-info/entry_points.txt,sha256=bycw_EKUzup_rxfCetOwcauXV4kLln_OPpPT8jEnr-I,94
182
- dls_dodal-1.40.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
183
- dls_dodal-1.40.0.dist-info/RECORD,,
178
+ dls_dodal-1.41.0.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
179
+ dls_dodal-1.41.0.dist-info/METADATA,sha256=0xKqobHJQk4qTg-57eXoXfkBm1Sgh63jVo4ePiQr2OU,16792
180
+ dls_dodal-1.41.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
181
+ dls_dodal-1.41.0.dist-info/entry_points.txt,sha256=bycw_EKUzup_rxfCetOwcauXV4kLln_OPpPT8jEnr-I,94
182
+ dls_dodal-1.41.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
183
+ dls_dodal-1.41.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
dodal/_version.py CHANGED
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '1.40.0'
16
- __version_tuple__ = version_tuple = (1, 40, 0)
20
+ __version__ = version = '1.41.0'
21
+ __version_tuple__ = version_tuple = (1, 41, 0)
dodal/beamlines/i23.py CHANGED
@@ -1,13 +1,15 @@
1
- from dodal.common.beamlines.beamline_utils import device_instantiation
1
+ from dodal.common.beamlines.beamline_utils import device_factory
2
2
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
3
3
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
4
4
  from dodal.log import set_beamline as set_log_beamline
5
- from dodal.utils import get_beamline_name, get_hostname, skip_device
5
+ from dodal.utils import BeamlinePrefix, get_beamline_name, get_hostname
6
6
 
7
7
  BL = get_beamline_name("i23")
8
8
  set_log_beamline(BL)
9
9
  set_utils_beamline(BL)
10
10
 
11
+ PREFIX = BeamlinePrefix(BL)
12
+
11
13
 
12
14
  def _is_i23_machine():
13
15
  """
@@ -18,16 +20,11 @@ def _is_i23_machine():
18
20
  return hostname.startswith("i23-ws") or hostname.startswith("i23-control")
19
21
 
20
22
 
21
- @skip_device(lambda: not _is_i23_machine())
22
- def oav_pin_tip_detection(
23
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
24
- ) -> PinTipDetection:
23
+ @device_factory(skip=lambda: not _is_i23_machine())
24
+ def oav_pin_tip_detection() -> PinTipDetection:
25
25
  """Get the i23 OAV pin-tip detection device"""
26
26
 
27
- return device_instantiation(
28
- PinTipDetection,
27
+ return PinTipDetection(
28
+ f"{PREFIX.beamline_prefix}-DI-OAV-01:",
29
29
  "pin_tip_detection",
30
- "-DI-OAV-01:",
31
- wait_for_connection,
32
- fake_with_ophyd_sim,
33
30
  )
dodal/beamlines/p38.py CHANGED
@@ -4,16 +4,12 @@ from ophyd_async.epics.adaravis import AravisDetector
4
4
  from ophyd_async.fastcs.panda import HDFPanda
5
5
 
6
6
  from dodal.common.beamlines.beamline_utils import (
7
- device_instantiation,
7
+ device_factory,
8
8
  get_path_provider,
9
9
  set_path_provider,
10
10
  )
11
11
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
12
- from dodal.common.beamlines.device_helpers import (
13
- DET_SUFFIX,
14
- HDF5_SUFFIX,
15
- numbered_slits,
16
- )
12
+ from dodal.common.beamlines.device_helpers import HDF5_SUFFIX
17
13
  from dodal.common.crystal_metadata import (
18
14
  MaterialsEnum,
19
15
  make_crystal_metadata_from_material,
@@ -29,9 +25,10 @@ from dodal.devices.tetramm import TetrammDetector
29
25
  from dodal.devices.undulator import Undulator
30
26
  from dodal.devices.watsonmarlow323_pump import WatsonMarlow323Pump
31
27
  from dodal.log import set_beamline as set_log_beamline
32
- from dodal.utils import BeamlinePrefix, get_beamline_name, skip_device
28
+ from dodal.utils import BeamlinePrefix, get_beamline_name
33
29
 
34
30
  BL = get_beamline_name("p38")
31
+ PREFIX = BeamlinePrefix(BL)
35
32
  set_log_beamline(BL)
36
33
  set_utils_beamline(BL)
37
34
 
@@ -49,63 +46,41 @@ set_path_provider(
49
46
  )
50
47
 
51
48
 
52
- def d3(
53
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
54
- ) -> AravisDetector:
55
- return device_instantiation(
56
- AravisDetector,
57
- "d3",
58
- "-DI-DCAM-01:",
59
- wait_for_connection,
60
- fake_with_ophyd_sim,
61
- drv_suffix=DET_SUFFIX,
62
- fileio_suffix=HDF5_SUFFIX,
49
+ @device_factory()
50
+ def d3() -> AravisDetector:
51
+ return AravisDetector(
52
+ f"{PREFIX.beamline_prefix}-DI-DCAM-01:",
63
53
  path_provider=get_path_provider(),
54
+ drv_suffix="DET:",
55
+ fileio_suffix=HDF5_SUFFIX,
64
56
  )
65
57
 
66
58
 
67
59
  # Disconnected
68
- @skip_device()
69
- def d11(
70
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
71
- ) -> AravisDetector:
72
- return device_instantiation(
73
- AravisDetector,
74
- "d11",
75
- "-DI-DCAM-03:",
76
- wait_for_connection,
77
- fake_with_ophyd_sim,
78
- drv_suffix=DET_SUFFIX,
79
- fileio_suffix=HDF5_SUFFIX,
60
+ @device_factory(skip=True)
61
+ def d11() -> AravisDetector:
62
+ return AravisDetector(
63
+ f"{PREFIX.beamline_prefix}-DI-DCAM-03:",
80
64
  path_provider=get_path_provider(),
65
+ drv_suffix="DET:",
66
+ fileio_suffix=HDF5_SUFFIX,
81
67
  )
82
68
 
83
69
 
84
- def d12(
85
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
86
- ) -> AravisDetector:
87
- return device_instantiation(
88
- AravisDetector,
89
- "d12",
90
- "-DI-DCAM-04:",
91
- wait_for_connection,
92
- fake_with_ophyd_sim,
93
- drv_suffix=DET_SUFFIX,
94
- fileio_suffix=HDF5_SUFFIX,
70
+ @device_factory()
71
+ def d12() -> AravisDetector:
72
+ return AravisDetector(
73
+ f"{PREFIX.beamline_prefix}-DI-DCAM-04:",
95
74
  path_provider=get_path_provider(),
75
+ drv_suffix="DET:",
76
+ fileio_suffix=HDF5_SUFFIX,
96
77
  )
97
78
 
98
79
 
99
- def i0(
100
- wait_for_connection: bool = True,
101
- fake_with_ophyd_sim: bool = False,
102
- ) -> TetrammDetector:
103
- return device_instantiation(
104
- TetrammDetector,
105
- "i0",
106
- "-EA-XBPM-01:",
107
- wait_for_connection,
108
- fake_with_ophyd_sim,
80
+ @device_factory()
81
+ def i0() -> TetrammDetector:
82
+ return TetrammDetector(
83
+ f"{PREFIX.beamline_prefix}-EA-XBPM-01:",
109
84
  path_provider=get_path_provider(),
110
85
  )
111
86
 
@@ -117,126 +92,60 @@ def i0(
117
92
  #
118
93
 
119
94
 
120
- def slits_1(
121
- wait_for_connection: bool = True,
122
- fake_with_ophyd_sim: bool = True,
123
- ) -> Slits:
124
- return numbered_slits(
125
- 1,
126
- wait_for_connection,
127
- fake_with_ophyd_sim,
128
- )
95
+ @device_factory(mock=True)
96
+ def slits_1() -> Slits:
97
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-01:")
129
98
 
130
99
 
131
- def slits_2(
132
- wait_for_connection: bool = True,
133
- fake_with_ophyd_sim: bool = True,
134
- ) -> Slits:
135
- return numbered_slits(
136
- 2,
137
- wait_for_connection,
138
- fake_with_ophyd_sim,
139
- )
100
+ @device_factory(mock=True)
101
+ def slits_2() -> Slits:
102
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-02:")
140
103
 
141
104
 
142
- def slits_3(
143
- wait_for_connection: bool = True,
144
- fake_with_ophyd_sim: bool = True,
145
- ) -> Slits:
146
- return numbered_slits(
147
- 3,
148
- wait_for_connection,
149
- fake_with_ophyd_sim,
150
- )
105
+ @device_factory(mock=True)
106
+ def slits_3() -> Slits:
107
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-03:")
151
108
 
152
109
 
153
- def slits_4(
154
- wait_for_connection: bool = True,
155
- fake_with_ophyd_sim: bool = True,
156
- ) -> Slits:
157
- return numbered_slits(
158
- 4,
159
- wait_for_connection,
160
- fake_with_ophyd_sim,
161
- )
110
+ @device_factory(mock=True)
111
+ def slits_4() -> Slits:
112
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-04:")
162
113
 
163
114
 
164
- def slits_5(
165
- wait_for_connection: bool = True,
166
- fake_with_ophyd_sim: bool = True,
167
- ) -> Slits:
168
- return numbered_slits(
169
- 5,
170
- wait_for_connection,
171
- fake_with_ophyd_sim,
172
- )
115
+ @device_factory(mock=True)
116
+ def slits_5() -> Slits:
117
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-05:")
173
118
 
174
119
 
175
- def slits_6(
176
- wait_for_connection: bool = True,
177
- fake_with_ophyd_sim: bool = True,
178
- ) -> Slits:
179
- return numbered_slits(
180
- 6,
181
- wait_for_connection,
182
- fake_with_ophyd_sim,
183
- )
120
+ @device_factory(mock=True)
121
+ def slits_6() -> Slits:
122
+ return Slits(f"{PREFIX.beamline_prefix}-AL-SLITS-06:")
184
123
 
185
124
 
186
- def fswitch(
187
- wait_for_connection: bool = True,
188
- fake_with_ophyd_sim: bool = True,
189
- ) -> FSwitch:
190
- return device_instantiation(
191
- FSwitch,
192
- "fswitch",
193
- "-MO-FSWT-01:",
194
- wait_for_connection,
195
- fake_with_ophyd_sim,
125
+ @device_factory(mock=True)
126
+ def fswitch() -> FSwitch:
127
+ return FSwitch(
128
+ f"{PREFIX.beamline_prefix}-MO-FSWT-01:",
196
129
  lens_geometry="paraboloid",
197
130
  cylindrical=True,
198
131
  lens_material="Beryllium",
199
132
  )
200
133
 
201
134
 
202
- def vfm(
203
- wait_for_connection: bool = True,
204
- fake_with_ophyd_sim: bool = True,
205
- ) -> FocusingMirror:
206
- return device_instantiation(
207
- FocusingMirror,
208
- "vfm",
209
- "-OP-KBM-01:VFM:",
210
- wait_for_connection,
211
- fake_with_ophyd_sim,
212
- )
135
+ @device_factory(mock=True)
136
+ def vfm() -> FocusingMirror:
137
+ return FocusingMirror(f"{PREFIX.beamline_prefix}-OP-KBM-01:VFM:")
213
138
 
214
139
 
215
- def hfm(
216
- wait_for_connection: bool = True,
217
- fake_with_ophyd_sim: bool = True,
218
- ) -> FocusingMirror:
219
- return device_instantiation(
220
- FocusingMirror,
221
- "hfm",
222
- "-OP-KBM-01:HFM:",
223
- wait_for_connection,
224
- fake_with_ophyd_sim,
225
- )
140
+ @device_factory(mock=True)
141
+ def hfm() -> FocusingMirror:
142
+ return FocusingMirror(f"{PREFIX.beamline_prefix}-OP-KBM-01:HFM:")
226
143
 
227
144
 
228
- def dcm(
229
- wait_for_connection: bool = True,
230
- fake_with_ophyd_sim: bool = True,
231
- ) -> DoubleCrystalMonochromator:
232
- return device_instantiation(
233
- DoubleCrystalMonochromator,
234
- "dcm",
235
- f"{BeamlinePrefix(BL).beamline_prefix}-MO-DCM-01:",
236
- wait_for_connection,
237
- fake_with_ophyd_sim,
238
- bl_prefix=False,
239
- temperature_prefix=f"{BeamlinePrefix(BL).beamline_prefix}-DI-DCM-01:",
145
+ @device_factory(mock=True)
146
+ def dcm() -> DoubleCrystalMonochromator:
147
+ return DoubleCrystalMonochromator(
148
+ temperature_prefix=f"{PREFIX.beamline_prefix}-DI-DCM-01:",
240
149
  crystal_1_metadata=make_crystal_metadata_from_material(
241
150
  MaterialsEnum.Si, (1, 1, 1)
242
151
  ),
@@ -246,105 +155,56 @@ def dcm(
246
155
  )
247
156
 
248
157
 
249
- def undulator(
250
- wait_for_connection: bool = True,
251
- fake_with_ophyd_sim: bool = True,
252
- ) -> Undulator:
253
- return device_instantiation(
254
- Undulator,
255
- "undulator",
256
- f"{BeamlinePrefix(BL).insertion_prefix}-MO-SERVC-01:",
257
- wait_for_connection,
258
- fake_with_ophyd_sim,
259
- bl_prefix=False,
158
+ @device_factory(mock=True)
159
+ def undulator() -> Undulator:
160
+ return Undulator(
161
+ f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
260
162
  poles=80,
261
163
  length=2.0,
262
164
  )
263
165
 
264
166
 
265
- # Must find which PandA IOC(s) are compatible
266
167
  # Must document what PandAs are physically connected to
267
168
  # See: https://github.com/bluesky/ophyd-async/issues/284
268
- @skip_device()
269
- def panda1(
270
- wait_for_connection: bool = True,
271
- fake_with_ophyd_sim: bool = False,
272
- ) -> HDFPanda:
273
- return device_instantiation(
274
- HDFPanda,
275
- "panda1",
276
- "-EA-PANDA-01:",
277
- wait_for_connection,
278
- fake_with_ophyd_sim,
169
+ @device_factory(skip=True)
170
+ def panda1() -> HDFPanda:
171
+ return HDFPanda(
172
+ f"{PREFIX.beamline_prefix}-EA-PANDA-01:",
279
173
  path_provider=get_path_provider(),
280
174
  )
281
175
 
282
176
 
283
- @skip_device()
284
- def panda2(
285
- wait_for_connection: bool = True,
286
- fake_with_ophyd_sim: bool = False,
287
- ) -> HDFPanda:
288
- return device_instantiation(
289
- HDFPanda,
290
- "panda2",
291
- "-EA-PANDA-02:",
292
- wait_for_connection,
293
- fake_with_ophyd_sim,
177
+ @device_factory(skip=True)
178
+ def panda2() -> HDFPanda:
179
+ return HDFPanda(
180
+ f"{PREFIX.beamline_prefix}-EA-PANDA-02:",
294
181
  path_provider=get_path_provider(),
295
182
  )
296
183
 
297
184
 
298
- @skip_device()
299
- def panda3(
300
- wait_for_connection: bool = True,
301
- fake_with_ophyd_sim: bool = False,
302
- ) -> HDFPanda:
303
- return device_instantiation(
304
- HDFPanda,
305
- "panda3",
306
- "-EA-PANDA-03:",
307
- wait_for_connection,
308
- fake_with_ophyd_sim,
185
+ @device_factory(skip=True)
186
+ def panda3() -> HDFPanda:
187
+ return HDFPanda(
188
+ f"{PREFIX.beamline_prefix}-EA-PANDA-03:",
309
189
  path_provider=get_path_provider(),
310
190
  )
311
191
 
312
192
 
313
- @skip_device()
314
- def linkam(
315
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
316
- ) -> Linkam3:
317
- return device_instantiation(
318
- Linkam3,
319
- "linkam",
320
- f"{BeamlinePrefix(BL).insertion_prefix}-EA-LINKM-02:",
321
- wait_for_connection,
322
- fake_with_ophyd_sim,
323
- )
193
+ @device_factory(skip=True)
194
+ def linkam() -> Linkam3:
195
+ return Linkam3(f"{PREFIX.beamline_prefix}-EA-LINKM-02:")
324
196
 
325
197
 
326
- def ppump(
327
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = True
328
- ) -> WatsonMarlow323Pump:
198
+ @device_factory()
199
+ def ppump() -> WatsonMarlow323Pump:
329
200
  """Peristaltic Pump"""
330
- return device_instantiation(
331
- WatsonMarlow323Pump,
332
- "ppump",
333
- "-EA-PUMP-01:",
334
- wait_for_connection,
335
- fake_with_ophyd_sim,
336
- )
201
+ return WatsonMarlow323Pump(f"{PREFIX.beamline_prefix}-EA-PUMP-01:")
337
202
 
338
203
 
339
- def high_pressure_xray_cell(
340
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
341
- ) -> PressureJumpCell:
342
- return device_instantiation(
343
- PressureJumpCell,
344
- "high_pressure_xray_cell",
345
- "-EA",
346
- wait_for_connection,
347
- fake_with_ophyd_sim,
204
+ @device_factory()
205
+ def high_pressure_xray_cell() -> PressureJumpCell:
206
+ return PressureJumpCell(
207
+ f"{PREFIX.beamline_prefix}-EA",
348
208
  cell_prefix="-HPXC-01:",
349
209
  adc_prefix="-ADC",
350
210
  )
@@ -123,7 +123,7 @@ def load_positions_from_beamline_parameters(
123
123
  }
124
124
 
125
125
 
126
- class ApertureScatterguard(StandardReadable, Movable, Preparable):
126
+ class ApertureScatterguard(StandardReadable, Movable[ApertureValue], Preparable):
127
127
  """Move the aperture and scatterguard assembly in a safe way. There are two ways to
128
128
  interact with the device depending on if you want simplicity or move flexibility.
129
129
 
@@ -1,7 +1,7 @@
1
1
  import abc
2
2
  import asyncio
3
3
  from dataclasses import dataclass
4
- from typing import Any
4
+ from typing import Any, Generic, TypeVar
5
5
 
6
6
  import numpy as np
7
7
  from bluesky.protocols import Movable
@@ -21,6 +21,8 @@ from pydantic import BaseModel, ConfigDict, RootModel
21
21
 
22
22
  from dodal.log import LOGGER
23
23
 
24
+ T = TypeVar("T")
25
+
24
26
 
25
27
  class UndulatorGateStatus(StrictEnum):
26
28
  OPEN = "Open"
@@ -99,7 +101,7 @@ async def estimate_motor_timeout(
99
101
  return abs((target_pos - cur_pos) * 2.0 / vel) + 1
100
102
 
101
103
 
102
- class SafeUndulatorMover(StandardReadable, Movable):
104
+ class SafeUndulatorMover(StandardReadable, Movable[T], Generic[T]):
103
105
  """A device that will check it's safe to move the undulator before moving it and
104
106
  wait for the undulator to be safe again before calling the move complete.
105
107
  """
@@ -115,7 +117,7 @@ class SafeUndulatorMover(StandardReadable, Movable):
115
117
  super().__init__(name)
116
118
 
117
119
  @AsyncStatus.wrap
118
- async def set(self, value) -> None:
120
+ async def set(self, value: T) -> None:
119
121
  LOGGER.info(f"Setting {self.name} to {value}")
120
122
  await self.raise_if_cannot_move()
121
123
  await self._set_demand_positions(value)
@@ -125,7 +127,7 @@ class SafeUndulatorMover(StandardReadable, Movable):
125
127
  await wait_for_value(self.gate, UndulatorGateStatus.CLOSE, timeout=timeout)
126
128
 
127
129
  @abc.abstractmethod
128
- async def _set_demand_positions(self, value) -> None:
130
+ async def _set_demand_positions(self, value: T) -> None:
129
131
  """Set the demand positions on the device without actually hitting move."""
130
132
 
131
133
  @abc.abstractmethod
@@ -139,7 +141,7 @@ class SafeUndulatorMover(StandardReadable, Movable):
139
141
  raise RuntimeError(f"{self.name} is already in motion.")
140
142
 
141
143
 
142
- class UndulatorGap(SafeUndulatorMover):
144
+ class UndulatorGap(SafeUndulatorMover[float]):
143
145
  """A device with a collection of epics signals to set Apple 2 undulator gap motion.
144
146
  Only PV used by beamline are added the full list is here:
145
147
  /dls_sw/work/R3.14.12.7/support/insertionDevice/db/IDGapVelocityControl.template
@@ -185,7 +187,7 @@ class UndulatorGap(SafeUndulatorMover):
185
187
  self.user_readback = epics_signal_r(float, prefix + "CURRGAPD")
186
188
  super().__init__(self.set_move, prefix, name)
187
189
 
188
- async def _set_demand_positions(self, value) -> None:
190
+ async def _set_demand_positions(self, value: float) -> None:
189
191
  await self.user_setpoint.set(str(value))
190
192
 
191
193
  async def get_timeout(self) -> float:
@@ -234,7 +236,7 @@ class UndulatorPhaseMotor(StandardReadable):
234
236
  super().__init__(name=name)
235
237
 
236
238
 
237
- class UndulatorPhaseAxes(SafeUndulatorMover):
239
+ class UndulatorPhaseAxes(SafeUndulatorMover[Apple2PhasesVal]):
238
240
  """
239
241
  A collection of 4 phase Motor to make up the full id phase motion. We are using the diamond pv convention.
240
242
  e.g. top_outer == Q1
@@ -290,7 +292,7 @@ class UndulatorPhaseAxes(SafeUndulatorMover):
290
292
  return np.max(timeouts)
291
293
 
292
294
 
293
- class UndulatorJawPhase(SafeUndulatorMover):
295
+ class UndulatorJawPhase(SafeUndulatorMover[float]):
294
296
  """
295
297
  A JawPhase movable, this is use for moving the jaw phase which is use to control the
296
298
  linear arbitrary polarisation but only one some of the beamline.
@@ -29,7 +29,7 @@ class ReadOnlyAttenuator(StandardReadable):
29
29
  super().__init__(name)
30
30
 
31
31
 
32
- class BinaryFilterAttenuator(ReadOnlyAttenuator, Movable):
32
+ class BinaryFilterAttenuator(ReadOnlyAttenuator, Movable[float]):
33
33
  """The attenuator will insert filters into the beam to reduce its transmission.
34
34
  In this attenuator, each filter can be in one of two states: IN or OUT
35
35
 
@@ -15,7 +15,7 @@ class BacklightPosition(StrictEnum):
15
15
  OUT = "Out"
16
16
 
17
17
 
18
- class Backlight(StandardReadable, Movable):
18
+ class Backlight(StandardReadable, Movable[BacklightPosition]):
19
19
  """Simple device to trigger the pneumatic in/out."""
20
20
 
21
21
  TIME_TO_MOVE_S = 1.0 # Tested using a stopwatch on the beamline 09/2024
@@ -41,7 +41,7 @@ class BimorphMirrorStatus(StrictEnum):
41
41
  ERROR = "Error"
42
42
 
43
43
 
44
- class BimorphMirrorChannel(StandardReadable, Movable, EpicsDevice):
44
+ class BimorphMirrorChannel(StandardReadable, Movable[float], EpicsDevice):
45
45
  """Collection of PVs comprising a single bimorph channel.
46
46
 
47
47
  Attributes:
@@ -66,7 +66,7 @@ class BimorphMirrorChannel(StandardReadable, Movable, EpicsDevice):
66
66
  await self.output_voltage.set(value)
67
67
 
68
68
 
69
- class BimorphMirror(StandardReadable, Movable):
69
+ class BimorphMirror(StandardReadable, Movable[Mapping[int, float]]):
70
70
  """Class to represent CAENels Bimorph Mirrors.
71
71
 
72
72
  Attributes:
@@ -200,6 +200,7 @@ class FastGridScanCommon(StandardReadable, Flyable, ABC, Generic[ParamType]):
200
200
  self.scan_invalid = epics_signal_r(float, f"{prefix}SCAN_INVALID")
201
201
 
202
202
  self.run_cmd = epics_signal_x(f"{prefix}RUN.PROC")
203
+ self.stop_cmd = epics_signal_x(f"{prefix}STOP.PROC")
203
204
  self.status = epics_signal_r(int, f"{prefix}SCAN_STATUS")
204
205
 
205
206
  self.expected_images = create_hardware_backed_soft_signal(
@@ -257,7 +258,15 @@ class FastGridScanCommon(StandardReadable, Flyable, ABC, Generic[ParamType]):
257
258
 
258
259
  @AsyncStatus.wrap
259
260
  async def complete(self):
260
- await wait_for_value(self.status, 0, self.COMPLETE_STATUS)
261
+ try:
262
+ await wait_for_value(self.status, 0, self.COMPLETE_STATUS)
263
+ except asyncio.TimeoutError:
264
+ LOGGER.error(
265
+ "Hyperion timed out waiting for FGS motion to complete. This may have been caused by a goniometer stage getting stuck.\n\
266
+ Forcibly stopping the FGS motion program..."
267
+ )
268
+ await self.stop_cmd.trigger()
269
+ raise
261
270
 
262
271
  @abstractmethod
263
272
  def _create_position_counter(self, prefix: str) -> SignalRW[int]:
@@ -55,7 +55,7 @@ class HutchInterlock(StandardReadable):
55
55
  return interlock_state == HUTCH_SAFE_FOR_OPERATIONS
56
56
 
57
57
 
58
- class HutchShutter(StandardReadable, Movable):
58
+ class HutchShutter(StandardReadable, Movable[ShutterDemand]):
59
59
  """Device to operate the hutch shutter.
60
60
 
61
61
  When a demand is sent, the device should first check the hutch status \
@@ -175,7 +175,7 @@ class I10Apple2(Apple2):
175
175
  self._available_pol = list(self.lookup_tables["Gap"].keys())
176
176
 
177
177
 
178
- class I10Apple2PGM(StandardReadable, Movable):
178
+ class I10Apple2PGM(StandardReadable, Movable[float]):
179
179
  """
180
180
  Compound device to set both ID and PGM energy at the sample time,poly_deg
181
181
 
@@ -211,7 +211,7 @@ class I10Apple2PGM(StandardReadable, Movable):
211
211
  )
212
212
 
213
213
 
214
- class I10Apple2Pol(StandardReadable, Movable):
214
+ class I10Apple2Pol(StandardReadable, Movable[str]):
215
215
  """
216
216
  Compound device to set polorisation of ID.
217
217
  """
@@ -240,7 +240,7 @@ class I10Apple2Pol(StandardReadable, Movable):
240
240
  ) # Move id to new polarisation
241
241
 
242
242
 
243
- class LinearArbitraryAngle(StandardReadable, Movable):
243
+ class LinearArbitraryAngle(StandardReadable, Movable[SupportsFloat]):
244
244
  """
245
245
  Device to set polorisation angle of the ID. Linear Arbitrary Angle (laa)
246
246
  is the direction of the magnetic field which can be change by varying the jaw_phase
@@ -18,7 +18,7 @@ class HutchState(str, Enum):
18
18
  INVALID = "INVALID"
19
19
 
20
20
 
21
- class HutchConditionalShutter(StandardReadable, Movable):
21
+ class HutchConditionalShutter(StandardReadable, Movable[ShutterDemand]):
22
22
  """ I19-specific device to operate the hutch shutter.
23
23
 
24
24
  This device evaluates the hutch state value to work out which of the two I19 \
dodal/devices/i24/pmac.py CHANGED
@@ -71,7 +71,7 @@ class PMACStringMove(Triggerable):
71
71
  await self.signal_ref().set(self.cmd_string, wait=True)
72
72
 
73
73
 
74
- class PMACStringLaser(Device, Movable):
74
+ class PMACStringLaser(Device, Movable[LaserSettings]):
75
75
  """Set the pmac_string to control the laser."""
76
76
 
77
77
  def __init__(
@@ -90,7 +90,7 @@ class PMACStringLaser(Device, Movable):
90
90
  await self._signal_ref().set(value.value)
91
91
 
92
92
 
93
- class PMACStringEncReset(Device, Movable):
93
+ class PMACStringEncReset(Device, Movable[EncReset]):
94
94
  """Set a pmac_string to control the encoder channels in the controller."""
95
95
 
96
96
  def __init__(
@@ -29,7 +29,7 @@ def _get_correct_zoom_string(zoom: str) -> str:
29
29
  return zoom
30
30
 
31
31
 
32
- class ZoomController(StandardReadable, Movable):
32
+ class ZoomController(StandardReadable, Movable[str]):
33
33
  """
34
34
  Device to control the zoom level. This should be set like
35
35
  o = OAV(name="oav")
@@ -41,8 +41,8 @@ class ValveControlRequest(StrictEnum):
41
41
 
42
42
 
43
43
  class ValveOpenSeqRequest(StrictEnum):
44
- INACTIVE = 0
45
- OPEN_SEQ = 1
44
+ INACTIVE = "0"
45
+ OPEN_SEQ = "1"
46
46
 
47
47
 
48
48
  class PumpMotorDirectionState(StrictEnum):
@@ -76,7 +76,7 @@ class AllValvesControlState:
76
76
  valve_6: FastValveControlRequest | None = None
77
77
 
78
78
 
79
- class AllValvesControl(StandardReadable, Movable):
79
+ class AllValvesControl(StandardReadable, Movable[AllValvesControlState]):
80
80
  """
81
81
  valves 2, 4, 7, 8 are not controlled by the IOC,
82
82
  as they are under manual control.
@@ -151,7 +151,9 @@ class AllValvesControl(StandardReadable, Movable):
151
151
  )
152
152
 
153
153
 
154
- class ValveControl(StandardReadable, Movable):
154
+ class ValveControl(
155
+ StandardReadable, Movable[ValveControlRequest | ValveOpenSeqRequest]
156
+ ):
155
157
  def __init__(self, prefix: str, name: str = "") -> None:
156
158
  with self.add_children_as_readables():
157
159
  self.close = epics_signal_rw(ValveControlRequest, prefix + ":CON")
@@ -170,7 +172,9 @@ class ValveControl(StandardReadable, Movable):
170
172
  return set_status
171
173
 
172
174
 
173
- class FastValveControl(StandardReadable, Movable):
175
+ class FastValveControl(
176
+ StandardReadable, Movable[FastValveControlRequest | ValveOpenSeqRequest]
177
+ ):
174
178
  def __init__(self, prefix: str, name: str = "") -> None:
175
179
  with self.add_children_as_readables():
176
180
  self.close = epics_signal_rw(FastValveControlRequest, prefix + ":CON")
@@ -235,6 +239,9 @@ class PressureTransducer(StandardReadable):
235
239
  self.beckhoff_pressure = epics_signal_r(
236
240
  float, f"{final_prefix}STATP{transducer_number}:MeanValue_RBV"
237
241
  )
242
+ # P1 beckhoff voltage = BL38P-EA-ADC-02:CH1
243
+ # P2 beckhoff voltage = BL38P-EA-ADC-01:CH2
244
+ # P3 beckhoff voltage = BL38P-EA-ADC-01:CH1
238
245
  self.slow_beckhoff_voltage_readout = epics_signal_r(
239
246
  float, f"{full_different_prefix_adc}CH{ethercat_channel_number}"
240
247
  )
dodal/devices/robot.py CHANGED
@@ -52,7 +52,7 @@ class ErrorStatus(Device):
52
52
  raise RobotLoadFailed(int(error_code), error_string) from raise_from
53
53
 
54
54
 
55
- class BartRobot(StandardReadable, Movable):
55
+ class BartRobot(StandardReadable, Movable[SampleLocation]):
56
56
  """The sample changing robot."""
57
57
 
58
58
  # How long to wait for the robot if it is busy soaking/drying
dodal/devices/thawer.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from asyncio import Task, create_task, sleep
2
2
 
3
- from bluesky.protocols import Stoppable
3
+ from bluesky.protocols import Movable, Stoppable
4
4
  from ophyd_async.core import (
5
5
  AsyncStatus,
6
6
  Device,
@@ -21,18 +21,18 @@ class ThawerStates(StrictEnum):
21
21
  ON = "On"
22
22
 
23
23
 
24
- class ThawingTimer(Device, Stoppable):
24
+ class ThawingTimer(Device, Stoppable, Movable[float]):
25
25
  def __init__(self, control_signal: SignalRW[ThawerStates]) -> None:
26
26
  self._control_signal_ref = Reference(control_signal)
27
27
  self._thawing_task: Task | None = None
28
28
  super().__init__("thaw_for_time_s")
29
29
 
30
30
  @AsyncStatus.wrap
31
- async def set(self, time_to_thaw_for: float):
31
+ async def set(self, value: float):
32
32
  await self._control_signal_ref().set(ThawerStates.ON)
33
33
  if self._thawing_task and not self._thawing_task.done():
34
34
  raise ThawingException("Thawing task already in progress")
35
- self._thawing_task = create_task(sleep(time_to_thaw_for))
35
+ self._thawing_task = create_task(sleep(value))
36
36
  try:
37
37
  await self._thawing_task
38
38
  finally:
@@ -46,7 +46,7 @@ def _get_closest_gap_for_energy(
46
46
  return table[1][idx]
47
47
 
48
48
 
49
- class Undulator(StandardReadable, Movable):
49
+ class Undulator(StandardReadable, Movable[float]):
50
50
  """
51
51
  An Undulator-type insertion device, used to control photon emission at a given
52
52
  beam energy.
@@ -12,7 +12,7 @@ from .undulator import Undulator
12
12
  ENERGY_TIMEOUT_S: float = 30.0
13
13
 
14
14
 
15
- class UndulatorDCM(StandardReadable, Movable):
15
+ class UndulatorDCM(StandardReadable, Movable[float]):
16
16
  """
17
17
  Composite device to handle changing beamline energies, wraps the Undulator and the
18
18
  DCM. The DCM has a motor which controls the beam energy, when it moves, the
@@ -114,7 +114,7 @@ def call_func(func: Callable[[], StatusBase]) -> StatusBase:
114
114
  return func()
115
115
 
116
116
 
117
- class SetWhenEnabled(OphydAsyncDevice, Movable):
117
+ class SetWhenEnabled(OphydAsyncDevice, Movable[int]):
118
118
  """A device that sets the proc field of a PV when it becomes enabled."""
119
119
 
120
120
  def __init__(self, name: str = "", prefix: str = ""):
@@ -4,6 +4,7 @@ import asyncio
4
4
  from enum import Enum
5
5
  from functools import partialmethod
6
6
 
7
+ from bluesky.protocols import Movable
7
8
  from ophyd_async.core import (
8
9
  AsyncStatus,
9
10
  DeviceVector,
@@ -74,7 +75,7 @@ class SoftInState(StrictEnum):
74
75
  NO = "No"
75
76
 
76
77
 
77
- class ArmingDevice(StandardReadable):
78
+ class ArmingDevice(StandardReadable, Movable[ArmDemand]):
78
79
  """A useful device that can abstract some of the logic of arming.
79
80
  Allows a user to just call arm.set(ArmDemand.ARM)"""
80
81
 
@@ -94,8 +95,8 @@ class ArmingDevice(StandardReadable):
94
95
  return
95
96
 
96
97
  @AsyncStatus.wrap
97
- async def set(self, demand: ArmDemand):
98
- await asyncio.wait_for(self._set_armed(demand), timeout=self.TIMEOUT)
98
+ async def set(self, value: ArmDemand):
99
+ await asyncio.wait_for(self._set_armed(value), timeout=self.TIMEOUT)
99
100
 
100
101
 
101
102
  class PositionCompare(StandardReadable):
@@ -19,7 +19,7 @@ class ZebraShutterControl(StrictEnum):
19
19
  AUTO = "Auto"
20
20
 
21
21
 
22
- class ZebraShutter(StandardReadable, Movable):
22
+ class ZebraShutter(StandardReadable, Movable[ZebraShutterState]):
23
23
  """The shutter on most MX beamlines is controlled by the zebra.
24
24
 
25
25
  Internally in the zebra there are two AND gates, one for manual control and one for
@@ -1,6 +1,6 @@
1
1
  import itertools
2
2
  from collections.abc import Mapping
3
- from typing import Annotated, Any
3
+ from typing import Annotated, TypeVar
4
4
 
5
5
  import bluesky.plan_stubs as bps
6
6
  from bluesky.protocols import Movable
@@ -12,17 +12,17 @@ Wrappers for Bluesky built-in plan stubs with type hinting
12
12
 
13
13
  Group = Annotated[str, "String identifier used by 'wait' or stubs that await"]
14
14
 
15
+ T = TypeVar("T")
16
+
15
17
 
16
- # After bluesky 1.14, bounds for stubs that move can be narrowed
17
- # https://github.com/bluesky/bluesky/issues/1821
18
18
  def set_absolute(
19
- movable: Movable, value: Any, group: Group | None = None, wait: bool = False
19
+ movable: Movable[T], value: T, group: Group | None = None, wait: bool = False
20
20
  ) -> MsgGenerator:
21
21
  """
22
22
  Set a device, wrapper for `bp.abs_set`.
23
23
 
24
24
  Args:
25
- movable (Movable): The device to set
25
+ movable (Movable[T]): The device to set
26
26
  value (T): The new value
27
27
  group (Group | None, optional): The message group to associate with the
28
28
  setting, for sequencing. Defaults to None.
@@ -39,7 +39,7 @@ def set_absolute(
39
39
 
40
40
 
41
41
  def set_relative(
42
- movable: Movable, value: Any, group: Group | None = None, wait: bool = False
42
+ movable: Movable[T], value: T, group: Group | None = None, wait: bool = False
43
43
  ) -> MsgGenerator:
44
44
  """
45
45
  Change a device, wrapper for `bp.rel_set`.
@@ -62,7 +62,7 @@ def set_relative(
62
62
  return (yield from bps.rel_set(movable, value, group=group, wait=wait))
63
63
 
64
64
 
65
- def move(moves: Mapping[Movable, Any], group: Group | None = None) -> MsgGenerator:
65
+ def move(moves: Mapping[Movable[T], T], group: Group | None = None) -> MsgGenerator:
66
66
  """
67
67
  Move a device, wrapper for `bp.mv`.
68
68
 
@@ -79,13 +79,12 @@ def move(moves: Mapping[Movable, Any], group: Group | None = None) -> MsgGenerat
79
79
  """
80
80
 
81
81
  return (
82
- # type ignore until https://github.com/bluesky/bluesky/issues/1809
83
- yield from bps.mv(*itertools.chain.from_iterable(moves.items()), group=group) # type: ignore
82
+ yield from bps.mv(*itertools.chain.from_iterable(moves.items()), group=group)
84
83
  )
85
84
 
86
85
 
87
86
  def move_relative(
88
- moves: Mapping[Movable, Any], group: Group | None = None
87
+ moves: Mapping[Movable[T], T], group: Group | None = None
89
88
  ) -> MsgGenerator:
90
89
  """
91
90
  Move a device relative to its current position, wrapper for `bp.mvr`.
@@ -103,8 +102,7 @@ def move_relative(
103
102
  """
104
103
 
105
104
  return (
106
- # type ignore until https://github.com/bluesky/bluesky/issues/1809
107
- yield from bps.mvr(*itertools.chain.from_iterable(moves.items()), group=group) # type: ignore
105
+ yield from bps.mvr(*itertools.chain.from_iterable(moves.items()), group=group)
108
106
  )
109
107
 
110
108
 
dodal/utils.py CHANGED
@@ -16,6 +16,7 @@ from typing import (
16
16
  Any,
17
17
  Generic,
18
18
  Protocol,
19
+ TypeAlias,
19
20
  TypeGuard,
20
21
  TypeVar,
21
22
  runtime_checkable,
@@ -43,12 +44,6 @@ from ophyd_async.core import Device as OphydV2Device
43
44
 
44
45
  import dodal.log
45
46
 
46
- try:
47
- from typing import TypeAlias
48
- except ImportError:
49
- from typing import TypeAlias
50
-
51
-
52
47
  #: Protocols defining interface to hardware
53
48
  BLUESKY_PROTOCOLS = [
54
49
  Checkable,