dls-dodal 1.66.0__py3-none-any.whl → 1.67.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/METADATA +1 -1
  2. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/RECORD +47 -37
  3. dodal/_version.py +2 -2
  4. dodal/beamlines/i03.py +92 -208
  5. dodal/beamlines/i04.py +22 -1
  6. dodal/beamlines/i05.py +1 -1
  7. dodal/beamlines/i06.py +1 -1
  8. dodal/beamlines/i09_1.py +26 -2
  9. dodal/beamlines/i09_2.py +57 -2
  10. dodal/beamlines/i10_optics.py +44 -25
  11. dodal/beamlines/i17.py +7 -3
  12. dodal/beamlines/i19_1.py +26 -14
  13. dodal/beamlines/i19_2.py +49 -38
  14. dodal/beamlines/i21.py +2 -2
  15. dodal/beamlines/i22.py +16 -1
  16. dodal/beamlines/training_rig.py +0 -16
  17. dodal/cli.py +26 -12
  18. dodal/common/coordination.py +3 -2
  19. dodal/device_manager.py +604 -0
  20. dodal/devices/cryostream.py +28 -57
  21. dodal/devices/eiger.py +26 -18
  22. dodal/devices/i04/max_pixel.py +38 -0
  23. dodal/devices/i09_1_shared/__init__.py +8 -1
  24. dodal/devices/i09_1_shared/hard_energy.py +112 -0
  25. dodal/devices/i09_2_shared/__init__.py +0 -0
  26. dodal/devices/i09_2_shared/i09_apple2.py +86 -0
  27. dodal/devices/i10/i10_apple2.py +23 -21
  28. dodal/devices/i17/i17_apple2.py +32 -20
  29. dodal/devices/i19/access_controlled/attenuator_motor_squad.py +61 -0
  30. dodal/devices/i19/access_controlled/blueapi_device.py +9 -1
  31. dodal/devices/i19/access_controlled/shutter.py +2 -4
  32. dodal/devices/insertion_device/__init__.py +0 -0
  33. dodal/devices/{apple2_undulator.py → insertion_device/apple2_undulator.py} +36 -28
  34. dodal/devices/insertion_device/energy_motor_lookup.py +88 -0
  35. dodal/devices/insertion_device/lookup_table_models.py +287 -0
  36. dodal/devices/motors.py +14 -0
  37. dodal/devices/robot.py +16 -11
  38. dodal/plans/__init__.py +1 -1
  39. dodal/plans/configure_arm_trigger_and_disarm_detector.py +2 -4
  40. dodal/testing/fixtures/devices/__init__.py +0 -0
  41. dodal/testing/fixtures/devices/apple2.py +78 -0
  42. dodal/utils.py +6 -3
  43. dodal/devices/util/lookup_tables_apple2.py +0 -390
  44. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/WHEEL +0 -0
  45. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/entry_points.txt +0 -0
  46. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/licenses/LICENSE +0 -0
  47. {dls_dodal-1.66.0.dist-info → dls_dodal-1.67.0.dist-info}/top_level.txt +0 -0
  48. /dodal/plans/{scanspec.py → spec_path.py} +0 -0
dodal/beamlines/i09_2.py CHANGED
@@ -1,18 +1,39 @@
1
+ from pathlib import Path
2
+
3
+ from daq_config_server.client import ConfigServer
4
+
1
5
  from dodal.common.beamlines.beamline_utils import (
2
6
  device_factory,
3
7
  )
4
8
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
5
- from dodal.devices.apple2_undulator import (
9
+ from dodal.devices.i09.enums import Grating
10
+ from dodal.devices.i09_2_shared.i09_apple2 import (
11
+ J09_GAP_POLY_DEG_COLUMNS,
12
+ J09_PHASE_POLY_DEG_COLUMNS,
13
+ J09Apple2Controller,
14
+ )
15
+ from dodal.devices.insertion_device.apple2_undulator import (
6
16
  Apple2,
17
+ BeamEnergy,
18
+ InsertionDeviceEnergy,
19
+ InsertionDevicePolarisation,
7
20
  UndulatorGap,
8
21
  UndulatorPhaseAxes,
9
22
  )
10
- from dodal.devices.i09.enums import Grating
23
+ from dodal.devices.insertion_device.energy_motor_lookup import (
24
+ ConfigServerEnergyMotorLookup,
25
+ )
26
+ from dodal.devices.insertion_device.lookup_table_models import LookupTableColumnConfig
11
27
  from dodal.devices.pgm import PlaneGratingMonochromator
12
28
  from dodal.devices.synchrotron import Synchrotron
13
29
  from dodal.log import set_beamline as set_log_beamline
14
30
  from dodal.utils import BeamlinePrefix, get_beamline_name
15
31
 
32
+ J09_CONF_CLIENT = ConfigServer(url="https://daq-config.diamond.ac.uk")
33
+ LOOK_UPTABLE_DIR = "/dls_sw/i09-2/software/gda/workspace_git/gda-diamond.git/configurations/i09-2-shared/lookupTables/"
34
+ GAP_LOOKUP_FILE_NAME = "JIDEnergy2GapCalibrations.csv"
35
+ PHASE_LOOKUP_FILE_NAME = "JIDEnergy2PhaseCalibrations.csv"
36
+
16
37
  BL = get_beamline_name("i09-2")
17
38
  PREFIX = BeamlinePrefix(BL, suffix="J")
18
39
  set_log_beamline(BL)
@@ -55,3 +76,37 @@ def jid() -> Apple2:
55
76
  id_gap=jid_gap(),
56
77
  id_phase=jid_phase(),
57
78
  )
79
+
80
+
81
+ @device_factory()
82
+ def jid_controller() -> J09Apple2Controller:
83
+ """J09 insertion device controller."""
84
+ return J09Apple2Controller(
85
+ apple2=jid(),
86
+ gap_energy_motor_lut=ConfigServerEnergyMotorLookup(
87
+ lut_config=LookupTableColumnConfig(poly_deg=J09_GAP_POLY_DEG_COLUMNS),
88
+ config_client=J09_CONF_CLIENT,
89
+ path=Path(LOOK_UPTABLE_DIR, GAP_LOOKUP_FILE_NAME),
90
+ ),
91
+ phase_energy_motor_lut=ConfigServerEnergyMotorLookup(
92
+ lut_config=LookupTableColumnConfig(poly_deg=J09_PHASE_POLY_DEG_COLUMNS),
93
+ config_client=J09_CONF_CLIENT,
94
+ path=Path(LOOK_UPTABLE_DIR, PHASE_LOOKUP_FILE_NAME),
95
+ ),
96
+ )
97
+
98
+
99
+ @device_factory()
100
+ def jid_energy() -> InsertionDeviceEnergy:
101
+ return InsertionDeviceEnergy(id_controller=jid_controller())
102
+
103
+
104
+ @device_factory()
105
+ def jid_polarisation() -> InsertionDevicePolarisation:
106
+ return InsertionDevicePolarisation(id_controller=jid_controller())
107
+
108
+
109
+ @device_factory()
110
+ def energy_jid() -> BeamEnergy:
111
+ """Beam energy."""
112
+ return BeamEnergy(id_energy=jid_energy(), mono=pgm().energy)
@@ -12,14 +12,6 @@ from daq_config_server.client import ConfigServer
12
12
 
13
13
  from dodal.common.beamlines.beamline_utils import device_factory
14
14
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
15
- from dodal.devices.apple2_undulator import (
16
- BeamEnergy,
17
- InsertionDeviceEnergy,
18
- InsertionDevicePolarisation,
19
- UndulatorGap,
20
- UndulatorJawPhase,
21
- UndulatorPhaseAxes,
22
- )
23
15
  from dodal.devices.i10 import (
24
16
  I10SharedDiagnostic,
25
17
  I10SharedSlits,
@@ -34,14 +26,25 @@ from dodal.devices.i10.i10_apple2 import (
34
26
 
35
27
  # Imports taken from i10 while we work out how to deal with split end stations
36
28
  from dodal.devices.i10.i10_setting_data import I10Grating
37
- from dodal.devices.pgm import PlaneGratingMonochromator
38
- from dodal.devices.synchrotron import Synchrotron
39
- from dodal.devices.util.lookup_tables_apple2 import (
29
+ from dodal.devices.insertion_device.apple2_undulator import (
30
+ BeamEnergy,
31
+ InsertionDeviceEnergy,
32
+ InsertionDevicePolarisation,
33
+ UndulatorGap,
34
+ UndulatorJawPhase,
35
+ UndulatorPhaseAxes,
36
+ )
37
+ from dodal.devices.insertion_device.energy_motor_lookup import (
38
+ ConfigServerEnergyMotorLookup,
39
+ )
40
+ from dodal.devices.insertion_device.lookup_table_models import (
40
41
  DEFAULT_GAP_FILE,
41
42
  DEFAULT_PHASE_FILE,
42
- EnergyMotorLookup,
43
- LookupTableConfig,
43
+ LookupTableColumnConfig,
44
+ Source,
44
45
  )
46
+ from dodal.devices.pgm import PlaneGratingMonochromator
47
+ from dodal.devices.synchrotron import Synchrotron
45
48
  from dodal.log import set_beamline as set_log_beamline
46
49
  from dodal.utils import BeamlinePrefix, get_beamline_name
47
50
 
@@ -50,8 +53,6 @@ set_log_beamline(BL)
50
53
  set_utils_beamline(BL)
51
54
  PREFIX = BeamlinePrefix(BL)
52
55
 
53
- LOOK_UPTABLE_DIR = "/dls_sw/i10/software/blueapi/scratch/i10-config/lookupTables/"
54
-
55
56
 
56
57
  @device_factory()
57
58
  def synchrotron() -> Synchrotron:
@@ -123,13 +124,22 @@ def idd() -> I10Apple2:
123
124
  @device_factory()
124
125
  def idd_controller() -> I10Apple2Controller:
125
126
  """I10 downstream insertion device controller."""
126
- idd_energy_motor_lut = EnergyMotorLookup(
127
+ source = Source(column="Source", value="idd")
128
+ idd_gap_energy_motor_lut = ConfigServerEnergyMotorLookup(
127
129
  config_client=I10_CONF_CLIENT,
128
- lut_config=LookupTableConfig(source=("Source", "idd")),
129
- gap_path=Path(LOOK_UPTABLE_DIR, DEFAULT_GAP_FILE),
130
- phase_path=Path(LOOK_UPTABLE_DIR, DEFAULT_PHASE_FILE),
130
+ lut_config=LookupTableColumnConfig(source=source),
131
+ path=Path(LOOK_UPTABLE_DIR, DEFAULT_GAP_FILE),
132
+ )
133
+ idd_phase_energy_motor_lut = ConfigServerEnergyMotorLookup(
134
+ config_client=I10_CONF_CLIENT,
135
+ lut_config=LookupTableColumnConfig(source=source),
136
+ path=Path(LOOK_UPTABLE_DIR, DEFAULT_PHASE_FILE),
137
+ )
138
+ return I10Apple2Controller(
139
+ apple2=idd(),
140
+ gap_energy_motor_lut=idd_gap_energy_motor_lut,
141
+ phase_energy_motor_lut=idd_phase_energy_motor_lut,
131
142
  )
132
- return I10Apple2Controller(apple2=idd(), energy_motor_lut=idd_energy_motor_lut)
133
143
 
134
144
 
135
145
  @device_factory()
@@ -188,13 +198,22 @@ def idu() -> I10Apple2:
188
198
  @device_factory()
189
199
  def idu_controller() -> I10Apple2Controller:
190
200
  """I10 upstream insertion device controller."""
191
- idu_energy_motor_lut = EnergyMotorLookup(
201
+ source = Source(column="Source", value="idu")
202
+ idu_gap_energy_motor_lut = ConfigServerEnergyMotorLookup(
192
203
  config_client=I10_CONF_CLIENT,
193
- lut_config=LookupTableConfig(source=("Source", "idu")),
194
- gap_path=Path(LOOK_UPTABLE_DIR, DEFAULT_GAP_FILE),
195
- phase_path=Path(LOOK_UPTABLE_DIR, DEFAULT_PHASE_FILE),
204
+ lut_config=LookupTableColumnConfig(source=source),
205
+ path=Path(LOOK_UPTABLE_DIR, DEFAULT_GAP_FILE),
206
+ )
207
+ idu_phase_energy_motor_lut = ConfigServerEnergyMotorLookup(
208
+ config_client=I10_CONF_CLIENT,
209
+ lut_config=LookupTableColumnConfig(source=source),
210
+ path=Path(LOOK_UPTABLE_DIR, DEFAULT_PHASE_FILE),
211
+ )
212
+ return I10Apple2Controller(
213
+ apple2=idd(),
214
+ gap_energy_motor_lut=idu_gap_energy_motor_lut,
215
+ phase_energy_motor_lut=idu_phase_energy_motor_lut,
196
216
  )
197
- return I10Apple2Controller(apple2=idd(), energy_motor_lut=idu_energy_motor_lut)
198
217
 
199
218
 
200
219
  @device_factory()
dodal/beamlines/i17.py CHANGED
@@ -7,7 +7,8 @@ from dodal.common.beamlines.beamline_utils import (
7
7
  device_factory,
8
8
  )
9
9
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
10
- from dodal.devices.apple2_undulator import (
10
+ from dodal.devices.i17.i17_apple2 import I17Apple2Controller
11
+ from dodal.devices.insertion_device.apple2_undulator import (
11
12
  Apple2,
12
13
  Apple2Controller,
13
14
  BeamEnergy,
@@ -16,7 +17,8 @@ from dodal.devices.apple2_undulator import (
16
17
  UndulatorGap,
17
18
  UndulatorPhaseAxes,
18
19
  )
19
- from dodal.devices.i17.i17_apple2 import I17Apple2Controller
20
+ from dodal.devices.insertion_device.energy_motor_lookup import EnergyMotorLookup
21
+ from dodal.devices.insertion_device.lookup_table_models import LookupTable
20
22
  from dodal.devices.pgm import PlaneGratingMonochromator
21
23
  from dodal.devices.synchrotron import Synchrotron
22
24
  from dodal.log import set_beamline as set_log_beamline
@@ -76,7 +78,9 @@ def id() -> Apple2:
76
78
  def id_controller() -> Apple2Controller:
77
79
  """I17 insertion device controller with dummy energy to motor_converter."""
78
80
  return I17Apple2Controller(
79
- apple2=id(), energy_to_motor_converter=lambda energy, pol: (0.0, 0.0)
81
+ apple2=id(),
82
+ gap_energy_motor_lut=EnergyMotorLookup(lut=LookupTable()),
83
+ phase_energy_motor_lut=EnergyMotorLookup(lut=LookupTable()),
80
84
  )
81
85
 
82
86
 
dodal/beamlines/i19_1.py CHANGED
@@ -4,6 +4,9 @@ from dodal.common.beamlines.beamline_utils import (
4
4
  from dodal.common.beamlines.beamline_utils import (
5
5
  set_beamline as set_utils_beamline,
6
6
  )
7
+ from dodal.devices.i19.access_controlled.attenuator_motor_squad import (
8
+ AttenuatorMotorSquad,
9
+ )
7
10
  from dodal.devices.i19.access_controlled.blueapi_device import HutchState
8
11
  from dodal.devices.i19.access_controlled.shutter import (
9
12
  AccessControlledShutter,
@@ -29,6 +32,8 @@ set_log_beamline(BL)
29
32
  set_utils_beamline(BL)
30
33
 
31
34
 
35
+ I19_1_COMMISSIONING_INSTR_SESSION: str = "cm40638-5"
36
+
32
37
  I19_1_ZEBRA_MAPPING = ZebraMapping(
33
38
  outputs=ZebraTTLOutputs(TTL_PILATUS=1),
34
39
  sources=ZebraSources(),
@@ -40,6 +45,13 @@ ZOOM_PARAMS_FILE = (
40
45
  DISPLAY_CONFIG = "/dls_sw/i19-1/software/daq_configuration/domain/display.configuration"
41
46
 
42
47
 
48
+ @device_factory()
49
+ def attenuator_motor_squad() -> AttenuatorMotorSquad:
50
+ return AttenuatorMotorSquad(
51
+ hutch=HutchState.EH1, instrument_session=I19_1_COMMISSIONING_INSTR_SESSION
52
+ )
53
+
54
+
43
55
  # Needs to wait until enum is fixed on the beamline
44
56
  # See https://github.com/DiamondLightSource/dodal/issues/1150
45
57
  @device_factory()
@@ -58,19 +70,6 @@ def oav() -> OAVBeamCentreFile:
58
70
  )
59
71
 
60
72
 
61
- # NOTE EH1 uses the Zebra 2 box. While a Zebra 1 box exists and is connected
62
- # on the beamline, it is currently not in use
63
- @device_factory()
64
- def zebra() -> Zebra:
65
- """Get the i19-1 zebra device, instantiate it if it hasn't already been.
66
- If this is called when already instantiated in i19-1, it will return the existing object.
67
- """
68
- return Zebra(
69
- mapping=I19_1_ZEBRA_MAPPING,
70
- prefix=f"{PREFIX.beamline_prefix}-EA-ZEBRA-02:",
71
- )
72
-
73
-
74
73
  @device_factory()
75
74
  def shutter() -> AccessControlledShutter:
76
75
  """Get the i19-1 hutch shutter device, instantiate it if it hasn't already been.
@@ -79,7 +78,7 @@ def shutter() -> AccessControlledShutter:
79
78
  return AccessControlledShutter(
80
79
  prefix=f"{PREFIX.beamline_prefix}-PS-SHTR-01:",
81
80
  hutch=HutchState.EH1,
82
- instrument_session="cm40638-4",
81
+ instrument_session=I19_1_COMMISSIONING_INSTR_SESSION,
83
82
  )
84
83
 
85
84
 
@@ -89,3 +88,16 @@ def synchrotron() -> Synchrotron:
89
88
  If this is called when already instantiated in i19-1, it will return the existing object.
90
89
  """
91
90
  return Synchrotron()
91
+
92
+
93
+ # NOTE EH1 uses the Zebra 2 box. While a Zebra 1 box exists and is connected
94
+ # on the beamline, it is currently not in use
95
+ @device_factory()
96
+ def zebra() -> Zebra:
97
+ """Get the i19-1 zebra device, instantiate it if it hasn't already been.
98
+ If this is called when already instantiated in i19-1, it will return the existing object.
99
+ """
100
+ return Zebra(
101
+ mapping=I19_1_ZEBRA_MAPPING,
102
+ prefix=f"{PREFIX.beamline_prefix}-EA-ZEBRA-02:",
103
+ )
dodal/beamlines/i19_2.py CHANGED
@@ -12,6 +12,9 @@ from dodal.common.beamlines.beamline_utils import (
12
12
  set_beamline as set_utils_beamline,
13
13
  )
14
14
  from dodal.common.visit import StaticVisitPathProvider
15
+ from dodal.devices.i19.access_controlled.attenuator_motor_squad import (
16
+ AttenuatorMotorSquad,
17
+ )
15
18
  from dodal.devices.i19.access_controlled.blueapi_device import HutchState
16
19
  from dodal.devices.i19.access_controlled.shutter import AccessControlledShutter
17
20
  from dodal.devices.i19.backlight import BacklightPosition
@@ -43,6 +46,7 @@ set_path_provider(
43
46
  )
44
47
  )
45
48
 
49
+ I19_2_COMMISSIONING_INSTR_SESSION: str = "cm40639-5"
46
50
 
47
51
  I19_2_ZEBRA_MAPPING = ZebraMapping(
48
52
  outputs=ZebraTTLOutputs(),
@@ -51,8 +55,18 @@ I19_2_ZEBRA_MAPPING = ZebraMapping(
51
55
 
52
56
 
53
57
  @device_factory()
54
- def diffractometer() -> FourCircleDiffractometer:
55
- return FourCircleDiffractometer(prefix=PREFIX.beamline_prefix)
58
+ def attenuator_motor_squad() -> AttenuatorMotorSquad:
59
+ return AttenuatorMotorSquad(
60
+ hutch=HutchState.EH2, instrument_session=I19_2_COMMISSIONING_INSTR_SESSION
61
+ )
62
+
63
+
64
+ @device_factory()
65
+ def backlight() -> BacklightPosition:
66
+ """Get the i19-2 backlight device, instantiate it if it hasn't already been.
67
+ If this is called when already instantiated in i19-2, it will return the existing object.
68
+ """
69
+ return BacklightPosition(prefix=f"{PREFIX.beamline_prefix}-EA-IOC-12:")
56
70
 
57
71
 
58
72
  @device_factory()
@@ -64,34 +78,26 @@ def beamstop() -> BeamStop:
64
78
 
65
79
 
66
80
  @device_factory()
67
- def zebra() -> Zebra:
68
- """Get the i19-2 zebra device, instantiate it if it hasn't already been.
69
- If this is called when already instantiated in i19-2, it will return the existing object.
70
- """
71
- return Zebra(
72
- mapping=I19_2_ZEBRA_MAPPING,
73
- prefix=f"{PREFIX.beamline_prefix}-EA-ZEBRA-03:",
74
- )
81
+ def diffractometer() -> FourCircleDiffractometer:
82
+ return FourCircleDiffractometer(prefix=PREFIX.beamline_prefix)
75
83
 
76
84
 
77
85
  @device_factory()
78
- def shutter() -> AccessControlledShutter:
79
- """Get the i19-2 hutch shutter device, instantiate it if it hasn't already been.
80
- If this is called when already instantiated, it will return the existing object.
81
- """
82
- return AccessControlledShutter(
83
- prefix=f"{PREFIX.beamline_prefix}-PS-SHTR-01:",
84
- hutch=HutchState.EH2,
85
- instrument_session="cm40639-4",
86
+ def eiger() -> EigerDetector:
87
+ return EigerDetector(
88
+ prefix=PREFIX.beamline_prefix,
89
+ path_provider=get_path_provider(),
90
+ drv_suffix="-EA-EIGER-01:",
91
+ hdf_suffix="-EA-EIGER-01:OD:",
86
92
  )
87
93
 
88
94
 
89
95
  @device_factory()
90
- def synchrotron() -> Synchrotron:
91
- """Get the i19-2 synchrotron device, instantiate it if it hasn't already been.
92
- If this is called when already instantiated in i19-2, it will return the existing object.
93
- """
94
- return Synchrotron()
96
+ def panda() -> HDFPanda:
97
+ return HDFPanda(
98
+ prefix=f"{PREFIX.beamline_prefix}-EA-PANDA-01:",
99
+ path_provider=get_path_provider(),
100
+ )
95
101
 
96
102
 
97
103
  @device_factory()
@@ -104,26 +110,31 @@ def pinhole_and_collimator() -> PinholeCollimatorControl:
104
110
 
105
111
 
106
112
  @device_factory()
107
- def backlight() -> BacklightPosition:
108
- """Get the i19-2 backlight device, instantiate it if it hasn't already been.
109
- If this is called when already instantiated in i19-2, it will return the existing object.
113
+ def shutter() -> AccessControlledShutter:
114
+ """Get the i19-2 hutch shutter device, instantiate it if it hasn't already been.
115
+ If this is called when already instantiated, it will return the existing object.
110
116
  """
111
- return BacklightPosition(prefix=f"{PREFIX.beamline_prefix}-EA-IOC-12:")
117
+ return AccessControlledShutter(
118
+ prefix=f"{PREFIX.beamline_prefix}-PS-SHTR-01:",
119
+ hutch=HutchState.EH2,
120
+ instrument_session=I19_2_COMMISSIONING_INSTR_SESSION,
121
+ )
112
122
 
113
123
 
114
124
  @device_factory()
115
- def panda() -> HDFPanda:
116
- return HDFPanda(
117
- prefix=f"{PREFIX.beamline_prefix}-EA-PANDA-01:",
118
- path_provider=get_path_provider(),
119
- )
125
+ def synchrotron() -> Synchrotron:
126
+ """Get the i19-2 synchrotron device, instantiate it if it hasn't already been.
127
+ If this is called when already instantiated in i19-2, it will return the existing object.
128
+ """
129
+ return Synchrotron()
120
130
 
121
131
 
122
132
  @device_factory()
123
- def eiger() -> EigerDetector:
124
- return EigerDetector(
125
- prefix=PREFIX.beamline_prefix,
126
- path_provider=get_path_provider(),
127
- drv_suffix="-EA-EIGER-01:",
128
- hdf_suffix="-EA-EIGER-01:OD:",
133
+ def zebra() -> Zebra:
134
+ """Get the i19-2 zebra device, instantiate it if it hasn't already been.
135
+ If this is called when already instantiated in i19-2, it will return the existing object.
136
+ """
137
+ return Zebra(
138
+ mapping=I19_2_ZEBRA_MAPPING,
139
+ prefix=f"{PREFIX.beamline_prefix}-EA-ZEBRA-03:",
129
140
  )
dodal/beamlines/i21.py CHANGED
@@ -2,12 +2,12 @@ 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 (
5
+ from dodal.devices.i21 import Grating
6
+ from dodal.devices.insertion_device.apple2_undulator import (
6
7
  Apple2,
7
8
  UndulatorGap,
8
9
  UndulatorPhaseAxes,
9
10
  )
10
- from dodal.devices.i21 import Grating
11
11
  from dodal.devices.pgm import PlaneGratingMonochromator
12
12
  from dodal.devices.synchrotron import Synchrotron
13
13
  from dodal.log import set_beamline as set_log_beamline
dodal/beamlines/i22.py CHANGED
@@ -19,7 +19,7 @@ from dodal.devices.i22.dcm import DCM
19
19
  from dodal.devices.i22.fswitch import FSwitch
20
20
  from dodal.devices.i22.nxsas import NXSasMetadataHolder, NXSasOAV, NXSasPilatus
21
21
  from dodal.devices.linkam3 import Linkam3
22
- from dodal.devices.motors import XYPitchStage
22
+ from dodal.devices.motors import XYPitchStage, XYRollStage, XYStage
23
23
  from dodal.devices.slits import Slits
24
24
  from dodal.devices.synchrotron import Synchrotron
25
25
  from dodal.devices.tetramm import TetrammDetector
@@ -274,3 +274,18 @@ def ppump() -> WatsonMarlow323Pump:
274
274
  @device_factory()
275
275
  def base() -> XYPitchStage:
276
276
  return XYPitchStage(f"{PREFIX.beamline_prefix}-MO-STABL-01:")
277
+
278
+
279
+ @device_factory()
280
+ def bs1() -> XYStage:
281
+ return XYStage(f"{PREFIX.beamline_prefix}-MO-SAXSP-01:BS1:")
282
+
283
+
284
+ @device_factory()
285
+ def bs2() -> XYStage:
286
+ return XYStage(f"{PREFIX.beamline_prefix}-MO-SAXSP-01:BS2:")
287
+
288
+
289
+ @device_factory()
290
+ def bs3() -> XYRollStage:
291
+ return XYRollStage(f"{PREFIX.beamline_prefix}-MO-SAXSP-01:BS3:")
@@ -1,19 +1,12 @@
1
- from pathlib import Path
2
-
3
1
  from ophyd_async.epics.adaravis import AravisDetector
4
2
  from ophyd_async.fastcs.panda import HDFPanda
5
3
 
6
4
  from dodal.common.beamlines.beamline_utils import (
7
5
  device_factory,
8
6
  get_path_provider,
9
- set_path_provider,
10
7
  )
11
8
  from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
12
9
  from dodal.common.beamlines.device_helpers import DET_SUFFIX, HDF5_SUFFIX
13
- from dodal.common.visit import (
14
- LocalDirectoryServiceClient,
15
- StaticVisitPathProvider,
16
- )
17
10
  from dodal.devices.motors import XThetaStage
18
11
  from dodal.log import set_beamline as set_log_beamline
19
12
  from dodal.utils import BeamlinePrefix, get_beamline_name
@@ -35,15 +28,6 @@ set_log_beamline(BL)
35
28
  set_utils_beamline(BL)
36
29
 
37
30
 
38
- set_path_provider(
39
- StaticVisitPathProvider(
40
- BL,
41
- Path("/exports/mybeamline/data/2025"),
42
- client=LocalDirectoryServiceClient(),
43
- )
44
- )
45
-
46
-
47
31
  @device_factory()
48
32
  def sample_stage() -> XThetaStage:
49
33
  return XThetaStage(f"{PREFIX.beamline_prefix}-MO-MAP-01:STAGE:")
dodal/cli.py CHANGED
@@ -1,3 +1,4 @@
1
+ import importlib
1
2
  import os
2
3
  from collections.abc import Mapping
3
4
  from pathlib import Path
@@ -9,6 +10,7 @@ from ophyd_async.plan_stubs import ensure_connected
9
10
 
10
11
  from dodal.beamlines import all_beamline_names, module_name_for_beamline
11
12
  from dodal.common.beamlines.beamline_utils import set_path_provider
13
+ from dodal.device_manager import DeviceManager
12
14
  from dodal.utils import AnyDevice, filter_ophyd_devices, make_all_devices
13
15
 
14
16
  from . import __version__
@@ -43,7 +45,8 @@ def main(ctx: click.Context) -> None:
43
45
  "attempt any I/O. Useful as a a dry-run.",
44
46
  default=False,
45
47
  )
46
- def connect(beamline: str, all: bool, sim_backend: bool) -> None:
48
+ @click.option("-n", "--name", "device_manager", default="devices")
49
+ def connect(beamline: str, all: bool, sim_backend: bool, device_manager: str) -> None:
47
50
  """Initialises a beamline module, connects to all devices, reports
48
51
  any connection issues."""
49
52
 
@@ -51,7 +54,6 @@ def connect(beamline: str, all: bool, sim_backend: bool) -> None:
51
54
 
52
55
  # We need to make a fake path provider for any detectors that need one,
53
56
  # it is not used in dodal connect
54
- _spoof_path_provider()
55
57
 
56
58
  module_name = module_name_for_beamline(beamline)
57
59
  full_module_path = f"dodal.beamlines.{module_name}"
@@ -62,16 +64,28 @@ def connect(beamline: str, all: bool, sim_backend: bool) -> None:
62
64
 
63
65
  print(f"Attempting connection to {beamline} (using {full_module_path})")
64
66
 
65
- # Force all devices to be lazy (don't connect to PVs on instantiation) and do
66
- # connection as an extra step, because the alternatives is handling the fact
67
- # that only some devices may be lazy.
68
- devices, instance_exceptions = make_all_devices(
69
- full_module_path,
70
- include_skipped=all,
71
- fake_with_ophyd_sim=sim_backend,
72
- wait_for_connection=False,
73
- )
74
- devices, connect_exceptions = _connect_devices(run_engine, devices, sim_backend)
67
+ mod = importlib.import_module(full_module_path)
68
+
69
+ # Don't connect devices as they're built and do connection as an extra step,
70
+ # because the alternatives is handling the fact that only some devices may
71
+ # be lazy.
72
+
73
+ if (manager := getattr(mod, device_manager, None)) and isinstance(
74
+ manager, DeviceManager
75
+ ):
76
+ devices, instance_exceptions, connect_exceptions = manager.build_and_connect(
77
+ mock=sim_backend,
78
+ )
79
+ else:
80
+ print(f"No device manager named '{device_manager}' found in {mod}")
81
+ _spoof_path_provider()
82
+ devices, instance_exceptions = make_all_devices(
83
+ full_module_path,
84
+ include_skipped=all,
85
+ fake_with_ophyd_sim=sim_backend,
86
+ wait_for_connection=False,
87
+ )
88
+ devices, connect_exceptions = _connect_devices(run_engine, devices, sim_backend)
75
89
 
76
90
  # Inform user of successful connections
77
91
  _report_successful_devices(devices, sim_backend)
@@ -17,7 +17,7 @@ def group_uuid(name: str) -> Group:
17
17
  return f"{name}-{str(uuid.uuid4())[:6]}"
18
18
 
19
19
 
20
- def inject(name: str) -> Any: # type: ignore
20
+ def inject(name: str = "") -> Any: # type: ignore
21
21
  """
22
22
  Function to mark a defaulted argument of a plan as a reference to a device stored
23
23
  in another context and not available to be referenced directly.
@@ -30,7 +30,8 @@ def inject(name: str) -> Any: # type: ignore
30
30
  def scan(x: Movable = inject("stage_x"), start: float = 0.0 ...)
31
31
 
32
32
  Args:
33
- name (str): Name of a Device to be fetched from an external context
33
+ name (str): Name of a Device to be fetched from an external context. This can be
34
+ left blank when injecting device composites (the default)
34
35
 
35
36
  Returns:
36
37
  Any: name but without typing checking, valid as any default type