dls-dodal 1.63.0__py3-none-any.whl → 1.64.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.
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/METADATA +3 -3
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/RECORD +31 -23
- dodal/_version.py +2 -2
- dodal/beamlines/i07.py +21 -0
- dodal/beamlines/i09.py +1 -1
- dodal/beamlines/i09_1.py +1 -1
- dodal/beamlines/i09_2.py +30 -0
- dodal/beamlines/i10_optics.py +50 -24
- dodal/beamlines/i17.py +18 -8
- dodal/beamlines/i21.py +31 -1
- dodal/cli.py +3 -3
- dodal/devices/apple2_undulator.py +19 -17
- dodal/devices/b07_1/ccmc.py +1 -1
- dodal/devices/common_dcm.py +3 -3
- dodal/devices/i03/undulator_dcm.py +1 -1
- dodal/devices/i07/__init__.py +0 -0
- dodal/devices/i07/dcm.py +33 -0
- dodal/devices/i09_1_shared/__init__.py +3 -0
- dodal/devices/i09_1_shared/hard_undulator_functions.py +111 -0
- dodal/devices/i10/i10_apple2.py +4 -4
- dodal/devices/i15/dcm.py +1 -1
- dodal/devices/i22/dcm.py +1 -1
- dodal/devices/util/lookup_tables.py +8 -2
- dodal/plans/verify_undulator_gap.py +2 -2
- dodal/testing/fixtures/__init__.py +0 -0
- dodal/testing/fixtures/run_engine.py +46 -0
- dodal/testing/fixtures/utils.py +57 -0
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/WHEEL +0 -0
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/licenses/LICENSE +0 -0
- {dls_dodal-1.63.0.dist-info → dls_dodal-1.64.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dls-dodal
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.64.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>, Joseph Ware <joseph.ware@diamond.ac.uk>, Oliver Silvester <Oliver.Silvester@diamond.ac.uk>, Noemi Frisina <noemi.frisina@diamond.ac.uk>
|
|
6
6
|
License: Apache License
|
|
@@ -215,7 +215,7 @@ Description-Content-Type: text/markdown
|
|
|
215
215
|
License-File: LICENSE
|
|
216
216
|
Requires-Dist: click
|
|
217
217
|
Requires-Dist: ophyd
|
|
218
|
-
Requires-Dist: ophyd-async[ca,pva]>=0.13.
|
|
218
|
+
Requires-Dist: ophyd-async[ca,pva]>=0.13.5
|
|
219
219
|
Requires-Dist: bluesky>=1.14.5
|
|
220
220
|
Requires-Dist: pyepics
|
|
221
221
|
Requires-Dist: dataclasses-json
|
|
@@ -245,7 +245,7 @@ Requires-Dist: pipdeptree; extra == "dev"
|
|
|
245
245
|
Requires-Dist: pre-commit; extra == "dev"
|
|
246
246
|
Requires-Dist: psutil; extra == "dev"
|
|
247
247
|
Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
|
|
248
|
-
Requires-Dist: pyright; extra == "dev"
|
|
248
|
+
Requires-Dist: pyright==1.1.406; extra == "dev"
|
|
249
249
|
Requires-Dist: pytest; extra == "dev"
|
|
250
250
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
251
251
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
dls_dodal-1.
|
|
1
|
+
dls_dodal-1.64.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
2
2
|
dodal/__init__.py,sha256=Ksms_WJF8LTkbm38gEpm1jBpGqcQ8NGvmb2ZJlOE1j8,198
|
|
3
3
|
dodal/__main__.py,sha256=kP2S2RPitnOWpNGokjZ1Yq-1umOtp5sNOZk2B3tBPLM,111
|
|
4
|
-
dodal/_version.py,sha256=
|
|
5
|
-
dodal/cli.py,sha256=
|
|
4
|
+
dodal/_version.py,sha256=_zrl8M91Rnv6DVBIBxk-gZepOz8nYyzbsC1kzAgyxxY,706
|
|
5
|
+
dodal/cli.py,sha256=NJopu78ebawAL3qNSvOoxMpyzcejVRCh9qw2lRpEJZw,4199
|
|
6
6
|
dodal/log.py,sha256=UckmmyY_SdZePyi5lHnjh-DVw6qvnat3ANa_5-y80Og,9877
|
|
7
7
|
dodal/utils.py,sha256=abGitd4FLpLnmckF7lUqOKYUL88r5Ex_NGSVgO4gOf4,19305
|
|
8
8
|
dodal/beamline_specific_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -24,23 +24,24 @@ dodal/beamlines/i03.py,sha256=-CkU60NXyXVjTjDqwkSWugu6MbG4r8mkwF6ax7WVP-I,16561
|
|
|
24
24
|
dodal/beamlines/i04.py,sha256=QyprATHFxnw_cP2gak1i2_ywj-i26vrGlvOYM6RmyTY,13758
|
|
25
25
|
dodal/beamlines/i05.py,sha256=v4QKd8-neh4Og205oovm6NDRnAU6Oktu1WrxalXsI40,656
|
|
26
26
|
dodal/beamlines/i05_1.py,sha256=R6JFFg8Bj-Izw355mx3mOd4IDvJb5ipB4p7_S0I_4Z0,670
|
|
27
|
-
dodal/beamlines/
|
|
28
|
-
dodal/beamlines/
|
|
29
|
-
dodal/beamlines/
|
|
27
|
+
dodal/beamlines/i07.py,sha256=So3qlieBwLufsy-yei-Fj4zLKPhm6swUN3aHDQQWzpM,634
|
|
28
|
+
dodal/beamlines/i09.py,sha256=OOf7Yf4q3Pu0q_MsczxTCdNkr5A-pqNRsrQb6BxZyA8,1839
|
|
29
|
+
dodal/beamlines/i09_1.py,sha256=0aoUgirXT6qNtc8fN7FzG0fwuQcVmGH8dDtoLWVj_RM,1521
|
|
30
|
+
dodal/beamlines/i09_2.py,sha256=iut2-ADQn7r4rpHo4ycCsE4dczm4VKYxabzwWQNvcwg,1358
|
|
30
31
|
dodal/beamlines/i10.py,sha256=LC0ii13rVyZj1ziatBAyRoyuutdyyTCkpSvICGv4IGY,4059
|
|
31
32
|
dodal/beamlines/i10_1.py,sha256=FxnWjr1u55XgIvnuyTfknnj-xPMNJOAtxObq1y9k518,1062
|
|
32
|
-
dodal/beamlines/i10_optics.py,sha256=
|
|
33
|
+
dodal/beamlines/i10_optics.py,sha256=u0eDHQDGteh1IXGOesDP66WfMsYn2mCXerIbYpB1bE4,5888
|
|
33
34
|
dodal/beamlines/i11.py,sha256=hzW5Lh74zDzUD0vqXQzekoFVWDp8qEIc0OPRm0Qepqs,3643
|
|
34
35
|
dodal/beamlines/i13_1.py,sha256=VYVqMN8-njy7YSI08gskRccT-K2paRC9edAx0ah-Cwo,1602
|
|
35
36
|
dodal/beamlines/i15.py,sha256=lmUhh1jt5CtD4P_BzkwNufu814aT3uaQlLyDMY_B5AE,5725
|
|
36
37
|
dodal/beamlines/i15_1.py,sha256=EKg6BCr3wpHxdmG23kSTZYcNnGQxZbkzzulBLwz_Kew,3903
|
|
37
|
-
dodal/beamlines/i17.py,sha256=
|
|
38
|
+
dodal/beamlines/i17.py,sha256=HwQyD15gztKWbwjszE_Vv8cm44IKc7vwEq_oY3RzpJQ,2487
|
|
38
39
|
dodal/beamlines/i18.py,sha256=JAGk4Z1Q0fFHIClWDGGQSKcIhZZ14oKF6gyCC-Xspe0,3741
|
|
39
40
|
dodal/beamlines/i19_1.py,sha256=4-jU-JiF1J_aunoMW5GsHXE-R2l1xaXxmPH_89_D3IM,3093
|
|
40
41
|
dodal/beamlines/i19_2.py,sha256=8dehUVBjOe_jHBP_il-RZpMc8hZsPWHx9aE_zYCRJ4s,3630
|
|
41
42
|
dodal/beamlines/i19_optics.py,sha256=fNdAFRJYFA045l4giGI3V68qijDFE1C8gdvD6fncAio,1181
|
|
42
43
|
dodal/beamlines/i20_1.py,sha256=Zsr1lsH7ySbOgK7RhMVMWzNWZAV-fuYW0iAjSEJZicY,2625
|
|
43
|
-
dodal/beamlines/i21.py,sha256=
|
|
44
|
+
dodal/beamlines/i21.py,sha256=_XiMajHF739yfLOnme9hPyV_JfmA_iTY0iG2jeirgNI,1345
|
|
44
45
|
dodal/beamlines/i22.py,sha256=3WYXequNzEkGIMEFgnI5axIYTH_kNcENVmoTj1mvyyI,8426
|
|
45
46
|
dodal/beamlines/i23.py,sha256=ZXvPEiMA4mPbRTXOxvL1NcoVWDg4Deyl8k57cveDg90,3060
|
|
46
47
|
dodal/beamlines/i24.py,sha256=0ZjJCUYIUWIQTPrXFqKviiTCZiyuJh4MkmqMYd9JZ9o,7454
|
|
@@ -70,12 +71,12 @@ dodal/common/beamlines/device_helpers.py,sha256=8sasAIFRDwo6ElHqLrXnpj_v7xcEg-29
|
|
|
70
71
|
dodal/devices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
72
|
dodal/devices/aperture.py,sha256=S7AoIoQg_kFxaQk7HUMijbm1kYkOEi2csbdj76kp1ys,427
|
|
72
73
|
dodal/devices/aperturescatterguard.py,sha256=V3RFNq5BFeFPRK9ZEi4w2zEDpopkKvqBsdjY59PrIg0,13988
|
|
73
|
-
dodal/devices/apple2_undulator.py,sha256=
|
|
74
|
+
dodal/devices/apple2_undulator.py,sha256=zwSbioULT7R8D2wfpcq08nkI9ljqVgBG0-0h1sFT2EA,25952
|
|
74
75
|
dodal/devices/backlight.py,sha256=y40kR6N3qSFVLRaGU8CjJJpwv_hq2QALf_85fLQqras,1415
|
|
75
76
|
dodal/devices/baton.py,sha256=315I_0V73_DYYVT0PBs0luVy4CMqdPo0kLvHBi12MIU,606
|
|
76
77
|
dodal/devices/bimorph_mirror.py,sha256=OGe6aCczG0gVco4OvIRLJVxn2kw5F2QG1e06uqhFLTw,4609
|
|
77
78
|
dodal/devices/collimation_table.py,sha256=64HunSPJH-L2gZdfIj_RYdOlOuwRFEfMHfLHzu4BAKI,1681
|
|
78
|
-
dodal/devices/common_dcm.py,sha256=
|
|
79
|
+
dodal/devices/common_dcm.py,sha256=BmvwnT5mbCmSQI8aGl3GKEfpe7N1axUANEyG-NYgC98,5288
|
|
79
80
|
dodal/devices/controllers.py,sha256=W_Ras1c6xLjcOMKPSHN8Z1eCUCH-ktaah2hzQXyuFLk,652
|
|
80
81
|
dodal/devices/cryostream.py,sha256=2FxCGioEZNMHItsGm_rsnkRnHjwMUIwRMAX_x8odKIw,4678
|
|
81
82
|
dodal/devices/diamond_filter.py,sha256=hySd7HnLdplpPNvBrLddLjO_3LqgD8-99Zr__Sy_GbI,689
|
|
@@ -125,7 +126,7 @@ dodal/devices/attenuator/filter_selections.py,sha256=r0TsT3Cylx0wQiBoCsU0Kk8eOup
|
|
|
125
126
|
dodal/devices/b07/__init__.py,sha256=Zw4VkH-68MLoDveswDpR-lTlzK1-IeNz2W4qtkCO3Hs,109
|
|
126
127
|
dodal/devices/b07/enums.py,sha256=GmS6YZEbFH2wEwS1Ni4VNG-2wT98v7NnCzbHqFKo5Pg,1415
|
|
127
128
|
dodal/devices/b07_1/__init__.py,sha256=yInDRarid492g7unaL8zIrWSNpRXhgsj8z7TRTRJfjI,281
|
|
128
|
-
dodal/devices/b07_1/ccmc.py,sha256=
|
|
129
|
+
dodal/devices/b07_1/ccmc.py,sha256=SyxfR8Sd8C7Bx2q0cvItdxP2DOP-ZhbMuAfSvBrbSio,2554
|
|
129
130
|
dodal/devices/b07_1/enums.py,sha256=TREiXDSAGFRXR3iUkKADYfm-CmhLmlpGHKZUOQ2Z1as,723
|
|
130
131
|
dodal/devices/b16/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
131
132
|
dodal/devices/b16/detector.py,sha256=saI2aFBhT0oTisam5b1mlaMJTRwGT7bHbqPGBP7SDnk,840
|
|
@@ -168,20 +169,24 @@ dodal/devices/i02_1/sample_motors.py,sha256=fAHAyeuP4hjOnYsp2x5VQNrTh8Di35ezJV1s
|
|
|
168
169
|
dodal/devices/i02_2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
169
170
|
dodal/devices/i03/__init__.py,sha256=Kvukapy4a5lUQ20qaCqYCJzKNaqJn2DfXP5nKZ_Pec8,118
|
|
170
171
|
dodal/devices/i03/dcm.py,sha256=qK9qcPCedjOVMvKZ0TZaWNeyt7CJRsC-Wpjy44OQf4E,2336
|
|
171
|
-
dodal/devices/i03/undulator_dcm.py,sha256=
|
|
172
|
+
dodal/devices/i03/undulator_dcm.py,sha256=HyeqOdq7qA7bqxw5giY4XvX3SLTOMwzbEKdTc5FQXzQ,2857
|
|
172
173
|
dodal/devices/i04/__init__.py,sha256=Kvukapy4a5lUQ20qaCqYCJzKNaqJn2DfXP5nKZ_Pec8,118
|
|
173
174
|
dodal/devices/i04/constants.py,sha256=_Dw28NeXldwRYH-h6YP6OHnyj7h0z4NQs_-RysNby5Q,281
|
|
174
175
|
dodal/devices/i04/murko_results.py,sha256=6VtYDm0HXIBSyd-_v2O1G_6C1D-5fQ45FKMlNMDW--Y,9682
|
|
175
176
|
dodal/devices/i04/transfocator.py,sha256=sVI4Bgv-2-DH4-F1nIXMp5Aktevrm3agZnCA-WgjmW8,3780
|
|
176
177
|
dodal/devices/i05/__init__.py,sha256=v0Axsf-vMyLyxcbqS8lljJc0BQ5Tw8yVBTWcO3tG_4g,67
|
|
177
178
|
dodal/devices/i05/enums.py,sha256=9FHBIexkSfZSTHxUnGupravfG9sVriHcrB15jemkQOQ,191
|
|
179
|
+
dodal/devices/i07/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
180
|
+
dodal/devices/i07/dcm.py,sha256=AJpBiLX6t_mAjGKw9LmjXIFG5IIe5Ploe5LxS-ZckT8,1250
|
|
178
181
|
dodal/devices/i09/__init__.py,sha256=5AGY_SKtqrU7NeEbzu9ROazPD_C1fEci1LJfdcuz2VY,135
|
|
179
182
|
dodal/devices/i09/enums.py,sha256=Rfs6OgEHSSxcH2UiVmlR_5wLwxDmcHonXds0UDVRfCc,551
|
|
180
183
|
dodal/devices/i09_1/__init__.py,sha256=dTazun87AkMDXh7J8gIZYJxJth0XUs72qahJ-VvhRBI,72
|
|
181
184
|
dodal/devices/i09_1/enums.py,sha256=FwhsvKnEcm9M22U4gcAJi6FE2RaUBZH0jRjNgJUKRqc,1319
|
|
185
|
+
dodal/devices/i09_1_shared/__init__.py,sha256=rHFCmNUYbca82BQ9lbcSvINFkwncUDxZciqa286-6is,137
|
|
186
|
+
dodal/devices/i09_1_shared/hard_undulator_functions.py,sha256=U5-xzejtseZZs9NbT_J-tDOOP_4OR1tWaGvttzmQeZc,4018
|
|
182
187
|
dodal/devices/i10/__init__.py,sha256=Pa7gI_ulcPO3dN2xpw6tBN1E3CpV3Lj82kmGwIVU7TA,575
|
|
183
188
|
dodal/devices/i10/diagnostics.py,sha256=ULSHpaRPVWcP-HgKAJW2rsdPoYZs_MgF6HJoPj39MwU,6339
|
|
184
|
-
dodal/devices/i10/i10_apple2.py,sha256=
|
|
189
|
+
dodal/devices/i10/i10_apple2.py,sha256=K2Xq6t5gxsvhYx85tWv43nDnnSdPBqsadaeXLn6TOA4,15970
|
|
185
190
|
dodal/devices/i10/i10_setting_data.py,sha256=69XWgE-YNTiW7C3t67MNcTL5JDDhOo7h-X7DCTpFE5g,164
|
|
186
191
|
dodal/devices/i10/mirrors.py,sha256=Zofd0g2f3YvFi_KIHQE_w4dFZNglhmh--65tRnWLuyY,504
|
|
187
192
|
dodal/devices/i10/slits.py,sha256=pBstXJnA6j3ftDqei0EZyAPU--M_heqo6hm2DEOqPdc,5040
|
|
@@ -199,7 +204,7 @@ dodal/devices/i13_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
199
204
|
dodal/devices/i13_1/merlin.py,sha256=mgTFSMJftRzLL-HXAUuJkOYxtyA3Rp8YX0L46JCb30Y,1019
|
|
200
205
|
dodal/devices/i13_1/merlin_controller.py,sha256=myfmByOEXyMrlJZfsjOxDHeGQVwZGfsRtzrfSy2001o,1495
|
|
201
206
|
dodal/devices/i15/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
202
|
-
dodal/devices/i15/dcm.py,sha256=
|
|
207
|
+
dodal/devices/i15/dcm.py,sha256=S9kZaImMUUYDDycP_a7qJWE6UzU1JUq2kcbH_-jmuZU,1337
|
|
203
208
|
dodal/devices/i15/focussing_mirror.py,sha256=E6T_c7M2osgHLa7u8eUfQJlXlJbZHtOp95FhP3qZ4gY,1739
|
|
204
209
|
dodal/devices/i15/jack.py,sha256=VafCNx-uqkIy0LxbBAhSm_tuC8_SbGCrnTbvQCExAzA,962
|
|
205
210
|
dodal/devices/i15/laue.py,sha256=H0nLPH8gqJejBZtZeY0lv84EaE2lqdL3CmXvT9iHhpk,496
|
|
@@ -225,7 +230,7 @@ dodal/devices/i20_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
225
230
|
dodal/devices/i21/__init__.py,sha256=1H0Ov9s8K7nu6e20WtQDH39wgSKWz2ChRVAUzytIyzQ,67
|
|
226
231
|
dodal/devices/i21/enums.py,sha256=asy90S84fBBydYwz89jNeocz04JXpbHn8ynaPzW353c,141
|
|
227
232
|
dodal/devices/i22/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
228
|
-
dodal/devices/i22/dcm.py,sha256=
|
|
233
|
+
dodal/devices/i22/dcm.py,sha256=abs6U6DOUO8_g2adpynfoc9lQYbLC3tgObSwI9AhKZg,4551
|
|
229
234
|
dodal/devices/i22/fswitch.py,sha256=kpgegs4Wv_weBSzbrlXLXqXOOZdzTn3X9k5PlEN5F6c,2881
|
|
230
235
|
dodal/devices/i22/nxsas.py,sha256=M6hhiPmHO4WDBsFoSOhKAG_yPF6vTpLRPbB2UW3-aMs,6122
|
|
231
236
|
dodal/devices/i24/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -267,7 +272,7 @@ dodal/devices/temperture_controller/lakeshore/lakeshore_io.py,sha256=OSvJv-vtWIo
|
|
|
267
272
|
dodal/devices/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
268
273
|
dodal/devices/util/adjuster_plans.py,sha256=c40PFZpXFw0YmJLh9jU4VIb8vRxHyafZlmvprTKAOhM,824
|
|
269
274
|
dodal/devices/util/epics_util.py,sha256=4useFL8ngsVF08fhOn48BlnO4oh0T4sEKqjdS6mjvG0,4687
|
|
270
|
-
dodal/devices/util/lookup_tables.py,sha256=
|
|
275
|
+
dodal/devices/util/lookup_tables.py,sha256=8rip4fQI3YaYNcnUPiWF5Bhq9UXJSxFFfqJaFU4a_LU,3706
|
|
271
276
|
dodal/devices/xspress3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
272
277
|
dodal/devices/xspress3/xspress3.py,sha256=OerapEy-IuK7EFz13B5z0BzBmESVl6pYUlqAWHIwJck,4555
|
|
273
278
|
dodal/devices/xspress3/xspress3_channel.py,sha256=w8tAx2lz5kJ_LeJ_eb_4o--Dtt8MRijsYNgDG6oEIVg,1626
|
|
@@ -291,7 +296,7 @@ dodal/plans/bimorph.py,sha256=JxDmZDiEvZnz5f22tlaoyivpnaNGiX8kSL82qz5uvMM,11738
|
|
|
291
296
|
dodal/plans/configure_arm_trigger_and_disarm_detector.py,sha256=mzvno7ikEQkVfY1-vlrINxga2sOYAprRaf1LtySCfCk,6186
|
|
292
297
|
dodal/plans/save_panda.py,sha256=X-zR5GysBPp3M7ZpEYEqCUSc4nJYzHJBA44e52uQ6F4,3099
|
|
293
298
|
dodal/plans/scanspec.py,sha256=Q0AcvTKRT401iGMRDSqK-D523UX5_ofiVMZ_rNXKOx8,2074
|
|
294
|
-
dodal/plans/verify_undulator_gap.py,sha256=
|
|
299
|
+
dodal/plans/verify_undulator_gap.py,sha256=0YlkAPKH7A2auHbdhoxA9Bo50nGQ2xbNumDrAa6gjtg,628
|
|
295
300
|
dodal/plans/wrapped.py,sha256=BPMw__RcWvk9v5XnhMsi9_k4KsDEbmXogzD2n1ecbUg,2098
|
|
296
301
|
dodal/plans/preprocessors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
297
302
|
dodal/plans/preprocessors/verify_undulator_gap.py,sha256=cBZEGq8TW1jrXFXB00iClQVXSEaE_jP_rHMY9WTgYyY,1813
|
|
@@ -299,8 +304,11 @@ dodal/testing/__init__.py,sha256=AUYZKAvVOs7ZvxO1dVhL0pDTleRO34FQlO5MNe_cwgU,96
|
|
|
299
304
|
dodal/testing/setup.py,sha256=8cQnrzE5MQD4Etf0eqMarmtr-opsUOMQww-k1V7DzIQ,2442
|
|
300
305
|
dodal/testing/electron_analyser/__init__.py,sha256=-lc1opD2dCv0x678-J-ApOhHtvEvcslfOQ7E613U8-Y,118
|
|
301
306
|
dodal/testing/electron_analyser/device_factory.py,sha256=tkMY6fW3iI02DTD1XXHi4lH6sjo8RHHZBGDHSuTdmNU,2243
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
dls_dodal-1.
|
|
306
|
-
dls_dodal-1.
|
|
307
|
+
dodal/testing/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
308
|
+
dodal/testing/fixtures/run_engine.py,sha256=X_yrNQAGAZwclLds9lBTIyoI_DljNzFk-sYhWF1vYrI,1218
|
|
309
|
+
dodal/testing/fixtures/utils.py,sha256=jy3mfAAn_TFQ7gqCec-OiOlZkaNLUH3TESW2oohvNgo,1861
|
|
310
|
+
dls_dodal-1.64.0.dist-info/METADATA,sha256=Y0fRfaZjeMen-3IPUFnOBPKKrUbHu0zshyMlyrDrGFc,16950
|
|
311
|
+
dls_dodal-1.64.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
312
|
+
dls_dodal-1.64.0.dist-info/entry_points.txt,sha256=0IO1Bjlnv0vJSSFdGEZ-S_pqQNkE2FnPTA6f0-aTBs8,87
|
|
313
|
+
dls_dodal-1.64.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
|
|
314
|
+
dls_dodal-1.64.0.dist-info/RECORD,,
|
dodal/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.64.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 64, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
dodal/beamlines/i07.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from dodal.common.beamlines.beamline_utils import device_factory
|
|
2
|
+
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
|
|
3
|
+
from dodal.devices.i07.dcm import DCM
|
|
4
|
+
from dodal.log import set_beamline as set_log_beamline
|
|
5
|
+
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
6
|
+
|
|
7
|
+
BL = get_beamline_name("i07")
|
|
8
|
+
set_log_beamline(BL)
|
|
9
|
+
set_utils_beamline(BL)
|
|
10
|
+
PREFIX = BeamlinePrefix(BL)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@device_factory()
|
|
14
|
+
def dcm() -> DCM:
|
|
15
|
+
"""Instantiate DCM using two PV bases"""
|
|
16
|
+
dcm = DCM(
|
|
17
|
+
f"{PREFIX.beamline_prefix}-MO-DCM-01:",
|
|
18
|
+
f"{PREFIX.beamline_prefix}-DI-DCM-01:",
|
|
19
|
+
"dcm",
|
|
20
|
+
)
|
|
21
|
+
return dcm
|
dodal/beamlines/i09.py
CHANGED
|
@@ -43,7 +43,7 @@ def dcm() -> DoubleCrystalMonochromatorWithDSpacing:
|
|
|
43
43
|
|
|
44
44
|
@device_factory()
|
|
45
45
|
def energy_source() -> DualEnergySource:
|
|
46
|
-
return DualEnergySource(dcm().
|
|
46
|
+
return DualEnergySource(dcm().energy_in_eV, pgm().energy.user_readback)
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
# Connect will work again after this work completed
|
dodal/beamlines/i09_1.py
CHANGED
|
@@ -34,7 +34,7 @@ def dcm() -> DoubleCrystalMonochromatorWithDSpacing:
|
|
|
34
34
|
|
|
35
35
|
@device_factory()
|
|
36
36
|
def energy_source() -> EnergySource:
|
|
37
|
-
return EnergySource(dcm().
|
|
37
|
+
return EnergySource(dcm().energy_in_eV)
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
# Connect will work again after this work completed
|
dodal/beamlines/i09_2.py
CHANGED
|
@@ -2,6 +2,11 @@ from dodal.common.beamlines.beamline_utils import (
|
|
|
2
2
|
device_factory,
|
|
3
3
|
)
|
|
4
4
|
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
|
|
5
|
+
from dodal.devices.apple2_undulator import (
|
|
6
|
+
Apple2,
|
|
7
|
+
UndulatorGap,
|
|
8
|
+
UndulatorPhaseAxes,
|
|
9
|
+
)
|
|
5
10
|
from dodal.devices.i09.enums import Grating
|
|
6
11
|
from dodal.devices.pgm import PGM
|
|
7
12
|
from dodal.devices.synchrotron import Synchrotron
|
|
@@ -22,3 +27,28 @@ def synchrotron() -> Synchrotron:
|
|
|
22
27
|
@device_factory()
|
|
23
28
|
def pgm() -> PGM:
|
|
24
29
|
return PGM(prefix=f"{PREFIX.beamline_prefix}-MO-PGM-01:", grating=Grating)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@device_factory()
|
|
33
|
+
def jid_gap() -> UndulatorGap:
|
|
34
|
+
return UndulatorGap(prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@device_factory()
|
|
38
|
+
def jid_phase() -> UndulatorPhaseAxes:
|
|
39
|
+
return UndulatorPhaseAxes(
|
|
40
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
41
|
+
top_outer="PUO",
|
|
42
|
+
top_inner="PUI",
|
|
43
|
+
btm_inner="PLI",
|
|
44
|
+
btm_outer="PLO",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@device_factory()
|
|
49
|
+
def jid() -> Apple2:
|
|
50
|
+
"""I09 soft x-ray insertion device."""
|
|
51
|
+
return Apple2(
|
|
52
|
+
id_gap=jid_gap(),
|
|
53
|
+
id_phase=jid_phase(),
|
|
54
|
+
)
|
dodal/beamlines/i10_optics.py
CHANGED
|
@@ -80,22 +80,35 @@ I10_CONF_CLIENT = ConfigServer(url="https://daq-config.diamond.ac.uk")
|
|
|
80
80
|
LOOK_UPTABLE_DIR = "/dls_sw/i10/software/gda/workspace_git/gda-diamond.git/configurations/i10-shared/lookupTables/"
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
@device_factory()
|
|
84
|
+
def idd_gap() -> UndulatorGap:
|
|
85
|
+
return UndulatorGap(prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@device_factory()
|
|
89
|
+
def idd_phase() -> UndulatorPhaseAxes:
|
|
90
|
+
return UndulatorPhaseAxes(
|
|
91
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
92
|
+
top_outer="RPQ1",
|
|
93
|
+
top_inner="RPQ2",
|
|
94
|
+
btm_inner="RPQ3",
|
|
95
|
+
btm_outer="RPQ4",
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@device_factory()
|
|
100
|
+
def idd_jaw_phase() -> UndulatorJawPhase:
|
|
101
|
+
return UndulatorJawPhase(
|
|
102
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
103
|
+
move_pv="RPQ1",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
83
107
|
@device_factory()
|
|
84
108
|
def idd() -> I10Apple2:
|
|
85
109
|
"""i10 downstream insertion device:"""
|
|
86
110
|
return I10Apple2(
|
|
87
|
-
id_gap=
|
|
88
|
-
id_phase=UndulatorPhaseAxes(
|
|
89
|
-
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
90
|
-
top_outer="RPQ1",
|
|
91
|
-
top_inner="RPQ2",
|
|
92
|
-
btm_inner="RPQ3",
|
|
93
|
-
btm_outer="RPQ4",
|
|
94
|
-
),
|
|
95
|
-
id_jaw_phase=UndulatorJawPhase(
|
|
96
|
-
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
97
|
-
move_pv="RPQ1",
|
|
98
|
-
),
|
|
111
|
+
id_gap=idd_gap(), id_phase=idd_phase(), id_jaw_phase=idd_jaw_phase()
|
|
99
112
|
)
|
|
100
113
|
|
|
101
114
|
|
|
@@ -131,22 +144,35 @@ def energy_dd() -> BeamEnergy:
|
|
|
131
144
|
return BeamEnergy(id_energy=idd_energy(), mono=pgm().energy)
|
|
132
145
|
|
|
133
146
|
|
|
147
|
+
@device_factory()
|
|
148
|
+
def idu_gap() -> UndulatorGap:
|
|
149
|
+
return UndulatorGap(prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-21:")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@device_factory()
|
|
153
|
+
def idu_phase() -> UndulatorPhaseAxes:
|
|
154
|
+
return UndulatorPhaseAxes(
|
|
155
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-21:",
|
|
156
|
+
top_outer="RPQ1",
|
|
157
|
+
top_inner="RPQ2",
|
|
158
|
+
btm_inner="RPQ3",
|
|
159
|
+
btm_outer="RPQ4",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@device_factory()
|
|
164
|
+
def idu_jaw_phase() -> UndulatorJawPhase:
|
|
165
|
+
return UndulatorJawPhase(
|
|
166
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-21:",
|
|
167
|
+
move_pv="RPQ1",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
134
171
|
@device_factory()
|
|
135
172
|
def idu() -> I10Apple2:
|
|
136
173
|
"""i10 upstream insertion device"""
|
|
137
174
|
return I10Apple2(
|
|
138
|
-
id_gap=
|
|
139
|
-
id_phase=UndulatorPhaseAxes(
|
|
140
|
-
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-21:",
|
|
141
|
-
top_outer="RPQ1",
|
|
142
|
-
top_inner="RPQ2",
|
|
143
|
-
btm_inner="RPQ3",
|
|
144
|
-
btm_outer="RPQ4",
|
|
145
|
-
),
|
|
146
|
-
id_jaw_phase=UndulatorJawPhase(
|
|
147
|
-
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-21:",
|
|
148
|
-
move_pv="RPQ1",
|
|
149
|
-
),
|
|
175
|
+
id_gap=idu_gap(), id_phase=idu_phase(), id_jaw_phase=idu_jaw_phase()
|
|
150
176
|
)
|
|
151
177
|
|
|
152
178
|
|
dodal/beamlines/i17.py
CHANGED
|
@@ -47,18 +47,28 @@ def pgm() -> PGM:
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
@device_factory()
|
|
51
|
+
def id_gap() -> UndulatorGap:
|
|
52
|
+
return UndulatorGap(prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@device_factory()
|
|
56
|
+
def id_phase() -> UndulatorPhaseAxes:
|
|
57
|
+
return UndulatorPhaseAxes(
|
|
58
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
59
|
+
top_outer="RPQ1",
|
|
60
|
+
top_inner="RPQ2",
|
|
61
|
+
btm_inner="RPQ3",
|
|
62
|
+
btm_outer="RPQ4",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
50
66
|
@device_factory(skip=True)
|
|
51
67
|
def id() -> Apple2:
|
|
52
68
|
"""I17 insertion device:"""
|
|
53
69
|
return Apple2(
|
|
54
|
-
id_gap=
|
|
55
|
-
id_phase=
|
|
56
|
-
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
57
|
-
top_outer="RPQ1",
|
|
58
|
-
top_inner="RPQ2",
|
|
59
|
-
btm_inner="RPQ3",
|
|
60
|
-
btm_outer="RPQ4",
|
|
61
|
-
),
|
|
70
|
+
id_gap=id_gap(),
|
|
71
|
+
id_phase=id_phase(),
|
|
62
72
|
)
|
|
63
73
|
|
|
64
74
|
|
dodal/beamlines/i21.py
CHANGED
|
@@ -2,6 +2,11 @@ from dodal.common.beamlines.beamline_utils import (
|
|
|
2
2
|
device_factory,
|
|
3
3
|
)
|
|
4
4
|
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
|
|
5
|
+
from dodal.devices.apple2_undulator import (
|
|
6
|
+
Apple2,
|
|
7
|
+
UndulatorGap,
|
|
8
|
+
UndulatorPhaseAxes,
|
|
9
|
+
)
|
|
5
10
|
from dodal.devices.i21 import Grating
|
|
6
11
|
from dodal.devices.pgm import PGM
|
|
7
12
|
from dodal.devices.synchrotron import Synchrotron
|
|
@@ -9,7 +14,7 @@ from dodal.log import set_beamline as set_log_beamline
|
|
|
9
14
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
10
15
|
|
|
11
16
|
BL = get_beamline_name("i21")
|
|
12
|
-
PREFIX = BeamlinePrefix(BL
|
|
17
|
+
PREFIX = BeamlinePrefix(BL)
|
|
13
18
|
set_log_beamline(BL)
|
|
14
19
|
set_utils_beamline(BL)
|
|
15
20
|
|
|
@@ -25,3 +30,28 @@ def pgm() -> PGM:
|
|
|
25
30
|
prefix=f"{PREFIX.beamline_prefix}-OP-PGM-01:",
|
|
26
31
|
grating=Grating,
|
|
27
32
|
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@device_factory()
|
|
36
|
+
def id_gap() -> UndulatorGap:
|
|
37
|
+
return UndulatorGap(prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@device_factory()
|
|
41
|
+
def id_phase() -> UndulatorPhaseAxes:
|
|
42
|
+
return UndulatorPhaseAxes(
|
|
43
|
+
prefix=f"{PREFIX.insertion_prefix}-MO-SERVC-01:",
|
|
44
|
+
top_outer="PUO",
|
|
45
|
+
top_inner="PUI",
|
|
46
|
+
btm_inner="PLI",
|
|
47
|
+
btm_outer="PLO",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@device_factory()
|
|
52
|
+
def id() -> Apple2:
|
|
53
|
+
"""I21 insertion device."""
|
|
54
|
+
return Apple2(
|
|
55
|
+
id_gap=id_gap(),
|
|
56
|
+
id_phase=id_phase(),
|
|
57
|
+
)
|
dodal/cli.py
CHANGED
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
from bluesky.run_engine import RunEngine
|
|
7
|
-
from ophyd_async.core import
|
|
7
|
+
from ophyd_async.core import NotConnectedError, StaticPathProvider, UUIDFilenameProvider
|
|
8
8
|
from ophyd_async.plan_stubs import ensure_connected
|
|
9
9
|
|
|
10
10
|
from dodal.beamlines import all_beamline_names, module_name_for_beamline
|
|
@@ -79,7 +79,7 @@ def connect(beamline: str, all: bool, sim_backend: bool) -> None:
|
|
|
79
79
|
# If exceptions have occurred, this will print details of the relevant PVs
|
|
80
80
|
exceptions = {**instance_exceptions, **connect_exceptions}
|
|
81
81
|
if len(exceptions) > 0:
|
|
82
|
-
raise
|
|
82
|
+
raise NotConnectedError(exceptions)
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def _report_successful_devices(
|
|
@@ -113,7 +113,7 @@ def _connect_devices(
|
|
|
113
113
|
# Connect ophyd-async devices
|
|
114
114
|
try:
|
|
115
115
|
run_engine(ensure_connected(*ophyd_async_devices.values(), mock=sim_backend))
|
|
116
|
-
except
|
|
116
|
+
except NotConnectedError as ex:
|
|
117
117
|
exceptions = {**exceptions, **ex.sub_errors}
|
|
118
118
|
|
|
119
119
|
# Only return the subset of devices that haven't raised an exception
|
|
@@ -326,8 +326,8 @@ class Apple2(StandardReadable, Movable):
|
|
|
326
326
|
Name of the device.
|
|
327
327
|
"""
|
|
328
328
|
with self.add_children_as_readables():
|
|
329
|
-
self.gap = id_gap
|
|
330
|
-
self.phase = id_phase
|
|
329
|
+
self.gap = Reference(id_gap)
|
|
330
|
+
self.phase = Reference(id_phase)
|
|
331
331
|
super().__init__(name=name)
|
|
332
332
|
|
|
333
333
|
@AsyncStatus.wrap
|
|
@@ -338,25 +338,27 @@ class Apple2(StandardReadable, Movable):
|
|
|
338
338
|
"""
|
|
339
339
|
|
|
340
340
|
# Only need to check gap as the phase motors share both fault and gate with gap.
|
|
341
|
-
await self.gap.raise_if_cannot_move()
|
|
341
|
+
await self.gap().raise_if_cannot_move()
|
|
342
342
|
await asyncio.gather(
|
|
343
|
-
self.phase.top_outer.user_setpoint.set(value=id_motor_values.top_outer),
|
|
344
|
-
self.phase.top_inner.user_setpoint.set(value=id_motor_values.top_inner),
|
|
345
|
-
self.phase.btm_inner.user_setpoint.set(value=id_motor_values.btm_inner),
|
|
346
|
-
self.phase.btm_outer.user_setpoint.set(value=id_motor_values.btm_outer),
|
|
347
|
-
self.gap.user_setpoint.set(value=id_motor_values.gap),
|
|
343
|
+
self.phase().top_outer.user_setpoint.set(value=id_motor_values.top_outer),
|
|
344
|
+
self.phase().top_inner.user_setpoint.set(value=id_motor_values.top_inner),
|
|
345
|
+
self.phase().btm_inner.user_setpoint.set(value=id_motor_values.btm_inner),
|
|
346
|
+
self.phase().btm_outer.user_setpoint.set(value=id_motor_values.btm_outer),
|
|
347
|
+
self.gap().user_setpoint.set(value=id_motor_values.gap),
|
|
348
348
|
)
|
|
349
349
|
timeout = np.max(
|
|
350
|
-
await asyncio.gather(self.gap.get_timeout(), self.phase.get_timeout())
|
|
350
|
+
await asyncio.gather(self.gap().get_timeout(), self.phase().get_timeout())
|
|
351
351
|
)
|
|
352
352
|
LOGGER.info(
|
|
353
353
|
f"Moving f{self.name} apple2 motors to {id_motor_values}, timeout = {timeout}"
|
|
354
354
|
)
|
|
355
355
|
await asyncio.gather(
|
|
356
|
-
self.gap.set_move.set(value=1, wait=False, timeout=timeout),
|
|
357
|
-
self.phase.set_move.set(value=1, wait=False, timeout=timeout),
|
|
356
|
+
self.gap().set_move.set(value=1, wait=False, timeout=timeout),
|
|
357
|
+
self.phase().set_move.set(value=1, wait=False, timeout=timeout),
|
|
358
|
+
)
|
|
359
|
+
await wait_for_value(
|
|
360
|
+
self.gap().gate, UndulatorGateStatus.CLOSE, timeout=timeout
|
|
358
361
|
)
|
|
359
|
-
await wait_for_value(self.gap.gate, UndulatorGateStatus.CLOSE, timeout=timeout)
|
|
360
362
|
|
|
361
363
|
|
|
362
364
|
class EnergyMotorConvertor(Protocol):
|
|
@@ -448,11 +450,11 @@ class Apple2Controller(abc.ABC, StandardReadable, Generic[Apple2Type]):
|
|
|
448
450
|
raw_to_derived=self._read_pol,
|
|
449
451
|
set_derived=self._set_pol,
|
|
450
452
|
pol=self.polarisation_setpoint,
|
|
451
|
-
top_outer=self.apple2().phase.top_outer.user_readback,
|
|
452
|
-
top_inner=self.apple2().phase.top_inner.user_readback,
|
|
453
|
-
btm_inner=self.apple2().phase.btm_inner.user_readback,
|
|
454
|
-
btm_outer=self.apple2().phase.btm_outer.user_readback,
|
|
455
|
-
gap=self.apple2().gap.user_readback,
|
|
453
|
+
top_outer=self.apple2().phase().top_outer.user_readback,
|
|
454
|
+
top_inner=self.apple2().phase().top_inner.user_readback,
|
|
455
|
+
btm_inner=self.apple2().phase().btm_inner.user_readback,
|
|
456
|
+
btm_outer=self.apple2().phase().btm_outer.user_readback,
|
|
457
|
+
gap=self.apple2().gap().user_readback,
|
|
456
458
|
)
|
|
457
459
|
super().__init__(name)
|
|
458
460
|
|
dodal/devices/b07_1/ccmc.py
CHANGED
dodal/devices/common_dcm.py
CHANGED
|
@@ -53,9 +53,9 @@ class DoubleCrystalMonochromatorBase(StandardReadable, Generic[Xtal_1, Xtal_2]):
|
|
|
53
53
|
) -> None:
|
|
54
54
|
with self.add_children_as_readables():
|
|
55
55
|
# Virtual motor PV's which set the physical motors so that the DCM produces requested energy
|
|
56
|
-
self.
|
|
57
|
-
self.
|
|
58
|
-
self._convert_keV_to_eV, energy_signal=self.
|
|
56
|
+
self.energy_in_keV = Motor(prefix + "ENERGY")
|
|
57
|
+
self.energy_in_eV = derived_signal_r(
|
|
58
|
+
self._convert_keV_to_eV, energy_signal=self.energy_in_keV.user_readback
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
self._make_crystals(prefix, xtal_1, xtal_2)
|
|
@@ -58,7 +58,7 @@ class UndulatorDCM(StandardReadable, Movable[float]):
|
|
|
58
58
|
async def set(self, value: float):
|
|
59
59
|
await self.undulator_ref().raise_if_not_enabled()
|
|
60
60
|
await asyncio.gather(
|
|
61
|
-
self.dcm_ref().
|
|
61
|
+
self.dcm_ref().energy_in_keV.set(value, timeout=ENERGY_TIMEOUT_S),
|
|
62
62
|
self.undulator_ref().set(value),
|
|
63
63
|
)
|
|
64
64
|
|
|
File without changes
|
dodal/devices/i07/dcm.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from ophyd_async.epics.core import epics_signal_r
|
|
2
|
+
from ophyd_async.epics.motor import Motor
|
|
3
|
+
|
|
4
|
+
from dodal.devices.common_dcm import (
|
|
5
|
+
DoubleCrystalMonochromator,
|
|
6
|
+
PitchAndRollCrystal,
|
|
7
|
+
StationaryCrystal,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DCM(DoubleCrystalMonochromator[PitchAndRollCrystal, StationaryCrystal]):
|
|
12
|
+
"""
|
|
13
|
+
Device for i07's DCM, including temperature monitors and vertical motor which were
|
|
14
|
+
included in GDA.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
motor_prefix: str,
|
|
20
|
+
xtal_prefix: str,
|
|
21
|
+
name: str = "",
|
|
22
|
+
) -> None:
|
|
23
|
+
super().__init__(motor_prefix, PitchAndRollCrystal, StationaryCrystal, name)
|
|
24
|
+
with self.add_children_as_readables():
|
|
25
|
+
self.vertical_in_mm = Motor(motor_prefix + "PERP")
|
|
26
|
+
|
|
27
|
+
# temperatures
|
|
28
|
+
self.xtal1_temp = epics_signal_r(float, xtal_prefix + "PT100-2")
|
|
29
|
+
self.xtal2_temp = epics_signal_r(float, xtal_prefix + "PT100-3")
|
|
30
|
+
self.xtal1_holder_temp = epics_signal_r(float, xtal_prefix + "PT100-1")
|
|
31
|
+
self.xtal2_holder_temp = epics_signal_r(float, xtal_prefix + "PT100-4")
|
|
32
|
+
self.gap_motor = epics_signal_r(float, xtal_prefix + "TC-1")
|
|
33
|
+
self.white_beam_stop_temp = epics_signal_r(float, xtal_prefix + "WBS:TEMP")
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from dodal.devices.util.lookup_tables import energy_distance_table
|
|
4
|
+
from dodal.log import LOGGER
|
|
5
|
+
|
|
6
|
+
LUT_COMMENTS = ["#"]
|
|
7
|
+
HU_SKIP_ROWS = 3
|
|
8
|
+
|
|
9
|
+
# Physics constants
|
|
10
|
+
ELECTRON_REST_ENERGY_MEV = 0.510999
|
|
11
|
+
|
|
12
|
+
# Columns in the lookup table
|
|
13
|
+
RING_ENERGY_COLUMN = 1
|
|
14
|
+
MAGNET_FIELD_COLUMN = 2
|
|
15
|
+
MIN_ENERGY_COLUMN = 3
|
|
16
|
+
MAX_ENERGY_COLUMN = 4
|
|
17
|
+
GAP_OFFSET_COLUMN = 7
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def get_hu_lut_as_dict(lut_path: str) -> dict:
|
|
21
|
+
lut_dict: dict = {}
|
|
22
|
+
_lookup_table: np.ndarray = await energy_distance_table(
|
|
23
|
+
lut_path,
|
|
24
|
+
comments=LUT_COMMENTS,
|
|
25
|
+
skiprows=HU_SKIP_ROWS,
|
|
26
|
+
)
|
|
27
|
+
for i in range(_lookup_table.shape[0]):
|
|
28
|
+
lut_dict[_lookup_table[i][0]] = _lookup_table[i]
|
|
29
|
+
LOGGER.debug(f"Loaded lookup table:\n {lut_dict}")
|
|
30
|
+
return lut_dict
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def calculate_gap_i09_hu(
|
|
34
|
+
photon_energy_kev: float,
|
|
35
|
+
look_up_table: dict[int, "np.ndarray"],
|
|
36
|
+
order: int = 1,
|
|
37
|
+
gap_offset: float = 0.0,
|
|
38
|
+
undulator_period_mm: int = 27,
|
|
39
|
+
) -> float:
|
|
40
|
+
"""
|
|
41
|
+
Calculate the undulator gap required to produce a given energy at a given harmonic order.
|
|
42
|
+
This algorithm was provided by the I09 beamline scientists, and is based on the physics of undulator radiation.
|
|
43
|
+
https://cxro.lbl.gov//PDF/X-Ray-Data-Booklet.pdf
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
photon_energy_kev (float): Requested photon energy in keV.
|
|
47
|
+
look_up_table (dict[int, np.ndarray]): Lookup table containing undulator and beamline parameters for each harmonic order.
|
|
48
|
+
order (int, optional): Harmonic order for which to calculate the gap. Defaults to 1.
|
|
49
|
+
gap_offset (float, optional): Additional gap offset to apply (in mm). Defaults to 0.0.
|
|
50
|
+
undulator_period_mm (int, optional): Undulator period in mm. Defaults to 27.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
float: Calculated undulator gap in millimeters.
|
|
54
|
+
"""
|
|
55
|
+
magnet_blocks_per_period = 4
|
|
56
|
+
magnet_block_height_mm = 16
|
|
57
|
+
|
|
58
|
+
if order not in look_up_table.keys():
|
|
59
|
+
raise ValueError(f"Order parameter {order} not found in lookup table")
|
|
60
|
+
|
|
61
|
+
gamma = 1000 * look_up_table[order][RING_ENERGY_COLUMN] / ELECTRON_REST_ENERGY_MEV
|
|
62
|
+
|
|
63
|
+
# Constructive interference of radiation emitted at different poles
|
|
64
|
+
# lamda = (lambda_u/2*gamma^2)*(1+K^2/2 + gamma^2*theta^2)/n for n=1,2,3...
|
|
65
|
+
# theta is the observation angle, assumed to be 0 here.
|
|
66
|
+
# Rearranging for K (the undulator parameter, related to magnetic field and gap)
|
|
67
|
+
# gives K^2 = 2*((2*n*gamma^2*lamda/lambda_u)-1)
|
|
68
|
+
|
|
69
|
+
undulator_parameter_sqr = (
|
|
70
|
+
4.959368e-6
|
|
71
|
+
* (order * gamma * gamma / (undulator_period_mm * photon_energy_kev))
|
|
72
|
+
- 2
|
|
73
|
+
)
|
|
74
|
+
if undulator_parameter_sqr < 0:
|
|
75
|
+
raise ValueError(
|
|
76
|
+
f"Diffraction parameter squared must be positive! Calculated value {undulator_parameter_sqr}."
|
|
77
|
+
)
|
|
78
|
+
undulator_parameter = np.sqrt(undulator_parameter_sqr)
|
|
79
|
+
|
|
80
|
+
# Undulator_parameter K is also defined as K = 0.934*B0[T]*lambda_u[cm],
|
|
81
|
+
# where B0[T] is a peak magnetic field that must depend on gap,
|
|
82
|
+
# but in our LUT it is does not depend on gap, so it's a factor,
|
|
83
|
+
# leading to K = 0.934*B0[T]*lambda_u[cm]*exp(-pi*gap/lambda_u) or
|
|
84
|
+
# K = undulator_parameter_max*exp(-pi*gap/lambda_u)
|
|
85
|
+
# Calculating undulator_parameter_max gives:
|
|
86
|
+
undulator_parameter_max = (
|
|
87
|
+
(
|
|
88
|
+
2
|
|
89
|
+
* 0.0934
|
|
90
|
+
* undulator_period_mm
|
|
91
|
+
* look_up_table[order][MAGNET_FIELD_COLUMN]
|
|
92
|
+
* magnet_blocks_per_period
|
|
93
|
+
/ np.pi
|
|
94
|
+
)
|
|
95
|
+
* np.sin(np.pi / magnet_blocks_per_period)
|
|
96
|
+
* (1 - np.exp(-2 * np.pi * magnet_block_height_mm / undulator_period_mm))
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Finnaly, rearranging the equation:
|
|
100
|
+
# undulator_parameter = undulator_parameter_max*exp(-pi*gap/lambda_u) for gap gives
|
|
101
|
+
gap = (
|
|
102
|
+
(undulator_period_mm / np.pi)
|
|
103
|
+
* np.log(undulator_parameter_max / undulator_parameter)
|
|
104
|
+
+ look_up_table[order][GAP_OFFSET_COLUMN]
|
|
105
|
+
+ gap_offset
|
|
106
|
+
)
|
|
107
|
+
LOGGER.debug(
|
|
108
|
+
f"Calculated gap is {gap}mm for energy {photon_energy_kev}keV at order {order}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return gap
|
dodal/devices/i10/i10_apple2.py
CHANGED
|
@@ -340,7 +340,7 @@ class I10Apple2(Apple2):
|
|
|
340
340
|
The name of the device, by default "".
|
|
341
341
|
"""
|
|
342
342
|
with self.add_children_as_readables():
|
|
343
|
-
self.jaw_phase = id_jaw_phase
|
|
343
|
+
self.jaw_phase = Reference(id_jaw_phase)
|
|
344
344
|
super().__init__(id_gap=id_gap, id_phase=id_phase, name=name)
|
|
345
345
|
|
|
346
346
|
|
|
@@ -425,7 +425,7 @@ class I10Apple2Controller(Apple2Controller[I10Apple2]):
|
|
|
425
425
|
f"jaw_phase position for angle ({pol_angle}) is outside permitted range"
|
|
426
426
|
f" [-{self.jaw_phase_limit}, {self.jaw_phase_limit}]"
|
|
427
427
|
)
|
|
428
|
-
await self.apple2().jaw_phase.set(jaw_phase)
|
|
428
|
+
await self.apple2().jaw_phase().set(jaw_phase)
|
|
429
429
|
await self._linear_arbitrary_angle.set(pol_angle)
|
|
430
430
|
|
|
431
431
|
async def _set_motors_from_energy(self, value: float) -> None:
|
|
@@ -447,8 +447,8 @@ class I10Apple2Controller(Apple2Controller[I10Apple2]):
|
|
|
447
447
|
LOGGER.info(f"Setting polarisation to {pol}, with values: {id_set_val}")
|
|
448
448
|
await self.apple2().set(id_motor_values=id_set_val)
|
|
449
449
|
if pol != Pol.LA:
|
|
450
|
-
await self.apple2().jaw_phase.set(0)
|
|
451
|
-
await self.apple2().jaw_phase.set_move.set(1)
|
|
450
|
+
await self.apple2().jaw_phase().set(0)
|
|
451
|
+
await self.apple2().jaw_phase().set_move.set(1)
|
|
452
452
|
|
|
453
453
|
def _raise_if_not_la(self, pol: Pol) -> None:
|
|
454
454
|
if pol != Pol.LA:
|
dodal/devices/i15/dcm.py
CHANGED
|
@@ -33,7 +33,7 @@ class DCM(DoubleCrystalMonochromatorBase[ThetaRollYZCrystal, ThetaYCrystal]):
|
|
|
33
33
|
|
|
34
34
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
35
35
|
with self.add_children_as_readables():
|
|
36
|
-
self.
|
|
36
|
+
self.calibrated_energy_in_keV = Motor(prefix + "CAL")
|
|
37
37
|
self.x1 = Motor(prefix + "X1")
|
|
38
38
|
|
|
39
39
|
super().__init__(prefix, ThetaRollYZCrystal, ThetaYCrystal, name)
|
dodal/devices/i22/dcm.py
CHANGED
|
@@ -107,7 +107,7 @@ class DCM(DoubleCrystalMonochromatorWithDSpacing[RollCrystal, PitchAndRollCrysta
|
|
|
107
107
|
|
|
108
108
|
async def read(self) -> dict[str, Reading]:
|
|
109
109
|
default_reading = await super().read()
|
|
110
|
-
energy: float = default_reading[f"{self.name}-
|
|
110
|
+
energy: float = default_reading[f"{self.name}-energy_in_keV"]["value"]
|
|
111
111
|
if energy > 0.0:
|
|
112
112
|
wavelength = _CONVERSION_CONSTANT / energy
|
|
113
113
|
else:
|
|
@@ -13,13 +13,19 @@ from numpy import interp, loadtxt
|
|
|
13
13
|
from dodal.log import LOGGER
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
async def energy_distance_table(
|
|
16
|
+
async def energy_distance_table(
|
|
17
|
+
lookup_table_path: str,
|
|
18
|
+
comments: Sequence[str] = ["#", "Units"],
|
|
19
|
+
skiprows: int = 0,
|
|
20
|
+
) -> np.ndarray:
|
|
17
21
|
"""
|
|
18
22
|
Returns a numpy formatted lookup table for required positions of an ID gap to
|
|
19
23
|
provide emission at a given beam energy.
|
|
20
24
|
|
|
21
25
|
Args:
|
|
22
26
|
lookup_table_path: Path to lookup table
|
|
27
|
+
comments: Lines starting with any of these strings will be ignored
|
|
28
|
+
skiprows: Number of rows to skip at the start of the file
|
|
23
29
|
|
|
24
30
|
Returns:
|
|
25
31
|
ndarray: Lookup table
|
|
@@ -29,7 +35,7 @@ async def energy_distance_table(lookup_table_path: str) -> np.ndarray:
|
|
|
29
35
|
# decodes the text
|
|
30
36
|
async with aiofiles.open(lookup_table_path) as stream:
|
|
31
37
|
raw_table = await stream.read()
|
|
32
|
-
return loadtxt(StringIO(raw_table), comments=
|
|
38
|
+
return loadtxt(StringIO(raw_table), comments=comments, skiprows=skiprows)
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
def parse_lookup_table(filename: str) -> list[Sequence]:
|
|
@@ -15,5 +15,5 @@ class CheckUndulatorDevices(Protocol):
|
|
|
15
15
|
def verify_undulator_gap(devices: CheckUndulatorDevices):
|
|
16
16
|
"""Verify Undulator gap is correct - it may not be after a beam dump"""
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
yield from bps.abs_set(devices.undulator,
|
|
18
|
+
energy_in_keV = yield from bps.rd(devices.dcm.energy_in_keV.user_readback) # noqa: N806
|
|
19
|
+
yield from bps.abs_set(devices.undulator, energy_in_keV, wait=True)
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Allow external repos to reuse these fixtures so defined in single place.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import time
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from bluesky.run_engine import RunEngine
|
|
11
|
+
from bluesky.simulators import RunEngineSimulator
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
15
|
+
async def _ensure_running_bluesky_event_loop():
|
|
16
|
+
run_engine = RunEngine()
|
|
17
|
+
# make sure the event loop is thoroughly up and running before we try to create
|
|
18
|
+
# any ophyd_async devices which might need it
|
|
19
|
+
timeout = time.monotonic() + 1
|
|
20
|
+
while not run_engine.loop.is_running():
|
|
21
|
+
await asyncio.sleep(0)
|
|
22
|
+
if time.monotonic() > timeout:
|
|
23
|
+
raise TimeoutError("This really shouldn't happen but just in case...")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture()
|
|
27
|
+
async def run_engine():
|
|
28
|
+
yield RunEngine()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def sim_run_engine() -> RunEngineSimulator:
|
|
33
|
+
return RunEngineSimulator()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def run_engine_documents(run_engine: RunEngine) -> Mapping[str, list[dict]]:
|
|
38
|
+
docs: dict[str, list[dict]] = {}
|
|
39
|
+
|
|
40
|
+
def append_and_print(name, doc):
|
|
41
|
+
if name not in docs:
|
|
42
|
+
docs[name] = []
|
|
43
|
+
docs[name] += [doc]
|
|
44
|
+
|
|
45
|
+
run_engine.subscribe(append_and_print)
|
|
46
|
+
return docs
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
from random import random
|
|
5
|
+
from threading import Thread
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
async def event_loop_fuzzing():
|
|
12
|
+
"""
|
|
13
|
+
This fixture can be used to try and detect / reproduce intermittent test failures
|
|
14
|
+
caused by race conditions and timing issues, which are often difficult to replicate
|
|
15
|
+
due to caching etc. causing timing to be different on a development machine compared
|
|
16
|
+
to when the test runs in CI.
|
|
17
|
+
|
|
18
|
+
It works by attaching a fuzzer to the current event loop which randomly schedules
|
|
19
|
+
a fixed delay into the event loop thread every few milliseconds. The idea is that
|
|
20
|
+
over a number of iterations, there should be sufficient timing variation introduced
|
|
21
|
+
that the failure can be reproduced.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
Example usage:
|
|
25
|
+
>>> import pytest
|
|
26
|
+
>>> # repeat the test a number of times
|
|
27
|
+
>>> @pytest.mark.parametrize("i", range(0, 100))
|
|
28
|
+
... async def my_unreliable_test(i, event_loop_fuzzing):
|
|
29
|
+
... # Do some stuff in here
|
|
30
|
+
... ...
|
|
31
|
+
"""
|
|
32
|
+
fuzz_probability = 0.05
|
|
33
|
+
fuzz_delay_s = 0.05
|
|
34
|
+
fuzz_period_s = 0.001
|
|
35
|
+
stop_running = threading.Event()
|
|
36
|
+
event_loop = asyncio.get_running_loop()
|
|
37
|
+
|
|
38
|
+
def delay(finished_event: threading.Event):
|
|
39
|
+
time.sleep(fuzz_delay_s) # noqa: TID251
|
|
40
|
+
finished_event.set()
|
|
41
|
+
|
|
42
|
+
def fuzz():
|
|
43
|
+
while not stop_running.is_set():
|
|
44
|
+
if random() < fuzz_probability:
|
|
45
|
+
delay_is_finished = threading.Event()
|
|
46
|
+
event_loop.call_soon_threadsafe(delay, delay_is_finished)
|
|
47
|
+
delay_is_finished.wait()
|
|
48
|
+
|
|
49
|
+
time.sleep(fuzz_period_s) # noqa: TID251
|
|
50
|
+
|
|
51
|
+
fuzzer_thread = Thread(group=None, target=fuzz, name="Event loop fuzzer")
|
|
52
|
+
fuzzer_thread.start()
|
|
53
|
+
try:
|
|
54
|
+
yield None
|
|
55
|
+
finally:
|
|
56
|
+
stop_running.set()
|
|
57
|
+
fuzzer_thread.join()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|