dls-dodal 1.36.0__py3-none-any.whl → 1.36.1a0__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.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/METADATA +33 -33
- {dls_dodal-1.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/RECORD +37 -33
- {dls_dodal-1.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/WHEEL +1 -1
- dodal/_version.py +2 -2
- dodal/beamlines/b01_1.py +16 -31
- dodal/beamlines/i22.py +124 -265
- dodal/beamlines/i24.py +56 -7
- dodal/beamlines/p38.py +16 -1
- dodal/beamlines/p99.py +22 -53
- dodal/beamlines/training_rig.py +16 -26
- dodal/cli.py +54 -8
- dodal/common/beamlines/beamline_utils.py +32 -2
- dodal/common/beamlines/device_helpers.py +2 -0
- dodal/devices/aperture.py +7 -0
- dodal/devices/aperturescatterguard.py +195 -79
- dodal/devices/dcm.py +5 -4
- dodal/devices/fast_grid_scan.py +21 -46
- dodal/devices/focusing_mirror.py +8 -3
- dodal/devices/i24/beam_center.py +12 -0
- dodal/devices/i24/focus_mirrors.py +60 -0
- dodal/devices/i24/pilatus_metadata.py +44 -0
- dodal/devices/linkam3.py +1 -1
- dodal/devices/motors.py +14 -10
- dodal/devices/oav/oav_detector.py +2 -2
- dodal/devices/oav/pin_image_recognition/__init__.py +4 -5
- dodal/devices/oav/utils.py +1 -0
- dodal/devices/p99/sample_stage.py +12 -16
- dodal/devices/pressure_jump_cell.py +299 -0
- dodal/devices/robot.py +1 -1
- dodal/devices/tetramm.py +1 -1
- dodal/devices/undulator.py +4 -1
- dodal/devices/undulator_dcm.py +3 -19
- dodal/devices/zocalo/zocalo_results.py +7 -7
- dodal/utils.py +151 -2
- {dls_dodal-1.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/LICENSE +0 -0
- {dls_dodal-1.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.36.0.dist-info → dls_dodal-1.36.1a0.dist-info}/top_level.txt +0 -0
dodal/devices/fast_grid_scan.py
CHANGED
|
@@ -31,12 +31,12 @@ from dodal.parameters.experiment_parameter_base import AbstractExperimentWithBea
|
|
|
31
31
|
@dataclass
|
|
32
32
|
class GridAxis:
|
|
33
33
|
start: float
|
|
34
|
-
|
|
34
|
+
step_size_mm: float
|
|
35
35
|
full_steps: int
|
|
36
36
|
|
|
37
37
|
def steps_to_motor_position(self, steps):
|
|
38
38
|
"""Gives the motor position based on steps, where steps are 0 indexed"""
|
|
39
|
-
return self.start + self.
|
|
39
|
+
return self.start + self.step_size_mm * steps
|
|
40
40
|
|
|
41
41
|
@property
|
|
42
42
|
def end(self):
|
|
@@ -62,44 +62,29 @@ class GridScanParamsCommon(AbstractExperimentWithBeamParams):
|
|
|
62
62
|
x_steps: int = 1
|
|
63
63
|
y_steps: int = 1
|
|
64
64
|
z_steps: int = 0
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
x_step_size_mm: float = 0.1
|
|
66
|
+
y_step_size_mm: float = 0.1
|
|
67
|
+
z_step_size_mm: float = 0.1
|
|
68
|
+
x_start_mm: float = 0.1
|
|
69
|
+
y1_start_mm: float = 0.1
|
|
70
|
+
y2_start_mm: float = 0.1
|
|
71
|
+
z1_start_mm: float = 0.1
|
|
72
|
+
z2_start_mm: float = 0.1
|
|
73
73
|
|
|
74
74
|
# Whether to set the stub offsets after centering
|
|
75
75
|
set_stub_offsets: bool = False
|
|
76
76
|
|
|
77
|
-
def get_param_positions(self) -> dict:
|
|
78
|
-
return {
|
|
79
|
-
"x_steps": self.x_steps,
|
|
80
|
-
"y_steps": self.y_steps,
|
|
81
|
-
"z_steps": self.z_steps,
|
|
82
|
-
"x_step_size": self.x_step_size,
|
|
83
|
-
"y_step_size": self.y_step_size,
|
|
84
|
-
"z_step_size": self.z_step_size,
|
|
85
|
-
"x_start": self.x_start,
|
|
86
|
-
"y1_start": self.y1_start,
|
|
87
|
-
"y2_start": self.y2_start,
|
|
88
|
-
"z1_start": self.z1_start,
|
|
89
|
-
"z2_start": self.z2_start,
|
|
90
|
-
}
|
|
91
|
-
|
|
92
77
|
@property
|
|
93
78
|
def x_axis(self) -> GridAxis:
|
|
94
|
-
return GridAxis(self.
|
|
79
|
+
return GridAxis(self.x_start_mm, self.x_step_size_mm, self.x_steps)
|
|
95
80
|
|
|
96
81
|
@property
|
|
97
82
|
def y_axis(self) -> GridAxis:
|
|
98
|
-
return GridAxis(self.
|
|
83
|
+
return GridAxis(self.y1_start_mm, self.y_step_size_mm, self.y_steps)
|
|
99
84
|
|
|
100
85
|
@property
|
|
101
86
|
def z_axis(self) -> GridAxis:
|
|
102
|
-
return GridAxis(self.
|
|
87
|
+
return GridAxis(self.z2_start_mm, self.z_step_size_mm, self.z_steps)
|
|
103
88
|
|
|
104
89
|
def get_num_images(self):
|
|
105
90
|
return self.x_steps * (self.y_steps + self.z_steps)
|
|
@@ -140,11 +125,6 @@ class ZebraGridScanParams(GridScanParamsCommon):
|
|
|
140
125
|
|
|
141
126
|
dwell_time_ms: float = 10
|
|
142
127
|
|
|
143
|
-
def get_param_positions(self):
|
|
144
|
-
param_positions = super().get_param_positions()
|
|
145
|
-
param_positions["dwell_time_ms"] = self.dwell_time_ms
|
|
146
|
-
return param_positions
|
|
147
|
-
|
|
148
128
|
@field_validator("dwell_time_ms")
|
|
149
129
|
@classmethod
|
|
150
130
|
def non_integer_dwell_time(cls, dwell_time_ms: float) -> float:
|
|
@@ -166,11 +146,6 @@ class PandAGridScanParams(GridScanParamsCommon):
|
|
|
166
146
|
|
|
167
147
|
run_up_distance_mm: float = 0.17
|
|
168
148
|
|
|
169
|
-
def get_param_positions(self):
|
|
170
|
-
param_positions = super().get_param_positions()
|
|
171
|
-
param_positions["run_up_distance_mm"] = self.run_up_distance_mm
|
|
172
|
-
return param_positions
|
|
173
|
-
|
|
174
149
|
|
|
175
150
|
class MotionProgram(Device):
|
|
176
151
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
@@ -241,14 +216,14 @@ class FastGridScanCommon(StandardReadable, Flyable, ABC, Generic[ParamType]):
|
|
|
241
216
|
"x_steps": self.x_steps,
|
|
242
217
|
"y_steps": self.y_steps,
|
|
243
218
|
"z_steps": self.z_steps,
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
250
|
-
"
|
|
251
|
-
"
|
|
219
|
+
"x_step_size_mm": self.x_step_size,
|
|
220
|
+
"y_step_size_mm": self.y_step_size,
|
|
221
|
+
"z_step_size_mm": self.z_step_size,
|
|
222
|
+
"x_start_mm": self.x_start,
|
|
223
|
+
"y1_start_mm": self.y1_start,
|
|
224
|
+
"y2_start_mm": self.y2_start,
|
|
225
|
+
"z1_start_mm": self.z1_start,
|
|
226
|
+
"z2_start_mm": self.z2_start,
|
|
252
227
|
}
|
|
253
228
|
super().__init__(name)
|
|
254
229
|
|
dodal/devices/focusing_mirror.py
CHANGED
|
@@ -130,7 +130,12 @@ class FocusingMirror(StandardReadable):
|
|
|
130
130
|
"""Focusing Mirror"""
|
|
131
131
|
|
|
132
132
|
def __init__(
|
|
133
|
-
self,
|
|
133
|
+
self,
|
|
134
|
+
prefix: str,
|
|
135
|
+
name: str = "",
|
|
136
|
+
bragg_to_lat_lut_path: str | None = None,
|
|
137
|
+
x_suffix: str = "X",
|
|
138
|
+
y_suffix: str = "Y",
|
|
134
139
|
):
|
|
135
140
|
self.bragg_to_lat_lookup_table_path = bragg_to_lat_lut_path
|
|
136
141
|
self.yaw_mrad = Motor(prefix + "YAW")
|
|
@@ -161,12 +166,12 @@ class FocusingMirrorWithStripes(FocusingMirror):
|
|
|
161
166
|
"""A focusing mirror where the stripe material can be changed. This is usually done
|
|
162
167
|
based on the energy of the beamline."""
|
|
163
168
|
|
|
164
|
-
def __init__(self,
|
|
169
|
+
def __init__(self, prefix: str, name: str = "", *args, **kwargs):
|
|
165
170
|
self.stripe = epics_signal_rw(MirrorStripe, prefix + "STRP:DVAL")
|
|
166
171
|
# apply the current set stripe setting
|
|
167
172
|
self.apply_stripe = epics_signal_x(prefix + "CHANGE.PROC")
|
|
168
173
|
|
|
169
|
-
super().__init__(
|
|
174
|
+
super().__init__(prefix, name, *args, **kwargs)
|
|
170
175
|
|
|
171
176
|
def energy_to_stripe(self, energy_kev) -> MirrorStripe:
|
|
172
177
|
# In future, this should be configurable per-mirror
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""A small temporary device to get the beam center positions from \
|
|
2
|
+
eiger or pilatus detector on i24"""
|
|
3
|
+
|
|
4
|
+
from ophyd_async.core import StandardReadable
|
|
5
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DetectorBeamCenter(StandardReadable):
|
|
9
|
+
def __init__(self, prefix: str, name: str = "") -> None:
|
|
10
|
+
self.beam_x = epics_signal_rw(float, prefix + "BeamX")
|
|
11
|
+
self.beam_y = epics_signal_rw(float, prefix + "BeamY")
|
|
12
|
+
super().__init__(name)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from ophyd_async.core import StandardReadable, StrictEnum
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw
|
|
3
|
+
|
|
4
|
+
from dodal.common.signal_utils import create_hardware_backed_soft_signal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class HFocusMode(StrictEnum):
|
|
8
|
+
focus10 = "HMFMfocus10"
|
|
9
|
+
focus20d = "HMFMfocus20d"
|
|
10
|
+
focus30d = "HMFMfocus30d"
|
|
11
|
+
focus50d = "HMFMfocus50d"
|
|
12
|
+
focus1050d = "HMFMfocus1030d"
|
|
13
|
+
focus3010d = "HMFMfocus3010d"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class VFocusMode(StrictEnum):
|
|
17
|
+
focus10 = "VMFMfocus10"
|
|
18
|
+
focus20d = "VMFMfocus20d"
|
|
19
|
+
focus30d = "VMFMfocus30d"
|
|
20
|
+
focus50d = "VMFMfocus50d"
|
|
21
|
+
focus1030d = "VMFMfocus1030d"
|
|
22
|
+
focus3010d = "VMFMfocus3010d"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
BEAM_SIZES = {
|
|
26
|
+
"focus10": [7, 7],
|
|
27
|
+
"focus20d": [20, 20],
|
|
28
|
+
"focus30d": [30, 30],
|
|
29
|
+
"focus50d": [50, 50],
|
|
30
|
+
"focus1030d": [10, 30],
|
|
31
|
+
"focus3010d": [30, 10],
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class FocusMirrorsMode(StandardReadable):
|
|
36
|
+
"""A small device to read the focus mode and work out the beam size."""
|
|
37
|
+
|
|
38
|
+
def __init__(self, prefix: str, name: str = "") -> None:
|
|
39
|
+
self.horizontal = epics_signal_rw(HFocusMode, prefix + "G1:TARGETAPPLY")
|
|
40
|
+
self.vertical = epics_signal_rw(VFocusMode, prefix + "G0:TARGETAPPLY")
|
|
41
|
+
|
|
42
|
+
with self.add_children_as_readables():
|
|
43
|
+
self.beam_size_x = create_hardware_backed_soft_signal(
|
|
44
|
+
int, self._get_beam_size_x, units="um"
|
|
45
|
+
)
|
|
46
|
+
self.beam_size_y = create_hardware_backed_soft_signal(
|
|
47
|
+
int, self._get_beam_size_y, units="um"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
super().__init__(name)
|
|
51
|
+
|
|
52
|
+
async def _get_beam_size_x(self) -> int:
|
|
53
|
+
h_mode = await self.horizontal.get_value()
|
|
54
|
+
beam_x = BEAM_SIZES[h_mode.removeprefix("HMFM")][0]
|
|
55
|
+
return beam_x
|
|
56
|
+
|
|
57
|
+
async def _get_beam_size_y(self) -> int:
|
|
58
|
+
v_mode = await self.vertical.get_value()
|
|
59
|
+
beam_y = BEAM_SIZES[v_mode.removeprefix("VMFM")][1]
|
|
60
|
+
return beam_y
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""A small temporary device to set and read the filename template from the pilatus"""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from ophyd_async.core import StandardReadable
|
|
6
|
+
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
|
|
7
|
+
|
|
8
|
+
from dodal.common.signal_utils import create_hardware_backed_soft_signal
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PilatusMetadata(StandardReadable):
|
|
12
|
+
def __init__(self, prefix: str, name: str = "") -> None:
|
|
13
|
+
self.filename = epics_signal_rw(str, prefix + "cam1:FileName")
|
|
14
|
+
self.template = epics_signal_r(str, prefix + "cam1:FileTemplate_RBV")
|
|
15
|
+
self.filenumber = epics_signal_r(int, prefix + "cam1:FileNumber_RBV")
|
|
16
|
+
with self.add_children_as_readables():
|
|
17
|
+
self.filename_template = create_hardware_backed_soft_signal(
|
|
18
|
+
str, self._get_full_filename_template
|
|
19
|
+
)
|
|
20
|
+
super().__init__(name)
|
|
21
|
+
|
|
22
|
+
async def _get_full_filename_template(self) -> str:
|
|
23
|
+
"""
|
|
24
|
+
Get the template file path by querying the detector PVs.
|
|
25
|
+
Mirror the construction that the PPU does.
|
|
26
|
+
|
|
27
|
+
Returns: A template string, with the image numbers replaced with '#'
|
|
28
|
+
"""
|
|
29
|
+
filename = await self.filename.get_value()
|
|
30
|
+
filename_template = await self.template.get_value()
|
|
31
|
+
file_number = await self.filenumber.get_value()
|
|
32
|
+
# Exploit fact that passing negative numbers will put the - before the 0's
|
|
33
|
+
expected_filename = str(
|
|
34
|
+
filename_template % (filename, f"{file_number:05d}_", -9)
|
|
35
|
+
)
|
|
36
|
+
# Now, find the -09 part of this
|
|
37
|
+
numberpart = re.search(r"(-0+9)", expected_filename)
|
|
38
|
+
assert numberpart is not None
|
|
39
|
+
template_fill = "#" * len(numberpart.group(0))
|
|
40
|
+
return (
|
|
41
|
+
expected_filename[: numberpart.start()]
|
|
42
|
+
+ template_fill
|
|
43
|
+
+ expected_filename[numberpart.end() :]
|
|
44
|
+
)
|
dodal/devices/linkam3.py
CHANGED
|
@@ -33,7 +33,7 @@ class Linkam3(StandardReadable):
|
|
|
33
33
|
tolerance: float = 0.5
|
|
34
34
|
settle_time: int = 0
|
|
35
35
|
|
|
36
|
-
def __init__(self, prefix: str, name: str):
|
|
36
|
+
def __init__(self, prefix: str, name: str = ""):
|
|
37
37
|
self.temp = epics_signal_r(float, prefix + "TEMP:")
|
|
38
38
|
self.dsc = epics_signal_r(float, prefix + "DSC:")
|
|
39
39
|
self.start_heat = epics_signal_rw(bool, prefix + "STARTHEAT:")
|
dodal/devices/motors.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from ophyd_async.core import
|
|
1
|
+
from ophyd_async.core import StandardReadable
|
|
2
2
|
from ophyd_async.epics.motor import Motor
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class XYZPositioner(
|
|
5
|
+
class XYZPositioner(StandardReadable):
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
Standard ophyd_async xyz motor stage, by combining 3 Motors,
|
|
@@ -15,7 +15,7 @@ class XYZPositioner(Device):
|
|
|
15
15
|
name:
|
|
16
16
|
name for the stage.
|
|
17
17
|
infix:
|
|
18
|
-
EPICS PV, default is the
|
|
18
|
+
EPICS PV, default is the ("X", "Y", "Z").
|
|
19
19
|
Notes
|
|
20
20
|
-----
|
|
21
21
|
Example usage::
|
|
@@ -23,14 +23,18 @@ class XYZPositioner(Device):
|
|
|
23
23
|
xyz_stage = XYZPositioner("BLXX-MO-STAGE-XX:")
|
|
24
24
|
Or::
|
|
25
25
|
with DeviceCollector():
|
|
26
|
-
xyz_stage = XYZPositioner("BLXX-MO-STAGE-XX:",
|
|
26
|
+
xyz_stage = XYZPositioner("BLXX-MO-STAGE-XX:", infix = ("A", "B", "C"))
|
|
27
27
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
def __init__(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
prefix: str,
|
|
33
|
+
name: str = "",
|
|
34
|
+
infix: tuple[str, str, str] = ("X", "Y", "Z"),
|
|
35
|
+
):
|
|
36
|
+
with self.add_children_as_readables():
|
|
37
|
+
self.x = Motor(prefix + infix[0])
|
|
38
|
+
self.y = Motor(prefix + infix[1])
|
|
39
|
+
self.z = Motor(prefix + infix[2])
|
|
36
40
|
super().__init__(name=name)
|
|
@@ -40,15 +40,15 @@ class ZoomController(StandardReadable):
|
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
42
|
def __init__(self, prefix: str, name: str = "") -> None:
|
|
43
|
-
super().__init__(name=name)
|
|
44
43
|
self.percentage = epics_signal_rw(float, f"{prefix}ZOOMPOSCMD")
|
|
45
44
|
|
|
46
45
|
# Level is the string description of the zoom level e.g. "1.0x" or "1.0"
|
|
47
46
|
self.level = epics_signal_rw(str, f"{prefix}MP:SELECT")
|
|
47
|
+
super().__init__(name=name)
|
|
48
48
|
|
|
49
49
|
async def _get_allowed_zoom_levels(self) -> list:
|
|
50
50
|
zoom_levels = await self.level.describe()
|
|
51
|
-
return zoom_levels[
|
|
51
|
+
return zoom_levels[self.level.name]["choices"] # type: ignore
|
|
52
52
|
|
|
53
53
|
@AsyncStatus.wrap
|
|
54
54
|
async def set(self, level_to_set: str):
|
|
@@ -2,7 +2,6 @@ import asyncio
|
|
|
2
2
|
import time
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
|
-
from numpy.typing import NDArray
|
|
6
5
|
from ophyd_async.core import (
|
|
7
6
|
Array1D,
|
|
8
7
|
AsyncStatus,
|
|
@@ -57,12 +56,12 @@ class PinTipDetection(StandardReadable):
|
|
|
57
56
|
Tip, name="triggered_tip"
|
|
58
57
|
)
|
|
59
58
|
self.triggered_top_edge, self._top_edge_setter = soft_signal_r_and_setter(
|
|
60
|
-
|
|
59
|
+
Array1D[np.int32], name="triggered_top_edge"
|
|
61
60
|
)
|
|
62
61
|
self.triggered_bottom_edge, self._bottom_edge_setter = soft_signal_r_and_setter(
|
|
63
|
-
|
|
62
|
+
Array1D[np.int32], name="triggered_bottom_edge"
|
|
64
63
|
)
|
|
65
|
-
self.array_data = epics_signal_r(
|
|
64
|
+
self.array_data = epics_signal_r(Array1D[np.uint8], f"pva://{prefix}PVA:ARRAY")
|
|
66
65
|
|
|
67
66
|
# Soft parameters for pin-tip detection.
|
|
68
67
|
self.preprocess_operation = soft_signal_rw(int, 10, name="preprocess")
|
|
@@ -101,7 +100,7 @@ class PinTipDetection(StandardReadable):
|
|
|
101
100
|
self._bottom_edge_setter(results.edge_bottom)
|
|
102
101
|
|
|
103
102
|
async def _get_tip_and_edge_data(
|
|
104
|
-
self, array_data:
|
|
103
|
+
self, array_data: Array1D[np.uint8]
|
|
105
104
|
) -> SampleLocation:
|
|
106
105
|
"""
|
|
107
106
|
Gets the location of the pin tip and the top and bottom edges.
|
dodal/devices/oav/utils.py
CHANGED
|
@@ -87,6 +87,7 @@ def calculate_x_y_z_of_pixel(
|
|
|
87
87
|
beam_centre: tuple[int, int],
|
|
88
88
|
microns_per_pixel: tuple[float, float],
|
|
89
89
|
) -> np.ndarray:
|
|
90
|
+
"""Get the x, y, z position of a pixel in mm"""
|
|
90
91
|
beam_distance_px: Pixel = calculate_beam_distance(beam_centre, *pixel)
|
|
91
92
|
|
|
92
93
|
return current_x_y_z + camera_coordinates_to_xyz(
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
from ophyd_async.core import
|
|
2
|
-
from ophyd_async.epics.core import epics_signal_rw
|
|
1
|
+
from ophyd_async.core import StandardReadable, SubsetEnum
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw, epics_signal_rw_rbv
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class SampleAngleStage(
|
|
6
|
-
def __init__(self, prefix: str, name: str):
|
|
7
|
-
self.
|
|
8
|
-
float, prefix + "WRITETHETA
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
float, prefix + "WRITEROLL:RBV", prefix + "WRITEROLL"
|
|
12
|
-
)
|
|
13
|
-
self.pitch = epics_signal_rw(
|
|
14
|
-
float, prefix + "WRITEPITCH:RBV", prefix + "WRITEPITCH"
|
|
15
|
-
)
|
|
5
|
+
class SampleAngleStage(StandardReadable):
|
|
6
|
+
def __init__(self, prefix: str, name: str = ""):
|
|
7
|
+
with self.add_children_as_readables():
|
|
8
|
+
self.theta = epics_signal_rw_rbv(float, prefix + "WRITETHETA", ":RBV")
|
|
9
|
+
self.roll = epics_signal_rw_rbv(float, prefix + "WRITEROLL", ":RBV")
|
|
10
|
+
self.pitch = epics_signal_rw_rbv(float, prefix + "WRITEPITCH", ":RBV")
|
|
16
11
|
super().__init__(name=name)
|
|
17
12
|
|
|
18
13
|
|
|
@@ -35,7 +30,8 @@ class p99StageSelections(SubsetEnum):
|
|
|
35
30
|
User = "User"
|
|
36
31
|
|
|
37
32
|
|
|
38
|
-
class FilterMotor(
|
|
39
|
-
def __init__(self, prefix: str, name: str):
|
|
40
|
-
self.
|
|
33
|
+
class FilterMotor(StandardReadable):
|
|
34
|
+
def __init__(self, prefix: str, name: str = ""):
|
|
35
|
+
with self.add_children_as_readables():
|
|
36
|
+
self.user_setpoint = epics_signal_rw(p99StageSelections, prefix)
|
|
41
37
|
super().__init__(name=name)
|