dls-dodal 1.40.0__py3-none-any.whl → 1.42.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.42.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
@@ -217,7 +217,7 @@ License-File: LICENSE
217
217
  Requires-Dist: click
218
218
  Requires-Dist: ophyd
219
219
  Requires-Dist: ophyd-async>=0.9.0a2
220
- Requires-Dist: bluesky
220
+ Requires-Dist: bluesky==1.13.0
221
221
  Requires-Dist: pyepics
222
222
  Requires-Dist: dataclasses-json
223
223
  Requires-Dist: pillow
@@ -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"
@@ -249,6 +250,7 @@ Requires-Dist: pyright; 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,29 +1,31 @@
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=ovREbwPKWGv5kafSj2cj_y_IxXNlgemp5GRlT3e-7yQ,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
10
- dodal/beamlines/__init__.py,sha256=VJOFt2N6Ge-kvKzpiGee8so2Qs1BLO4k7SYFaF3lG8U,3118
11
- dodal/beamlines/adsim.py,sha256=_LMMjPou7r-T8Jt9ZSj2SGFLuDUju_WNtF5ID6xiZJU,1925
10
+ dodal/beamlines/__init__.py,sha256=dTmVSfeEVUHgxOTQO94lbQQiJHfFcvK2RAwVeTpCqxo,3150
11
+ dodal/beamlines/adsim.py,sha256=uOmFYZIGyput93XHk9R5ydZdxnTrS_wA2zSEm62UCVU,1930
12
+ dodal/beamlines/aithre.py,sha256=1q7zeMYunOBIWCm203NIkCl5tgVl_-jMWc0f5af-W_E,263
12
13
  dodal/beamlines/b01_1.py,sha256=-NYuJv6FhOgJvNYqDtpYb5HucI5_0HS4uDphRXUWzl4,1807
13
14
  dodal/beamlines/i02_1.py,sha256=d2IyqFMgeaSEyZYm7GMSjTKr7_02SakyC_oARx-XwnY,1204
14
15
  dodal/beamlines/i03.py,sha256=q0dMF0W44kCNXiXOUENaUv3nmAfxyOSr5C1zPonCbvk,14856
15
- dodal/beamlines/i04.py,sha256=IwZOnRPL1PC0Oe8m_L4xwXVW2IYJBo0wSbADLWBupyg,12128
16
+ dodal/beamlines/i04.py,sha256=V0fgXfEJnkh0spDXelK6zwjFChN6VaV9_CtrxJLZx2E,12100
16
17
  dodal/beamlines/i10.py,sha256=lkn_xg0pt-vFuWkUGyl62A0xT-Rzs71JztJ1EeQkMi0,11487
17
18
  dodal/beamlines/i13_1.py,sha256=EgnBzsJ55BmsBtq2sDHD6pKnWZsqqAtL0ZM-JP908zE,2467
18
19
  dodal/beamlines/i18.py,sha256=Y5qLniqUkbYHcGGLPdBbiMILQHonPT2oz5M1hKMGqzs,3434
19
20
  dodal/beamlines/i19_1.py,sha256=I5vz64UsVUkDDT7itdpGVFuYq8zkmPECB0rCbCVUkAY,2325
20
21
  dodal/beamlines/i19_2.py,sha256=DihbYZ27rCdF7fvBclyhZ6Rf0YRSs2rc7hmDNtEr6cA,1939
22
+ dodal/beamlines/i19_optics.py,sha256=TAl2ZNVveRGSbdxRjZC_vW8XFrCZlFB648Bkz7g-8oM,1148
21
23
  dodal/beamlines/i20_1.py,sha256=7ZZhPfjjKAhGjdXOI6mu2FPbMbsSjFHJOPa1toZRa0U,1725
22
24
  dodal/beamlines/i22.py,sha256=XCAVBkZxN9cmxfpGoWaCvo77lu8hVIJ_e3BUc_qxdu0,7664
23
- dodal/beamlines/i23.py,sha256=2j5qLoqE_hg9ETHqNkOVu7LLkVB8qalgXeORnVYKN_I,1075
25
+ dodal/beamlines/i23.py,sha256=Qnu3Rk9gb2BD3YolMqUXiupt0ehxw5rVnfPJXBWFoCU,973
24
26
  dodal/beamlines/i24.py,sha256=9rBQMCWGdKiRnFbcVvmjiBWiC9WJIJCtLh5m6LkHUtU,7096
25
- dodal/beamlines/p38.py,sha256=hz-njuiP82LpsTlG0s9dy-CCszJtVmJNzy3bCWLAjE0,8772
26
- dodal/beamlines/p45.py,sha256=0mQ_AEURczc7yzfJzR9QK9i-b6rBGIjGZ4xCIdLNfdI,3031
27
+ dodal/beamlines/p38.py,sha256=MwxBqYe_rUIj-MCRIFZpHJmR0JtA22bSFKfBpoDI9P0,5777
28
+ dodal/beamlines/p45.py,sha256=2snO895TGwf4LbNIvg4BkvAGSfvZcevdpv_82MRpXKo,2129
27
29
  dodal/beamlines/p99.py,sha256=k24QhYpoOHBd0188Fu3wvmpT6dsu8okiIVqVVckdBkw,1063
28
30
  dodal/beamlines/training_rig.py,sha256=8u1TulTFgvu28sfo6vFY-uo_VBAYKT66ENXTqegw3y0,1940
29
31
  dodal/common/__init__.py,sha256=ZC4ICKUDB0BDxRaVy8nmqclVmDBne-dPtk6UJsoFq6I,258
@@ -33,7 +35,7 @@ dodal/common/maths.py,sha256=K9x7iL3xXLtWYTV-xlFHDNSTIL9a2UP3Ws7wr6Dm2rQ,1803
33
35
  dodal/common/signal_utils.py,sha256=-p4h7xtGPp13t6HTjgFGcs5nN22kVArlkfCPVjpLuRU,1728
34
36
  dodal/common/types.py,sha256=fkL7UOwDbe3v2_VJ5f1W5RxR98Wx-Ra-LxUZWkNDtls,486
35
37
  dodal/common/udc_directory_provider.py,sha256=v5OBaCUwjtQZAsRQUw6LlVL58UvwwDO1l2MKlilXjdk,2403
36
- dodal/common/visit.py,sha256=2UbbCmgOjZWSCxFzE9RYiTJhA_IoVOegma-Jv-PJqps,5787
38
+ dodal/common/visit.py,sha256=BLpr3GrP7Ij95V135hRJLgg7gWtBKXVxyOibWtcO8RE,5782
37
39
  dodal/common/beamlines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
40
  dodal/common/beamlines/beamline_parameters.py,sha256=oIPHooqu5vTAwfqZutsKbzwdi9nvFF8568Mz7jrK5rI,3618
39
41
  dodal/common/beamlines/beamline_utils.py,sha256=-FEBuz4fYBclgifAODKaaBB5GIQFhPHPaktGS5c5lWc,5236
@@ -49,9 +51,9 @@ dodal/devices/bimorph_mirror.py,sha256=kG9waIdTkKglUrvY_wD9w533oKPqa7fct1-wa_GCF
49
51
  dodal/devices/cryostream.py,sha256=K-ldpredpeDTzNt4qtQMg99nKJNjBYoXBbK0WJGexzw,656
50
52
  dodal/devices/dcm.py,sha256=JbyxLnrS68nnnv39l9XEWgJgXUBqxX6aFo19MZnL36E,2574
51
53
  dodal/devices/diamond_filter.py,sha256=A--RHd7WuH-IBhvCyENcRCTP4K-mm_Kqpa0pojpHZow,1098
52
- dodal/devices/eiger.py,sha256=n9-rCrIdRnmDNdAz6sCKTYLhiglwlDTmKuMkLUdIWZg,15832
54
+ dodal/devices/eiger.py,sha256=RN3klVASvdTT_jer2HJHUCZWZBKoOUQQdTpsKdgTPfo,15836
53
55
  dodal/devices/eiger_odin.py,sha256=ytUH_18YuM1nJDhplS6OTdtADloYvHpO6ppENjVd4jU,7411
54
- dodal/devices/fast_grid_scan.py,sha256=N5tNSxNpnwLi7NgCHIqgArIUo8qbtVagIW-AIonZiJE,11630
56
+ dodal/devices/fast_grid_scan.py,sha256=SJTolz-LHlkxWA3Fb0lHa90CH8IjyJ1v2vkaaCURGpU,12044
55
57
  dodal/devices/fluorescence_detector_motion.py,sha256=-1qCSvW0PdT0m6BcoLxrtc0OJ5UDIBsEe11EOLr-gFw,501
56
58
  dodal/devices/flux.py,sha256=1CDsq9yU2-ho8MfYBl50Tl9ABZwpUBHnV486PQXKNoQ,462
57
59
  dodal/devices/focusing_mirror.py,sha256=vdUPkwyCAZBSR3LQ-EojDOoxVy1ZmOaD_nevETbj7BA,6592
@@ -60,9 +62,9 @@ dodal/devices/ipin.py,sha256=eq5jlKw7WGQi8VLrAWpaAIsZmfiVf-5Q0td_B22H6A4,473
60
62
  dodal/devices/linkam3.py,sha256=2sf-_heIsDg4qmqae-w9C2Py8pG8bPB3mT0TFPQIzd0,3869
61
63
  dodal/devices/logging_ophyd_device.py,sha256=dUVE-XhWA56WUXez0mrc4sf322CXY3MVLreTycO5j_A,668
62
64
  dodal/devices/motors.py,sha256=K1df9Pn1ThvsW-g7LrfKWOFaiaQXXUAf2BtbRehzUc4,1108
63
- dodal/devices/p45.py,sha256=hNCfWb8xubuHO8uJ5MpHPurp-r1ss7JMgbZQwHVJg-w,1743
65
+ dodal/devices/p45.py,sha256=hoBPpnj3b-njKqmhjAUFb79AyM4qFbWC9tuN6Aa47Rk,1703
64
66
  dodal/devices/pgm.py,sha256=am-AST9iTqma1PkGOKLozqAokZWbJUbM3TNcqXzB-6A,1132
65
- dodal/devices/pressure_jump_cell.py,sha256=LZbHqvClIe4oYX6SU1Rg7WVPjyKZOtGqOFmr3l3mvYg,10251
67
+ dodal/devices/pressure_jump_cell.py,sha256=QYU3BTA6O8lvWdg8UX81Ya0BCbGz4dirjt0xp2ez7O0,10423
66
68
  dodal/devices/qbpm.py,sha256=FfrWWAHHtYv3fGRT1qljyPpAwoHJYfbooT9CfKg-oXI,465
67
69
  dodal/devices/robot.py,sha256=5Y5lNkAbXooIAkSWHwDKyeKKzlqMeH3TuLHzCsw2FPI,5993
68
70
  dodal/devices/s4_slit_gaps.py,sha256=4KdarIQoRqX4ry3LUS1Km7fkjUFahA0VuTd2DvYEqQ8,446
@@ -80,6 +82,7 @@ dodal/devices/undulator_dcm.py,sha256=zulVn1wvu4-WEpf0BgLiDet58IsaKV7KW6qruAdRR_
80
82
  dodal/devices/watsonmarlow323_pump.py,sha256=rwU94YE6esgGLYdh-pe8nBo_3tvgp6brrrbPDrqp5_M,1406
81
83
  dodal/devices/webcam.py,sha256=mef075ynDbzZ4pNAjfxR_9tdTTqF_rM7hAOVEEOV-Do,2408
82
84
  dodal/devices/xbpm_feedback.py,sha256=j8MHhhE0feoe6R54zPKqS5EbQ0bEDR-nOpLHzHhnHHQ,1156
85
+ dodal/devices/aithre_lasershaping/goniometer.py,sha256=YEl0DEXW4Dl9b3nsyfwrM7FDiwEZCXK-evGxlyOJr8k,512
83
86
  dodal/devices/areadetector/plugins/CAM.py,sha256=sZzJm5Ez3eWfXZi_EB67wluhZmMQm1UyOc2bJFfzd1U,964
84
87
  dodal/devices/areadetector/plugins/MJPG.py,sha256=QTsxCoWbofNpLMGPoOR2hWoM33KyntuLepbF0YmX0KE,3031
85
88
  dodal/devices/attenuator/attenuator.py,sha256=eHJpM-E4XQfzy1mxGRk754y3n9q6i3youkCqQg_6SUM,3986
@@ -95,7 +98,7 @@ dodal/devices/detector/__init__.py,sha256=-RdACL3tzc3lLArWOoGNje48UUlv2fElOmGOz9
95
98
  dodal/devices/detector/det_dim_constants.py,sha256=arBWvzMwybatdSiCMAiwB4Bq1dX-wkLi54xPPfTfQhY,2772
96
99
  dodal/devices/detector/det_dist_to_beam_converter.py,sha256=7keoqZYfvgayePVx97lHYpcFRTJnQOfAk_PYP4EZTZQ,1951
97
100
  dodal/devices/detector/det_resolution.py,sha256=aQkKp24LpRGiwzPAQM3wLVa4ANw32HdrKc2kftHfKQA,3253
98
- dodal/devices/detector/detector.py,sha256=syzkl52kGaMINXCXEviFuYPbgNatm5tioVPDmjgro8s,4768
101
+ dodal/devices/detector/detector.py,sha256=sIOGwkixbJTYPdNiwZjDiY7DfYuYzRomKltO2EztDZE,4770
99
102
  dodal/devices/detector/detector_motion.py,sha256=UGDQriDWRluDZOZh1mDX9w_fPjMD-_BGe11kA36Kezs,1616
100
103
  dodal/devices/i03/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
104
  dodal/devices/i03/beamstop.py,sha256=D1-QeGNpNlUE1qtFz-XxgzQGZbvM5bdb09f69yDB7U0,2802
@@ -116,6 +119,7 @@ dodal/devices/i18/diode.py,sha256=q8ddVYT7yDXwURzxw5gfXlGT1tFirNfHBmiKnpvvXHk,40
116
119
  dodal/devices/i18/table.py,sha256=f6OtVSqCFIpXyoHX97CPLpaVDVXUNc2EvgSFP3qVFKo,446
117
120
  dodal/devices/i18/thor_labs_stage.py,sha256=I9JSKY-UqTjN-yBxQWL4CycTNNkUj3vknRrXjA6KZR8,364
118
121
  dodal/devices/i19/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
+ dodal/devices/i19/hutch_access.py,sha256=K8hYi5gYg46XPw03qFgwoInapYzNGjf4Fgf9Ifi0gAI,308
119
123
  dodal/devices/i19/shutter.py,sha256=9KmS4NBwvifgJ4FF_FeXIfSEAV7ZkBAfutiu_0SLrAs,2196
120
124
  dodal/devices/i20_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
125
  dodal/devices/i22/dcm.py,sha256=SQDh-Sj1OvplHZ9yTWblJwv8PJrUqxseDPupZOWmcLo,4701
@@ -144,7 +148,7 @@ dodal/devices/oav/pin_image_recognition/manual_test.py,sha256=h1Rto6ZDCB3jWhjSy9
144
148
  dodal/devices/oav/pin_image_recognition/utils.py,sha256=L9ypluYqeOFoS7gQuws-vTNc8LqaKl2ZIDNeQ2JaNpg,8592
145
149
  dodal/devices/oav/snapshots/grid_overlay.py,sha256=CdvCdTKMCiwMwxm2lV28KpcIUSXlscZmWxb73_KKmiI,3694
146
150
  dodal/devices/oav/snapshots/snapshot_with_beam_centre.py,sha256=J77RfE3AGTLNdWc6hvsRn2DUdupzuk_FTDGvdP0jqbU,1962
147
- dodal/devices/oav/snapshots/snapshot_with_grid.py,sha256=EBoCtr1NmOKye2yQHqbTBxSg-DsEKFeyBtMFmOeGPRs,2269
151
+ dodal/devices/oav/snapshots/snapshot_with_grid.py,sha256=KAM7KjF0BzhGxx-MXd4Zc16IBbi1BF8S_VT8T84_2OY,2309
148
152
  dodal/devices/p99/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
153
  dodal/devices/p99/sample_stage.py,sha256=DvHU556Gp0wFiufZiwY3o2W4xmsCL5uSwNnhd8HPAnc,528
150
154
  dodal/devices/training_rig/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -174,10 +178,13 @@ dodal/plan_stubs/wrapped.py,sha256=nriHKX4BF010CmrhdoUhY3-txClW5W8TPLz64kE_AXU,4
174
178
  dodal/plans/__init__.py,sha256=nH1jNxw3DzDMg9O8Uda0kqKIalRVEWBrq07OLY6Ey38,93
175
179
  dodal/plans/save_panda.py,sha256=1fumH7Ih8uDIv8ahAtgQ_vUuR3dz0sfUs4n9TEtEbSs,3053
176
180
  dodal/plans/scanspec.py,sha256=Q0AcvTKRT401iGMRDSqK-D523UX5_ofiVMZ_rNXKOx8,2074
181
+ dodal/plans/verify_undulator_gap.py,sha256=mq2fHtc5o5rSgdTM2xhULOImfjwa6x29tPpeoLw4GcU,553
177
182
  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,,
183
+ dodal/plans/preprocessors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
+ dodal/plans/preprocessors/verify_undulator_gap.py,sha256=cBZEGq8TW1jrXFXB00iClQVXSEaE_jP_rHMY9WTgYyY,1813
185
+ dls_dodal-1.42.0.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
186
+ dls_dodal-1.42.0.dist-info/METADATA,sha256=z74PYCHBK1Fi9i9jqxo4P2ss7NEXj5rBn2oRmXg4NH0,16791
187
+ dls_dodal-1.42.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
188
+ dls_dodal-1.42.0.dist-info/entry_points.txt,sha256=bycw_EKUzup_rxfCetOwcauXV4kLln_OPpPT8jEnr-I,94
189
+ dls_dodal-1.42.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
190
+ dls_dodal-1.42.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (76.1.0)
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.42.0'
21
+ __version_tuple__ = version_tuple = (1, 42, 0)
@@ -13,6 +13,7 @@ _BEAMLINE_NAME_OVERRIDES = {
13
13
  "i20-1": "i20_1",
14
14
  "i19-1": "i19_1",
15
15
  "i19-2": "i19_2",
16
+ "i19-optics": "i19_optics",
16
17
  "s03": "i03",
17
18
  "p46": "training_rig",
18
19
  "p47": "training_rig",
dodal/beamlines/adsim.py CHANGED
@@ -40,7 +40,7 @@ https://epics-containers.github.io/main/tutorials/launch_example.html
40
40
  And ensure that the signals are visible:
41
41
 
42
42
  ```sh
43
- export EPICS_CA_ADDR_LIST=127.0.0.1
43
+ export EPICS_CA_ADDR_LIST=127.0.0.1:5094
44
44
  ```
45
45
 
46
46
  How to use the devices in a plan:
@@ -0,0 +1,9 @@
1
+ from dodal.common.beamlines.beamline_utils import device_factory
2
+ from dodal.devices.aithre_lasershaping.goniometer import Goniometer
3
+
4
+ PREFIX = "LA18L"
5
+
6
+
7
+ @device_factory()
8
+ def goniometer() -> Goniometer:
9
+ return Goniometer(f"{PREFIX}-MO-LSR-01:", "goniometer")
dodal/beamlines/i04.py CHANGED
@@ -46,7 +46,7 @@ ZOOM_PARAMS_FILE = (
46
46
  DISPLAY_CONFIG = "/dls_sw/i04/software/gda_versions/var/display.configuration"
47
47
  DAQ_CONFIGURATION_PATH = "/dls_sw/i04/software/daq_configuration"
48
48
 
49
- REDIS_HOST = os.environ.get("VALKEY_PROD_SVC_SERVICE_HOST", "test_redis")
49
+ REDIS_HOST = "i04-valkey-murko.diamond.ac.uk"
50
50
  REDIS_PASSWORD = os.environ.get("VALKEY_PASSWORD", "test_redis_password")
51
51
  MURKO_REDIS_DB = 7
52
52
 
@@ -0,0 +1,34 @@
1
+ from dodal.common.beamlines.beamline_utils import (
2
+ device_factory,
3
+ )
4
+ from dodal.common.beamlines.beamline_utils import (
5
+ set_beamline as set_utils_beamline,
6
+ )
7
+ from dodal.devices.hutch_shutter import HutchShutter
8
+ from dodal.devices.i19.hutch_access import HutchAccessControl
9
+ from dodal.log import set_beamline as set_log_beamline
10
+ from dodal.utils import BeamlinePrefix
11
+
12
+ BL = "i19-optics"
13
+ PREFIX = BeamlinePrefix("i19", "I")
14
+ set_log_beamline(BL)
15
+ set_utils_beamline(BL)
16
+
17
+
18
+ @device_factory()
19
+ def shutter() -> HutchShutter:
20
+ """Get the i19 hutch shutter device, instantiate it if it hasn't already been.
21
+ If this is called when already instantiated, it will return the existing object.
22
+ """
23
+ return HutchShutter(
24
+ f"{PREFIX.beamline_prefix}-PS-SHTR-01:",
25
+ "shutter",
26
+ )
27
+
28
+
29
+ @device_factory()
30
+ def access_control() -> HutchAccessControl:
31
+ """Get a device that checks the active hutch for i19, instantiate it if it hasn't already been.
32
+ If this is called when already instantiated, it will return the existing object.
33
+ """
34
+ return HutchAccessControl(f"{PREFIX.beamline_prefix}-OP-STAT-01:", "access_control")
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
  )
dodal/beamlines/p45.py CHANGED
@@ -4,7 +4,7 @@ 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
  )
@@ -13,11 +13,13 @@ from dodal.common.beamlines.device_helpers import DET_SUFFIX, HDF5_SUFFIX
13
13
  from dodal.common.visit import StaticVisitPathProvider
14
14
  from dodal.devices.p45 import Choppers, TomoStageWithStretchAndSkew
15
15
  from dodal.log import set_beamline as set_log_beamline
16
- from dodal.utils import get_beamline_name, skip_device
16
+ from dodal.utils import BeamlinePrefix, get_beamline_name
17
17
 
18
18
  BL = get_beamline_name("p45")
19
+ PREFIX = BeamlinePrefix(BL)
19
20
  set_log_beamline(BL)
20
21
  set_utils_beamline(BL)
22
+
21
23
  set_path_provider(
22
24
  StaticVisitPathProvider(
23
25
  BL,
@@ -26,92 +28,51 @@ set_path_provider(
26
28
  )
27
29
 
28
30
 
29
- def sample(
30
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
31
- ) -> TomoStageWithStretchAndSkew:
32
- return device_instantiation(
33
- TomoStageWithStretchAndSkew,
34
- "sample_stage",
35
- "-MO-STAGE-01:",
36
- wait_for_connection,
37
- fake_with_ophyd_sim,
38
- )
31
+ @device_factory()
32
+ def sample() -> TomoStageWithStretchAndSkew:
33
+ return TomoStageWithStretchAndSkew(f"{PREFIX.beamline_prefix}-MO-STAGE-01:")
39
34
 
40
35
 
41
- def choppers(
42
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
43
- ) -> Choppers:
44
- return device_instantiation(
45
- Choppers,
46
- "chopper",
47
- "-MO-CHOP-01:",
48
- wait_for_connection,
49
- fake_with_ophyd_sim,
50
- )
36
+ @device_factory()
37
+ def choppers() -> Choppers:
38
+ return Choppers(f"{PREFIX.beamline_prefix}-MO-CHOP-01:")
51
39
 
52
40
 
53
41
  # Disconnected
54
- @skip_device()
55
- def det(
56
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
57
- ) -> AravisDetector:
58
- return device_instantiation(
59
- AravisDetector,
60
- "det",
61
- "-EA-MAP-01:",
62
- wait_for_connection,
63
- fake_with_ophyd_sim,
42
+ @device_factory(skip=True)
43
+ def det() -> AravisDetector:
44
+ return AravisDetector(
45
+ f"{PREFIX.beamline_prefix}-EA-MAP-01:",
46
+ path_provider=get_path_provider(),
64
47
  drv_suffix=DET_SUFFIX,
65
48
  fileio_suffix=HDF5_SUFFIX,
66
- path_provider=get_path_provider(),
67
49
  )
68
50
 
69
51
 
70
52
  # Disconnected
71
- @skip_device()
72
- def diff(
73
- wait_for_connection: bool = True, fake_with_ophyd_sim: bool = False
74
- ) -> AravisDetector:
75
- return device_instantiation(
76
- AravisDetector,
77
- "diff",
78
- "-EA-DIFF-01:",
79
- wait_for_connection,
80
- fake_with_ophyd_sim,
53
+ @device_factory(skip=True)
54
+ def diff() -> AravisDetector:
55
+ return AravisDetector(
56
+ f"{PREFIX.beamline_prefix}-EA-DIFF-01:",
57
+ path_provider=get_path_provider(),
81
58
  drv_suffix=DET_SUFFIX,
82
59
  fileio_suffix=HDF5_SUFFIX,
83
- path_provider=get_path_provider(),
84
60
  )
85
61
 
86
62
 
87
- # Must find which PandA IOC(s) are compatible
88
63
  # Must document what PandAs are physically connected to
89
64
  # See: https://github.com/bluesky/ophyd-async/issues/284
90
- @skip_device()
91
- def panda1(
92
- wait_for_connection: bool = True,
93
- fake_with_ophyd_sim: bool = False,
94
- ) -> HDFPanda:
95
- return device_instantiation(
96
- HDFPanda,
97
- "panda1",
98
- "-MO-PANDA-01:",
99
- wait_for_connection,
100
- fake_with_ophyd_sim,
65
+ @device_factory(skip=True)
66
+ def panda1() -> HDFPanda:
67
+ return HDFPanda(
68
+ f"{PREFIX.beamline_prefix}-MO-PANDA-01:",
101
69
  path_provider=get_path_provider(),
102
70
  )
103
71
 
104
72
 
105
- @skip_device()
106
- def panda2(
107
- wait_for_connection: bool = True,
108
- fake_with_ophyd_sim: bool = False,
109
- ) -> HDFPanda:
110
- return device_instantiation(
111
- HDFPanda,
112
- "panda2",
113
- "-MO-PANDA-02:",
114
- wait_for_connection,
115
- fake_with_ophyd_sim,
73
+ @device_factory(skip=True)
74
+ def panda2() -> HDFPanda:
75
+ return HDFPanda(
76
+ f"{PREFIX.beamline_prefix}-MO-PANDA-02:",
116
77
  path_provider=get_path_provider(),
117
78
  )
dodal/common/visit.py CHANGED
@@ -78,7 +78,7 @@ class RemoteDirectoryServiceClient(DirectoryServiceClient):
78
78
  ):
79
79
  response.raise_for_status()
80
80
  json = await response.json()
81
- return DataCollectionIdentifier.model_validate_json(json)
81
+ return DataCollectionIdentifier.model_validate(json)
82
82
 
83
83
 
84
84
  class LocalDirectoryServiceClient(DirectoryServiceClient):
@@ -0,0 +1,15 @@
1
+ from ophyd_async.core import StandardReadable
2
+ from ophyd_async.epics.motor import Motor
3
+
4
+
5
+ class Goniometer(StandardReadable):
6
+ """Goniometer and the stages it sits on"""
7
+
8
+ def __init__(self, prefix: str, name: str = "") -> None:
9
+ self.x = Motor(prefix + "X")
10
+ self.y = Motor(prefix + "Y")
11
+ self.z = Motor(prefix + "Z")
12
+ self.sampy = Motor(prefix + "SAMPY")
13
+ self.sampz = Motor(prefix + "SAMPZ")
14
+ self.omega = Motor(prefix + "OMEGA")
15
+ super().__init__(name)
@@ -32,7 +32,7 @@ class DetectorParams(BaseModel):
32
32
  # Must use model_dump(by_alias=True) if serialising!
33
33
 
34
34
  expected_energy_ev: float | None = None
35
- exposure_time: float
35
+ exposure_time_s: float
36
36
  directory: str # : Path https://github.com/DiamondLightSource/dodal/issues/774
37
37
  prefix: str
38
38
  detector_distance: float
dodal/devices/eiger.py CHANGED
@@ -221,11 +221,11 @@ class EigerDetector(Device, Stageable):
221
221
  def set_cam_pvs(self) -> AndStatus:
222
222
  assert self.detector_params is not None
223
223
  status = self.cam.acquire_time.set(
224
- self.detector_params.exposure_time,
224
+ self.detector_params.exposure_time_s,
225
225
  timeout=self.timeouts.general_status_timeout,
226
226
  )
227
227
  status &= self.cam.acquire_period.set(
228
- self.detector_params.exposure_time,
228
+ self.detector_params.exposure_time_s,
229
229
  timeout=self.timeouts.general_status_timeout,
230
230
  )
231
231
  status &= self.cam.num_exposures.set(
@@ -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]:
@@ -0,0 +1,8 @@
1
+ from ophyd_async.core import StandardReadable
2
+ from ophyd_async.epics.core import epics_signal_r
3
+
4
+
5
+ class HutchAccessControl(StandardReadable):
6
+ def __init__(self, prefix: str, name: str = "") -> None:
7
+ self.active_hutch = epics_signal_r(str, f"{prefix}EHStatus.VALA")
8
+ super().__init__(name)
@@ -34,9 +34,10 @@ class SnapshotWithGrid(MJPG):
34
34
  box_width = await self.box_width.get_value()
35
35
  num_boxes_x = await self.num_boxes_x.get_value()
36
36
  num_boxes_y = await self.num_boxes_y.get_value()
37
-
38
- assert isinstance(filename_str := await self.filename.get_value(), str)
39
- assert isinstance(directory_str := await self.directory.get_value(), str)
37
+ filename_str = await self.filename.get_value()
38
+ assert isinstance(filename_str, str)
39
+ directory_str = await self.directory.get_value()
40
+ assert isinstance(directory_str, str)
40
41
 
41
42
  add_grid_border_overlay_to_image(
42
43
  image, int(top_left_x), int(top_left_y), box_width, num_boxes_x, num_boxes_y
dodal/devices/p45.py CHANGED
@@ -7,13 +7,13 @@ class SampleY(StandardReadable):
7
7
  Motors for controlling the sample's y position and stretch in the y axis.
8
8
  """
9
9
 
10
- def __init__(self, prefix: str, name="") -> None:
10
+ def __init__(self, prefix: str, name: str = ""):
11
11
  with self.add_children_as_readables():
12
12
  self.base = Motor(prefix + "CS:Y")
13
13
  self.stretch = Motor(prefix + "CS:Y:STRETCH")
14
14
  self.top = Motor(prefix + "Y:TOP")
15
15
  self.bottom = Motor(prefix + "Y:BOT")
16
- super().__init__(name=name)
16
+ super().__init__(name)
17
17
 
18
18
 
19
19
  class SampleTheta(StandardReadable):
@@ -21,13 +21,13 @@ class SampleTheta(StandardReadable):
21
21
  Motors for controlling the sample's theta position and skew
22
22
  """
23
23
 
24
- def __init__(self, prefix: str, name="") -> None:
24
+ def __init__(self, prefix: str, name: str = ""):
25
25
  with self.add_children_as_readables():
26
26
  self.base = Motor(prefix + "THETA:POS")
27
27
  self.skew = Motor(prefix + "THETA:SKEW")
28
28
  self.top = Motor(prefix + "THETA:TOP")
29
29
  self.bottom = Motor(prefix + "THETA:BOT")
30
- super().__init__(name=name)
30
+ super().__init__(name)
31
31
 
32
32
 
33
33
  class TomoStageWithStretchAndSkew(StandardReadable):
@@ -35,12 +35,12 @@ class TomoStageWithStretchAndSkew(StandardReadable):
35
35
  Grouping of motors for the P45 tomography stage
36
36
  """
37
37
 
38
- def __init__(self, prefix: str, name="") -> None:
38
+ def __init__(self, prefix: str, name: str = ""):
39
39
  with self.add_children_as_readables():
40
40
  self.x = Motor(prefix + "X")
41
41
  self.y = SampleY(prefix)
42
42
  self.theta = SampleTheta(prefix)
43
- super().__init__(name=name)
43
+ super().__init__(name)
44
44
 
45
45
 
46
46
  class Choppers(StandardReadable):
@@ -48,8 +48,8 @@ class Choppers(StandardReadable):
48
48
  Grouping for the P45 chopper motors
49
49
  """
50
50
 
51
- def __init__(self, prefix: str, name="") -> None:
51
+ def __init__(self, prefix: str, name: str = ""):
52
52
  with self.add_children_as_readables():
53
53
  self.x = Motor(prefix + "ENDAT")
54
54
  self.y = Motor(prefix + "BISS")
55
- super().__init__(name=name)
55
+ super().__init__(name)
@@ -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):
@@ -235,6 +235,9 @@ class PressureTransducer(StandardReadable):
235
235
  self.beckhoff_pressure = epics_signal_r(
236
236
  float, f"{final_prefix}STATP{transducer_number}:MeanValue_RBV"
237
237
  )
238
+ # P1 beckhoff voltage = BL38P-EA-ADC-02:CH1
239
+ # P2 beckhoff voltage = BL38P-EA-ADC-01:CH2
240
+ # P3 beckhoff voltage = BL38P-EA-ADC-01:CH1
238
241
  self.slow_beckhoff_voltage_readout = epics_signal_r(
239
242
  float, f"{full_different_prefix_adc}CH{ethercat_channel_number}"
240
243
  )
File without changes
@@ -0,0 +1,49 @@
1
+ from bluesky.preprocessors import plan_mutator
2
+ from bluesky.utils import Msg, MsgGenerator, make_decorator
3
+
4
+ from dodal.plans.verify_undulator_gap import CheckUndulatorDevices, verify_undulator_gap
5
+
6
+
7
+ def verify_undulator_gap_before_run_wrapper(
8
+ plan: MsgGenerator,
9
+ devices: CheckUndulatorDevices,
10
+ run_key_to_wrap: str | None = None,
11
+ ):
12
+ """
13
+ Modifies the wrapped plan so that it checks the undulator gap before the specified run is opened and sets it to the correct value if needed.
14
+
15
+ After a beam dump, the undulator gap may not return correctly, scientists have often requested that this check is done before collections.
16
+
17
+ Args:
18
+ plan: The plan performing the run.
19
+ devices (CheckUndulatorDevices): Any device composite including the DCM and undulator
20
+ run_key_to_wrap: (str | None): The plan to verify the undulator gap is inserted after the 'open_run' message is seen with
21
+ the matching run key. If not specified, instead wrap the first run encountered.
22
+ """
23
+
24
+ # If no run_key specified, make sure we only do check on first run encountered
25
+ _wrapped_run_name: None | str = None
26
+
27
+ def head(msg: Msg):
28
+ yield from verify_undulator_gap(devices)
29
+ yield msg
30
+
31
+ def insert_plans(msg: Msg):
32
+ nonlocal _wrapped_run_name
33
+
34
+ match msg.command:
35
+ case "open_run":
36
+ if (
37
+ not (run_key_to_wrap or _wrapped_run_name)
38
+ or run_key_to_wrap is msg.run
39
+ ):
40
+ _wrapped_run_name = msg.run if msg.run else "unnamed_run"
41
+ return head(msg), None
42
+ return None, None
43
+
44
+ return plan_mutator(plan, insert_plans)
45
+
46
+
47
+ verify_undulator_gap_before_run_decorator = make_decorator(
48
+ verify_undulator_gap_before_run_wrapper
49
+ )
@@ -0,0 +1,19 @@
1
+ from typing import Protocol, runtime_checkable
2
+
3
+ from bluesky import plan_stubs as bps
4
+
5
+ from dodal.devices.dcm import DCM
6
+ from dodal.devices.undulator import Undulator
7
+
8
+
9
+ @runtime_checkable
10
+ class CheckUndulatorDevices(Protocol):
11
+ undulator: Undulator
12
+ dcm: DCM
13
+
14
+
15
+ def verify_undulator_gap(devices: CheckUndulatorDevices):
16
+ """Verify Undulator gap is correct - it may not be after a beam dump"""
17
+
18
+ energy_in_kev = yield from bps.rd(devices.dcm.energy_in_kev.user_readback)
19
+ yield from bps.abs_set(devices.undulator, energy_in_kev, wait=True)
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,