dls-dodal 1.46.0__py3-none-any.whl → 1.48.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.46.0.dist-info → dls_dodal-1.48.0.dist-info}/METADATA +2 -2
- {dls_dodal-1.46.0.dist-info → dls_dodal-1.48.0.dist-info}/RECORD +74 -63
- {dls_dodal-1.46.0.dist-info → dls_dodal-1.48.0.dist-info}/WHEEL +1 -1
- dodal/_version.py +2 -2
- dodal/beamlines/__init__.py +0 -1
- dodal/beamlines/aithre.py +6 -0
- dodal/beamlines/b01_1.py +1 -1
- dodal/beamlines/b07.py +2 -6
- dodal/beamlines/b07_1.py +1 -3
- dodal/beamlines/i03.py +33 -21
- dodal/beamlines/i04.py +65 -26
- dodal/beamlines/i09.py +1 -3
- dodal/beamlines/i09_1.py +1 -3
- dodal/beamlines/i18.py +1 -1
- dodal/beamlines/i19_1.py +9 -6
- dodal/beamlines/i23.py +17 -1
- dodal/beamlines/i24.py +5 -5
- dodal/beamlines/p38.py +1 -1
- dodal/beamlines/p60.py +2 -6
- dodal/beamlines/p99.py +48 -4
- dodal/common/beamlines/beamline_parameters.py +3 -30
- dodal/common/data_util.py +4 -0
- dodal/devices/aithre_lasershaping/goniometer.py +36 -2
- dodal/devices/aithre_lasershaping/laser_robot.py +27 -0
- dodal/devices/aperturescatterguard.py +47 -47
- dodal/devices/current_amplifiers/struck_scaler_counter.py +1 -1
- dodal/devices/diamond_filter.py +5 -17
- dodal/devices/eiger.py +1 -1
- dodal/devices/electron_analyser/__init__.py +18 -0
- dodal/devices/electron_analyser/abstract/__init__.py +22 -0
- dodal/devices/electron_analyser/abstract/base_detector.py +223 -0
- dodal/devices/electron_analyser/abstract/base_driver_io.py +230 -0
- dodal/devices/electron_analyser/{abstract_region.py → abstract/base_region.py} +3 -9
- dodal/devices/electron_analyser/specs/__init__.py +10 -0
- dodal/devices/electron_analyser/specs/detector.py +13 -0
- dodal/devices/electron_analyser/specs/driver_io.py +89 -0
- dodal/devices/electron_analyser/{specs_region.py → specs/region.py} +1 -1
- dodal/devices/electron_analyser/types.py +6 -0
- dodal/devices/electron_analyser/util.py +13 -0
- dodal/devices/electron_analyser/vgscienta/__init__.py +11 -0
- dodal/devices/electron_analyser/vgscienta/detector.py +22 -0
- dodal/devices/electron_analyser/vgscienta/driver_io.py +67 -0
- dodal/devices/electron_analyser/{vgscienta_region.py → vgscienta/region.py} +1 -2
- dodal/devices/fast_grid_scan.py +7 -9
- dodal/devices/i03/__init__.py +3 -0
- dodal/devices/i04/__init__.py +3 -0
- dodal/devices/i04/constants.py +9 -0
- dodal/devices/i04/murko_results.py +192 -0
- dodal/devices/i10/diagnostics.py +9 -61
- dodal/devices/i18/diode.py +37 -4
- dodal/devices/i24/focus_mirrors.py +9 -13
- dodal/devices/i24/pilatus_metadata.py +9 -9
- dodal/devices/i24/pmac.py +19 -14
- dodal/devices/{i03 → mx_phase1}/beamstop.py +26 -15
- dodal/devices/oav/oav_calculations.py +2 -2
- dodal/devices/oav/oav_detector.py +80 -32
- dodal/devices/oav/oav_parameters.py +46 -16
- dodal/devices/oav/oav_to_redis_forwarder.py +2 -2
- dodal/devices/oav/utils.py +2 -2
- dodal/devices/p99/andor2_point.py +41 -0
- dodal/devices/positioner.py +49 -0
- dodal/devices/robot.py +20 -1
- dodal/devices/smargon.py +43 -4
- dodal/devices/tetramm.py +5 -2
- dodal/devices/util/adjuster_plans.py +1 -1
- dodal/devices/zebra/zebra.py +8 -0
- dodal/devices/zebra/zebra_constants_mapping.py +1 -1
- dodal/devices/zocalo/__init__.py +0 -3
- dodal/devices/zocalo/zocalo_results.py +6 -32
- dodal/log.py +14 -14
- dodal/plans/configure_arm_trigger_and_disarm_detector.py +167 -0
- dodal/common/signal_utils.py +0 -88
- dodal/devices/electron_analyser/abstract_analyser_io.py +0 -47
- dodal/devices/electron_analyser/specs_analyser_io.py +0 -19
- dodal/devices/electron_analyser/vgscienta_analyser_io.py +0 -26
- dodal/devices/logging_ophyd_device.py +0 -17
- dodal/plan_stubs/electron_analyser/__init__.py +0 -0
- dodal/plan_stubs/electron_analyser/configure_controller.py +0 -80
- {dls_dodal-1.46.0.dist-info → dls_dodal-1.48.0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.46.0.dist-info → dls_dodal-1.48.0.dist-info}/licenses/LICENSE +0 -0
- {dls_dodal-1.46.0.dist-info → dls_dodal-1.48.0.dist-info}/top_level.txt +0 -0
dodal/beamlines/i04.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
1
|
from dodal.common.beamlines.beamline_parameters import get_beamline_parameters
|
|
4
|
-
from dodal.common.beamlines.beamline_utils import
|
|
2
|
+
from dodal.common.beamlines.beamline_utils import (
|
|
3
|
+
device_factory,
|
|
4
|
+
device_instantiation,
|
|
5
|
+
)
|
|
5
6
|
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
|
|
6
7
|
from dodal.devices.aperturescatterguard import (
|
|
7
8
|
AperturePosition,
|
|
@@ -17,12 +18,16 @@ from dodal.devices.eiger import EigerDetector
|
|
|
17
18
|
from dodal.devices.fast_grid_scan import ZebraFastGridScan
|
|
18
19
|
from dodal.devices.flux import Flux
|
|
19
20
|
from dodal.devices.i03.dcm import DCM
|
|
21
|
+
from dodal.devices.i04.constants import RedisConstants
|
|
22
|
+
from dodal.devices.i04.murko_results import MurkoResultsDevice
|
|
20
23
|
from dodal.devices.i04.transfocator import Transfocator
|
|
21
24
|
from dodal.devices.ipin import IPin
|
|
22
25
|
from dodal.devices.motors import XYZPositioner
|
|
23
|
-
from dodal.devices.
|
|
26
|
+
from dodal.devices.mx_phase1.beamstop import Beamstop
|
|
27
|
+
from dodal.devices.oav.oav_detector import OAVBeamCentrePV
|
|
24
28
|
from dodal.devices.oav.oav_parameters import OAVConfig
|
|
25
29
|
from dodal.devices.oav.oav_to_redis_forwarder import OAVToRedisForwarder
|
|
30
|
+
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
26
31
|
from dodal.devices.robot import BartRobot
|
|
27
32
|
from dodal.devices.s4_slit_gaps import S4SlitGaps
|
|
28
33
|
from dodal.devices.smargon import Smargon
|
|
@@ -37,6 +42,7 @@ from dodal.devices.zebra.zebra_constants_mapping import (
|
|
|
37
42
|
ZebraTTLOutputs,
|
|
38
43
|
)
|
|
39
44
|
from dodal.devices.zebra.zebra_controlled_shutter import ZebraShutter
|
|
45
|
+
from dodal.devices.zocalo import ZocaloResults
|
|
40
46
|
from dodal.log import set_beamline as set_log_beamline
|
|
41
47
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
42
48
|
|
|
@@ -46,11 +52,8 @@ ZOOM_PARAMS_FILE = (
|
|
|
46
52
|
DISPLAY_CONFIG = "/dls_sw/i04/software/gda_versions/var/display.configuration"
|
|
47
53
|
DAQ_CONFIGURATION_PATH = "/dls_sw/i04/software/daq_configuration"
|
|
48
54
|
|
|
49
|
-
REDIS_HOST = "i04-valkey-murko.diamond.ac.uk"
|
|
50
|
-
REDIS_PASSWORD = os.environ.get("VALKEY_PASSWORD", "test_redis_password")
|
|
51
|
-
MURKO_REDIS_DB = 7
|
|
52
55
|
|
|
53
|
-
BL = get_beamline_name("
|
|
56
|
+
BL = get_beamline_name("i04")
|
|
54
57
|
set_log_beamline(BL)
|
|
55
58
|
set_utils_beamline(BL)
|
|
56
59
|
|
|
@@ -107,13 +110,13 @@ def ipin() -> IPin:
|
|
|
107
110
|
|
|
108
111
|
|
|
109
112
|
@device_factory()
|
|
110
|
-
def beamstop() ->
|
|
113
|
+
def beamstop() -> Beamstop:
|
|
111
114
|
"""Get the i04 beamstop device, instantiate it if it hasn't already been.
|
|
112
115
|
If this is called when already instantiated in i04, it will return the existing object.
|
|
113
116
|
"""
|
|
114
|
-
return
|
|
117
|
+
return Beamstop(
|
|
115
118
|
f"{PREFIX.beamline_prefix}-MO-BS-01:",
|
|
116
|
-
|
|
119
|
+
beamline_parameters=get_beamline_parameters(),
|
|
117
120
|
)
|
|
118
121
|
|
|
119
122
|
|
|
@@ -294,18 +297,25 @@ def zebra() -> Zebra:
|
|
|
294
297
|
|
|
295
298
|
|
|
296
299
|
@device_factory(skip=BL == "s04")
|
|
297
|
-
def oav(
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
def oav(params: OAVConfig | None = None) -> OAVBeamCentrePV:
|
|
301
|
+
"""Get the i04 OAV device, instantiate it if it hasn't already been.
|
|
302
|
+
If this is called when already instantiated in i04, it will return the existing object.
|
|
303
|
+
"""
|
|
304
|
+
return OAVBeamCentrePV(
|
|
305
|
+
prefix=f"{PREFIX.beamline_prefix}-DI-OAV-01:",
|
|
306
|
+
config=params or OAVConfig(ZOOM_PARAMS_FILE),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
@device_factory(skip=BL == "s04")
|
|
311
|
+
def oav_full_screen(params: OAVConfig | None = None) -> OAVBeamCentrePV:
|
|
302
312
|
"""Get the i04 OAV device, instantiate it if it hasn't already been.
|
|
303
313
|
If this is called when already instantiated in i04, it will return the existing object.
|
|
304
314
|
"""
|
|
305
|
-
return
|
|
315
|
+
return OAVBeamCentrePV(
|
|
306
316
|
prefix=f"{PREFIX.beamline_prefix}-DI-OAV-01:",
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
config=params or OAVConfig(ZOOM_PARAMS_FILE),
|
|
318
|
+
overlay_channel=3,
|
|
309
319
|
)
|
|
310
320
|
|
|
311
321
|
|
|
@@ -350,19 +360,48 @@ def oav_to_redis_forwarder() -> OAVToRedisForwarder:
|
|
|
350
360
|
return OAVToRedisForwarder(
|
|
351
361
|
f"{PREFIX.beamline_prefix}-DI-OAV-01:",
|
|
352
362
|
name="oav_to_redis_forwarder",
|
|
353
|
-
redis_host=REDIS_HOST,
|
|
354
|
-
redis_password=REDIS_PASSWORD,
|
|
355
|
-
redis_db=
|
|
363
|
+
redis_host=RedisConstants.REDIS_HOST,
|
|
364
|
+
redis_password=RedisConstants.REDIS_PASSWORD,
|
|
365
|
+
redis_db=RedisConstants.MURKO_REDIS_DB,
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
@device_factory()
|
|
370
|
+
def murko_results() -> MurkoResultsDevice:
|
|
371
|
+
"""Get the i04 OAV to redis forwarder, instantiate it if it hasn't already been.
|
|
372
|
+
If this is called when already instantiated in i04, it will return the existing object.
|
|
373
|
+
"""
|
|
374
|
+
return MurkoResultsDevice(
|
|
375
|
+
name="murko_results",
|
|
376
|
+
redis_host=RedisConstants.REDIS_HOST,
|
|
377
|
+
redis_password=RedisConstants.REDIS_PASSWORD,
|
|
378
|
+
redis_db=RedisConstants.MURKO_REDIS_DB,
|
|
356
379
|
)
|
|
357
380
|
|
|
358
381
|
|
|
359
382
|
@device_factory()
|
|
360
383
|
def diamond_filter() -> DiamondFilter[I04Filters]:
|
|
361
384
|
"""Get the i04 diamond filter device, instantiate it if it hasn't already been.
|
|
362
|
-
If this is called when already instantiated in
|
|
385
|
+
If this is called when already instantiated in i04, it will return the existing object.
|
|
363
386
|
"""
|
|
364
387
|
return DiamondFilter[I04Filters](
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
388
|
+
f"{PREFIX.beamline_prefix}-MO-FLTR-01:Y", I04Filters
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@device_factory()
|
|
393
|
+
def zocalo() -> ZocaloResults:
|
|
394
|
+
"""Get the i04 ZocaloResults device, instantiate it if it hasn't already been.
|
|
395
|
+
If this is called when already instantiated in i04, it will return the existing object.
|
|
396
|
+
"""
|
|
397
|
+
return ZocaloResults(channel="xrc.i04")
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@device_factory()
|
|
401
|
+
def pin_tip_detection() -> PinTipDetection:
|
|
402
|
+
"""Get the i04 pin tip detection device, instantiate it if it hasn't already been.
|
|
403
|
+
If this is called when already instantiated in i04, it will return the existing object.
|
|
404
|
+
"""
|
|
405
|
+
return PinTipDetection(
|
|
406
|
+
f"{PREFIX.beamline_prefix}-DI-OAV-01:",
|
|
368
407
|
)
|
dodal/beamlines/i09.py
CHANGED
|
@@ -2,9 +2,7 @@ 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.electron_analyser.
|
|
6
|
-
VGScientaAnalyserDriverIO,
|
|
7
|
-
)
|
|
5
|
+
from dodal.devices.electron_analyser.vgscienta import VGScientaAnalyserDriverIO
|
|
8
6
|
from dodal.devices.synchrotron import Synchrotron
|
|
9
7
|
from dodal.log import set_beamline as set_log_beamline
|
|
10
8
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
dodal/beamlines/i09_1.py
CHANGED
|
@@ -2,9 +2,7 @@ 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.electron_analyser.
|
|
6
|
-
SpecsAnalyserDriverIO,
|
|
7
|
-
)
|
|
5
|
+
from dodal.devices.electron_analyser.specs import SpecsAnalyserDriverIO
|
|
8
6
|
from dodal.devices.synchrotron import Synchrotron
|
|
9
7
|
from dodal.log import set_beamline as set_log_beamline
|
|
10
8
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
dodal/beamlines/i18.py
CHANGED
dodal/beamlines/i19_1.py
CHANGED
|
@@ -6,9 +6,12 @@ from dodal.common.beamlines.beamline_utils import (
|
|
|
6
6
|
)
|
|
7
7
|
from dodal.devices.i19.beamstop import BeamStop
|
|
8
8
|
from dodal.devices.i19.blueapi_device import HutchState
|
|
9
|
-
from dodal.devices.i19.shutter import
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
from dodal.devices.i19.shutter import (
|
|
10
|
+
AccessControlledShutter,
|
|
11
|
+
HutchState,
|
|
12
|
+
)
|
|
13
|
+
from dodal.devices.oav.oav_detector import OAVBeamCentreFile
|
|
14
|
+
from dodal.devices.oav.oav_parameters import OAVConfigBeamCentre
|
|
12
15
|
from dodal.devices.synchrotron import Synchrotron
|
|
13
16
|
from dodal.devices.zebra.zebra import Zebra
|
|
14
17
|
from dodal.devices.zebra.zebra_constants_mapping import (
|
|
@@ -48,10 +51,10 @@ def beamstop() -> BeamStop:
|
|
|
48
51
|
|
|
49
52
|
|
|
50
53
|
@device_factory()
|
|
51
|
-
def oav() ->
|
|
52
|
-
return
|
|
54
|
+
def oav() -> OAVBeamCentreFile:
|
|
55
|
+
return OAVBeamCentreFile(
|
|
53
56
|
prefix=f"{PREFIX.beamline_prefix}-EA-OAV-01:",
|
|
54
|
-
config=
|
|
57
|
+
config=OAVConfigBeamCentre(ZOOM_PARAMS_FILE, DISPLAY_CONFIG),
|
|
55
58
|
)
|
|
56
59
|
|
|
57
60
|
|
dodal/beamlines/i23.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
+
from ophyd_async.core import StrictEnum
|
|
3
4
|
from ophyd_async.epics.adpilatus import PilatusDetector
|
|
4
5
|
|
|
5
6
|
from dodal.common.beamlines.beamline_utils import (
|
|
@@ -12,6 +13,7 @@ from dodal.common.beamlines.device_helpers import HDF5_SUFFIX
|
|
|
12
13
|
from dodal.common.visit import LocalDirectoryServiceClient, StaticVisitPathProvider
|
|
13
14
|
from dodal.devices.motors import SixAxisGonio
|
|
14
15
|
from dodal.devices.oav.pin_image_recognition import PinTipDetection
|
|
16
|
+
from dodal.devices.positioner import Positioner1D
|
|
15
17
|
from dodal.devices.zebra.zebra import Zebra
|
|
16
18
|
from dodal.devices.zebra.zebra_constants_mapping import (
|
|
17
19
|
ZebraMapping,
|
|
@@ -39,10 +41,15 @@ PREFIX = BeamlinePrefix(BL)
|
|
|
39
41
|
I23_ZEBRA_MAPPING = ZebraMapping(
|
|
40
42
|
outputs=ZebraTTLOutputs(TTL_DETECTOR=1, TTL_SHUTTER=4),
|
|
41
43
|
sources=ZebraSources(),
|
|
42
|
-
AND_GATE_FOR_AUTO_SHUTTER=2,
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
class I23DetectorPositions(StrictEnum):
|
|
48
|
+
IN = "In"
|
|
49
|
+
OUT = "Out"
|
|
50
|
+
SAMPLE_CHANGE = "sample change"
|
|
51
|
+
|
|
52
|
+
|
|
46
53
|
def _is_i23_machine():
|
|
47
54
|
"""
|
|
48
55
|
Devices using PVA can only connect from i23 machines, due to the absence of
|
|
@@ -93,3 +100,12 @@ def pilatus() -> PilatusDetector:
|
|
|
93
100
|
drv_suffix="cam1:",
|
|
94
101
|
fileio_suffix=HDF5_SUFFIX,
|
|
95
102
|
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@device_factory()
|
|
106
|
+
def detector_motion() -> Positioner1D[I23DetectorPositions]:
|
|
107
|
+
"""Get the i23 detector"""
|
|
108
|
+
return Positioner1D[I23DetectorPositions](
|
|
109
|
+
f"{PREFIX.beamline_prefix}-EA-DET-01:Z",
|
|
110
|
+
datatype=I23DetectorPositions,
|
|
111
|
+
)
|
dodal/beamlines/i24.py
CHANGED
|
@@ -15,8 +15,8 @@ from dodal.devices.i24.i24_detector_motion import DetectorMotion
|
|
|
15
15
|
from dodal.devices.i24.pilatus_metadata import PilatusMetadata
|
|
16
16
|
from dodal.devices.i24.pmac import PMAC
|
|
17
17
|
from dodal.devices.i24.vgonio import VerticalGoniometer
|
|
18
|
-
from dodal.devices.oav.oav_detector import
|
|
19
|
-
from dodal.devices.oav.oav_parameters import
|
|
18
|
+
from dodal.devices.oav.oav_detector import OAVBeamCentreFile
|
|
19
|
+
from dodal.devices.oav.oav_parameters import OAVConfigBeamCentre
|
|
20
20
|
from dodal.devices.zebra.zebra import Zebra
|
|
21
21
|
from dodal.devices.zebra.zebra_constants_mapping import (
|
|
22
22
|
ZebraMapping,
|
|
@@ -150,11 +150,11 @@ def pmac() -> PMAC:
|
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
@device_factory(skip=BL == "s24")
|
|
153
|
-
def oav() ->
|
|
154
|
-
return
|
|
153
|
+
def oav() -> OAVBeamCentreFile:
|
|
154
|
+
return OAVBeamCentreFile(
|
|
155
155
|
prefix=f"{PREFIX.beamline_prefix}-DI-OAV-01:",
|
|
156
156
|
name="oav",
|
|
157
|
-
config=
|
|
157
|
+
config=OAVConfigBeamCentre(ZOOM_PARAMS_FILE, DISPLAY_CONFIG),
|
|
158
158
|
)
|
|
159
159
|
|
|
160
160
|
|
dodal/beamlines/p38.py
CHANGED
dodal/beamlines/p60.py
CHANGED
|
@@ -2,9 +2,7 @@ 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.electron_analyser.
|
|
6
|
-
VGScientaAnalyserDriverIO,
|
|
7
|
-
)
|
|
5
|
+
from dodal.devices.electron_analyser.vgscienta import VGScientaAnalyserDriverIO
|
|
8
6
|
from dodal.log import set_beamline as set_log_beamline
|
|
9
7
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
10
8
|
|
|
@@ -16,6 +14,4 @@ set_utils_beamline(BL)
|
|
|
16
14
|
|
|
17
15
|
@device_factory()
|
|
18
16
|
def analyser_driver() -> VGScientaAnalyserDriverIO:
|
|
19
|
-
return VGScientaAnalyserDriverIO(
|
|
20
|
-
name="analyser_driver", prefix=f"{PREFIX.beamline_prefix}-EA-DET-01:CAM:"
|
|
21
|
-
)
|
|
17
|
+
return VGScientaAnalyserDriverIO(prefix=f"{PREFIX.beamline_prefix}-EA-DET-01:CAM:")
|
dodal/beamlines/p99.py
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
from
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from ophyd_async.epics.adandor import Andor2Detector
|
|
4
|
+
|
|
5
|
+
from dodal.common.beamlines.beamline_utils import (
|
|
6
|
+
device_factory,
|
|
7
|
+
get_path_provider,
|
|
8
|
+
set_beamline,
|
|
9
|
+
set_path_provider,
|
|
10
|
+
)
|
|
11
|
+
from dodal.common.beamlines.device_helpers import CAM_SUFFIX, HDF5_SUFFIX
|
|
12
|
+
from dodal.common.visit import (
|
|
13
|
+
LocalDirectoryServiceClient,
|
|
14
|
+
StaticVisitPathProvider,
|
|
15
|
+
)
|
|
2
16
|
from dodal.devices.attenuator.filter import FilterMotor
|
|
3
17
|
from dodal.devices.attenuator.filter_selections import P99FilterSelections
|
|
4
18
|
from dodal.devices.motors import XYZPositioner
|
|
19
|
+
from dodal.devices.p99.andor2_point import Andor2Point
|
|
5
20
|
from dodal.devices.p99.sample_stage import SampleAngleStage
|
|
6
21
|
from dodal.log import set_beamline as set_log_beamline
|
|
7
22
|
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
@@ -19,9 +34,7 @@ def angle_stage() -> SampleAngleStage:
|
|
|
19
34
|
|
|
20
35
|
@device_factory()
|
|
21
36
|
def filter() -> FilterMotor:
|
|
22
|
-
return FilterMotor(
|
|
23
|
-
f"{PREFIX.beamline_prefix}-MO-STAGE-02:MP:SELECT", P99FilterSelections
|
|
24
|
-
)
|
|
37
|
+
return FilterMotor(f"{PREFIX.beamline_prefix}-MO-STAGE-02:MP:", P99FilterSelections)
|
|
25
38
|
|
|
26
39
|
|
|
27
40
|
@device_factory()
|
|
@@ -32,3 +45,34 @@ def sample_stage() -> XYZPositioner:
|
|
|
32
45
|
@device_factory()
|
|
33
46
|
def lab_stage() -> XYZPositioner:
|
|
34
47
|
return XYZPositioner(f"{PREFIX.beamline_prefix}-MO-STAGE-02:LAB:")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
set_path_provider(
|
|
51
|
+
StaticVisitPathProvider(
|
|
52
|
+
BL,
|
|
53
|
+
Path("/dls/p99/data/2024/cm37284-2/processing/writenData"),
|
|
54
|
+
client=LocalDirectoryServiceClient(), # RemoteDirectoryServiceClient("http://p99-control:8088/api"),
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@device_factory()
|
|
60
|
+
def andor2_det() -> Andor2Detector:
|
|
61
|
+
"""Andor model:DU897_BV."""
|
|
62
|
+
return Andor2Detector(
|
|
63
|
+
prefix=f"{PREFIX.beamline_prefix}-EA-DET-03:",
|
|
64
|
+
path_provider=get_path_provider(),
|
|
65
|
+
drv_suffix=CAM_SUFFIX,
|
|
66
|
+
fileio_suffix=HDF5_SUFFIX,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@device_factory()
|
|
71
|
+
def andor2_point() -> Andor2Point:
|
|
72
|
+
"""Using the andor2 as if it is a massive point detector, read the meanValue and total after
|
|
73
|
+
a picture is taken."""
|
|
74
|
+
return Andor2Point(
|
|
75
|
+
prefix=f"{PREFIX.beamline_prefix}-EA-DET-03:",
|
|
76
|
+
drv_suffix=CAM_SUFFIX,
|
|
77
|
+
read_uncached={"mean": "STAT:MeanValue_RBV", "total": "STAT:Total_RBV"},
|
|
78
|
+
)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ast
|
|
1
2
|
from typing import Any, cast
|
|
2
3
|
|
|
3
4
|
from dodal.log import LOGGER
|
|
@@ -8,7 +9,6 @@ BEAMLINE_PARAMETER_KEYWORDS = ["FB", "FULL", "deadtime"]
|
|
|
8
9
|
BEAMLINE_PARAMETER_PATHS = {
|
|
9
10
|
"i03": "/dls_sw/i03/software/daq_configuration/domain/beamlineParameters",
|
|
10
11
|
"i04": "/dls_sw/i04/software/gda_versions/gda_9_34/workspace_git/gda-mx.git/configurations/i04-config/scripts/beamlineParameters",
|
|
11
|
-
"s03": "tests/test_data/test_beamline_parameters.txt",
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
|
|
@@ -58,41 +58,14 @@ class GDABeamlineParameters:
|
|
|
58
58
|
|
|
59
59
|
@classmethod
|
|
60
60
|
def parse_value(cls, value: str):
|
|
61
|
-
|
|
62
|
-
return cls.parse_list(value[1:].strip())
|
|
63
|
-
else:
|
|
64
|
-
return cls.parse_list_element(value)
|
|
65
|
-
|
|
66
|
-
@classmethod
|
|
67
|
-
def parse_list_element(cls, value: str):
|
|
68
|
-
if value == "Yes":
|
|
69
|
-
return True
|
|
70
|
-
elif value == "No":
|
|
71
|
-
return False
|
|
72
|
-
else:
|
|
73
|
-
return float(value)
|
|
74
|
-
|
|
75
|
-
@classmethod
|
|
76
|
-
def parse_list(cls, value: str):
|
|
77
|
-
list_output = []
|
|
78
|
-
remaining = value.strip()
|
|
79
|
-
i = 0
|
|
80
|
-
while (i := remaining.find(",")) != -1:
|
|
81
|
-
list_output.append(cls.parse_list_element(remaining[:i]))
|
|
82
|
-
remaining = remaining[i + 1 :].lstrip()
|
|
83
|
-
if (i := remaining.find("]")) != -1:
|
|
84
|
-
list_output.append(cls.parse_list_element(remaining[:i]))
|
|
85
|
-
remaining = remaining[i + 1 :].lstrip()
|
|
86
|
-
else:
|
|
87
|
-
raise ValueError("Missing closing ']' in list expression")
|
|
88
|
-
return list_output
|
|
61
|
+
return ast.literal_eval(value.replace("Yes", "True").replace("No", "False"))
|
|
89
62
|
|
|
90
63
|
|
|
91
64
|
def get_beamline_parameters(beamline_param_path: str | None = None):
|
|
92
65
|
"""Loads the beamline parameters from the specified path, or according to the
|
|
93
66
|
environment variable if none is given"""
|
|
94
67
|
if not beamline_param_path:
|
|
95
|
-
beamline_name = get_beamline_name("
|
|
68
|
+
beamline_name = get_beamline_name("i03")
|
|
96
69
|
beamline_param_path = BEAMLINE_PARAMETER_PATHS.get(beamline_name)
|
|
97
70
|
if beamline_param_path is None:
|
|
98
71
|
raise KeyError(
|
dodal/common/data_util.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from typing import TypeVar
|
|
2
3
|
|
|
3
4
|
from pydantic import BaseModel
|
|
@@ -9,6 +10,9 @@ def load_json_file_to_class(
|
|
|
9
10
|
t: type[TBaseModel],
|
|
10
11
|
file: str,
|
|
11
12
|
) -> TBaseModel:
|
|
13
|
+
if not os.path.isfile(file):
|
|
14
|
+
raise FileNotFoundError(f"Cannot find file {file}")
|
|
15
|
+
|
|
12
16
|
with open(file) as f:
|
|
13
17
|
json_obj = f.read()
|
|
14
18
|
cls = t.model_validate_json(json_obj)
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
from ophyd_async.core import StandardReadable, derived_signal_rw
|
|
2
5
|
from ophyd_async.epics.motor import Motor
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
class Goniometer(StandardReadable):
|
|
6
|
-
"""
|
|
9
|
+
"""The Aithre lab goniometer and the XYZ stage it sits on.
|
|
10
|
+
|
|
11
|
+
`x`, `y` and `z` control the axes of the positioner at the base, while `sampy` and
|
|
12
|
+
`sampz` control the positioner of the sample. `omega` is the rotation about the
|
|
13
|
+
x-axis (along the length of the sample holder).
|
|
14
|
+
|
|
15
|
+
The `vertical_position` signal refers to the height of the sample from the point of
|
|
16
|
+
view of the OAV and setting this value moves the sample vertically in the OAV plane
|
|
17
|
+
regardless of the current rotation.
|
|
18
|
+
"""
|
|
7
19
|
|
|
8
20
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
9
21
|
self.x = Motor(prefix + "X")
|
|
@@ -12,4 +24,26 @@ class Goniometer(StandardReadable):
|
|
|
12
24
|
self.sampy = Motor(prefix + "SAMPY")
|
|
13
25
|
self.sampz = Motor(prefix + "SAMPZ")
|
|
14
26
|
self.omega = Motor(prefix + "OMEGA")
|
|
27
|
+
self.vertical_position = derived_signal_rw(
|
|
28
|
+
self._get,
|
|
29
|
+
self._set,
|
|
30
|
+
sampy=self.sampy,
|
|
31
|
+
sampz=self.sampz,
|
|
32
|
+
omega=self.omega,
|
|
33
|
+
)
|
|
15
34
|
super().__init__(name)
|
|
35
|
+
|
|
36
|
+
def _get(self, sampz: float, sampy: float, omega: float) -> float:
|
|
37
|
+
z_component = sampz * math.cos(math.radians(omega))
|
|
38
|
+
y_component = sampy * math.sin(math.radians(omega))
|
|
39
|
+
return z_component + y_component
|
|
40
|
+
|
|
41
|
+
async def _set(self, value: float) -> None:
|
|
42
|
+
omega = await self.omega.user_readback.get_value()
|
|
43
|
+
z_component = value * math.cos(math.radians(omega))
|
|
44
|
+
y_component = value * math.sin(math.radians(omega))
|
|
45
|
+
await asyncio.gather(
|
|
46
|
+
self.sampy.set(y_component),
|
|
47
|
+
self.sampz.set(z_component),
|
|
48
|
+
self.omega.set(omega),
|
|
49
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from ophyd_async.core import StrictEnum
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
3
|
+
|
|
4
|
+
from dodal.devices.robot import BartRobot
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ForceBit(StrictEnum):
|
|
8
|
+
ON = "On"
|
|
9
|
+
NO = "No"
|
|
10
|
+
OFF = "Off"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LidHeatEnable(StrictEnum):
|
|
14
|
+
ENABLED = "Enabled"
|
|
15
|
+
DISABLED = "Disabled"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LaserRobot(BartRobot):
|
|
19
|
+
def __init__(self, name: str, prefix: str) -> None:
|
|
20
|
+
self.dewar_lid_heater = epics_signal_rw(
|
|
21
|
+
LidHeatEnable, prefix + "DW_1_ENABLED", prefix + "DW_1_CTRL"
|
|
22
|
+
)
|
|
23
|
+
self.cryojet_retract = epics_signal_rw(ForceBit, prefix + "OP_24_FORCE_OPTION")
|
|
24
|
+
self.set_beamline_safe = epics_signal_rw(
|
|
25
|
+
ForceBit, prefix + "IP_16_FORCE_OPTION"
|
|
26
|
+
)
|
|
27
|
+
super().__init__(name=name, prefix=prefix)
|