dls-dodal 1.36.3__py3-none-any.whl → 1.37.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.36.3.dist-info → dls_dodal-1.37.0.dist-info}/METADATA +3 -3
- {dls_dodal-1.36.3.dist-info → dls_dodal-1.37.0.dist-info}/RECORD +43 -29
- {dls_dodal-1.36.3.dist-info → dls_dodal-1.37.0.dist-info}/WHEEL +1 -1
- dodal/_version.py +2 -2
- dodal/beamlines/i02_1.py +37 -0
- dodal/beamlines/i03.py +20 -3
- dodal/beamlines/i04.py +3 -3
- dodal/beamlines/i10.py +105 -0
- dodal/beamlines/i22.py +15 -0
- dodal/beamlines/i24.py +1 -1
- dodal/beamlines/p99.py +6 -2
- dodal/common/crystal_metadata.py +3 -3
- dodal/common/udc_directory_provider.py +3 -1
- dodal/devices/aperturescatterguard.py +3 -0
- dodal/devices/{attenuator.py → attenuator/attenuator.py} +29 -1
- dodal/devices/attenuator/filter.py +11 -0
- dodal/devices/attenuator/filter_selections.py +72 -0
- dodal/devices/bimorph_mirror.py +151 -0
- dodal/devices/current_amplifiers/__init__.py +34 -0
- dodal/devices/current_amplifiers/current_amplifier.py +103 -0
- dodal/devices/current_amplifiers/current_amplifier_detector.py +109 -0
- dodal/devices/current_amplifiers/femto.py +143 -0
- dodal/devices/current_amplifiers/sr570.py +214 -0
- dodal/devices/current_amplifiers/struck_scaler_counter.py +79 -0
- dodal/devices/detector/det_dim_constants.py +15 -0
- dodal/devices/eiger_odin.py +3 -3
- dodal/devices/fast_grid_scan.py +8 -3
- dodal/devices/i03/beamstop.py +85 -0
- dodal/devices/i04/transfocator.py +67 -53
- dodal/devices/i10/rasor/rasor_current_amp.py +72 -0
- dodal/devices/i10/rasor/rasor_motors.py +62 -0
- dodal/devices/i10/rasor/rasor_scaler_cards.py +12 -0
- dodal/devices/p99/sample_stage.py +2 -28
- dodal/devices/robot.py +2 -2
- dodal/devices/undulator_dcm.py +9 -11
- dodal/devices/zebra.py +6 -1
- dodal/devices/zocalo/zocalo_interaction.py +2 -1
- dodal/devices/zocalo/zocalo_results.py +22 -2
- dodal/log.py +2 -2
- dodal/plans/wrapped.py +3 -3
- {dls_dodal-1.36.3.dist-info → dls_dodal-1.37.0.dist-info}/LICENSE +0 -0
- {dls_dodal-1.36.3.dist-info → dls_dodal-1.37.0.dist-info}/entry_points.txt +0 -0
- {dls_dodal-1.36.3.dist-info → dls_dodal-1.37.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from ophyd_async.core import StandardReadable
|
|
2
|
+
from ophyd_async.epics.motor import Motor
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PinHole(StandardReadable):
|
|
6
|
+
"Two motors stage for rasor pinhole"
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
prefix: str,
|
|
11
|
+
name: str = "",
|
|
12
|
+
):
|
|
13
|
+
with self.add_children_as_readables():
|
|
14
|
+
self.x = Motor(prefix + "X")
|
|
15
|
+
self.y = Motor(prefix + "Y")
|
|
16
|
+
super().__init__(name=name)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Diffractometer(StandardReadable):
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
prefix: str,
|
|
23
|
+
name: str = "",
|
|
24
|
+
):
|
|
25
|
+
with self.add_children_as_readables():
|
|
26
|
+
self.tth = Motor(prefix + "TWOTHETA")
|
|
27
|
+
self.th = Motor(prefix + "THETA")
|
|
28
|
+
self.chi = Motor(prefix + "CHI")
|
|
29
|
+
self.chamber_x = Motor(prefix + "X")
|
|
30
|
+
self.alpha = Motor(prefix + "ALPHA")
|
|
31
|
+
super().__init__(name=name)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DetSlits(StandardReadable):
|
|
35
|
+
"Detector slits"
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
prefix: str,
|
|
40
|
+
name: str = "",
|
|
41
|
+
):
|
|
42
|
+
with self.add_children_as_readables():
|
|
43
|
+
self.upstream = Motor(prefix + "1:TRANS")
|
|
44
|
+
self.downstream = Motor(prefix + "2:TRANS")
|
|
45
|
+
super().__init__(name=name)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class PaStage(StandardReadable):
|
|
49
|
+
"Rasor detector stage"
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
prefix: str,
|
|
54
|
+
name: str = "",
|
|
55
|
+
):
|
|
56
|
+
with self.add_children_as_readables():
|
|
57
|
+
self.ttp = Motor(prefix + "TWOTHETA")
|
|
58
|
+
self.thp = Motor(prefix + "THETA")
|
|
59
|
+
self.py = Motor(prefix + "Y")
|
|
60
|
+
self.pz = Motor(prefix + "Z")
|
|
61
|
+
self.eta = Motor(prefix + "ETA")
|
|
62
|
+
super().__init__(name=name)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from ophyd_async.core import Device
|
|
2
|
+
|
|
3
|
+
from dodal.devices.current_amplifiers import StruckScaler
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RasorScalerCard1(Device):
|
|
7
|
+
def __init__(self, prefix, name: str = "") -> None:
|
|
8
|
+
self.mon = StruckScaler(prefix=prefix, suffix=".16")
|
|
9
|
+
self.det = StruckScaler(prefix=prefix, suffix=".17")
|
|
10
|
+
self.fluo = StruckScaler(prefix=prefix, suffix=".18")
|
|
11
|
+
self.drain = StruckScaler(prefix=prefix, suffix=".19")
|
|
12
|
+
super().__init__(name)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from ophyd_async.core import StandardReadable
|
|
2
|
-
from ophyd_async.epics.core import
|
|
1
|
+
from ophyd_async.core import StandardReadable
|
|
2
|
+
from ophyd_async.epics.core import epics_signal_rw_rbv
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class SampleAngleStage(StandardReadable):
|
|
@@ -9,29 +9,3 @@ class SampleAngleStage(StandardReadable):
|
|
|
9
9
|
self.roll = epics_signal_rw_rbv(float, prefix + "WRITEROLL", ":RBV")
|
|
10
10
|
self.pitch = epics_signal_rw_rbv(float, prefix + "WRITEPITCH", ":RBV")
|
|
11
11
|
super().__init__(name=name)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class p99StageSelections(SubsetEnum):
|
|
15
|
-
EMPTY = "Empty"
|
|
16
|
-
MN5UM = "Mn 5um"
|
|
17
|
-
FE = "Fe (empty)"
|
|
18
|
-
CO5UM = "Co 5um"
|
|
19
|
-
NI5UM = "Ni 5um"
|
|
20
|
-
CU5UM = "Cu 5um"
|
|
21
|
-
ZN5UM = "Zn 5um"
|
|
22
|
-
ZR = "Zr (empty)"
|
|
23
|
-
MO = "Mo (empty)"
|
|
24
|
-
RH = "Rh (empty)"
|
|
25
|
-
PD = "Pd (empty)"
|
|
26
|
-
AG = "Ag (empty)"
|
|
27
|
-
CD25UM = "Cd 25um"
|
|
28
|
-
W = "W (empty)"
|
|
29
|
-
PT = "Pt (empty)"
|
|
30
|
-
USER = "User"
|
|
31
|
-
|
|
32
|
-
|
|
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)
|
|
37
|
-
super().__init__(name=name)
|
dodal/devices/robot.py
CHANGED
|
@@ -70,8 +70,8 @@ class BartRobot(StandardReadable, Movable):
|
|
|
70
70
|
self.program_running = epics_signal_r(bool, prefix + "PROGRAM_RUNNING")
|
|
71
71
|
self.program_name = epics_signal_r(str, prefix + "PROGRAM_NAME")
|
|
72
72
|
self.error_str = epics_signal_r(str, prefix + "PRG_ERR_MSG")
|
|
73
|
-
|
|
74
|
-
self.
|
|
73
|
+
self.error_code = epics_signal_r(int, prefix + "PRG_ERR_CODE")
|
|
74
|
+
self.reset = epics_signal_x(prefix + "RESET.PROC")
|
|
75
75
|
super().__init__(name=name)
|
|
76
76
|
|
|
77
77
|
async def pin_mounted_or_no_pin_found(self):
|
dodal/devices/undulator_dcm.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
|
|
3
3
|
from bluesky.protocols import Movable
|
|
4
|
-
from ophyd_async.core import AsyncStatus, StandardReadable
|
|
4
|
+
from ophyd_async.core import AsyncStatus, Reference, StandardReadable
|
|
5
5
|
|
|
6
6
|
from dodal.common.beamlines.beamline_parameters import get_beamline_parameters
|
|
7
7
|
|
|
@@ -33,12 +33,8 @@ class UndulatorDCM(StandardReadable, Movable):
|
|
|
33
33
|
prefix: str = "",
|
|
34
34
|
name: str = "",
|
|
35
35
|
):
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# Attributes are set after super call so they are not renamed to
|
|
39
|
-
# <name>-undulator, etc.
|
|
40
|
-
self.undulator = undulator
|
|
41
|
-
self.dcm = dcm
|
|
36
|
+
self.undulator_ref = Reference(undulator)
|
|
37
|
+
self.dcm_ref = Reference(dcm)
|
|
42
38
|
|
|
43
39
|
# These attributes are just used by hyperion for lookup purposes
|
|
44
40
|
self.pitch_energy_table_path = (
|
|
@@ -53,13 +49,15 @@ class UndulatorDCM(StandardReadable, Movable):
|
|
|
53
49
|
daq_configuration_path + "/domain/beamlineParameters"
|
|
54
50
|
)["DCM_Perp_Offset_FIXED"]
|
|
55
51
|
|
|
52
|
+
super().__init__(name)
|
|
53
|
+
|
|
56
54
|
@AsyncStatus.wrap
|
|
57
55
|
async def set(self, value: float):
|
|
58
|
-
await self.
|
|
56
|
+
await self.undulator_ref().raise_if_not_enabled()
|
|
59
57
|
await asyncio.gather(
|
|
60
|
-
self.
|
|
61
|
-
self.
|
|
58
|
+
self.dcm_ref().energy_in_kev.set(value, timeout=ENERGY_TIMEOUT_S),
|
|
59
|
+
self.undulator_ref().set(value),
|
|
62
60
|
)
|
|
63
61
|
# DCM Perp pitch
|
|
64
62
|
LOGGER.info(f"Adjusting DCM offset to {self.dcm_fixed_offset_mm} mm")
|
|
65
|
-
await self.
|
|
63
|
+
await self.dcm_ref().offset_in_mm.set(self.dcm_fixed_offset_mm)
|
dodal/devices/zebra.py
CHANGED
|
@@ -81,6 +81,11 @@ class I24Axes:
|
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
class RotationDirection(StrictEnum):
|
|
84
|
+
"""
|
|
85
|
+
Defines for a swept angle whether the scan width (sweep) is to be added or subtracted from
|
|
86
|
+
the initial angle to obtain the final angle.
|
|
87
|
+
"""
|
|
88
|
+
|
|
84
89
|
POSITIVE = "Positive"
|
|
85
90
|
NEGATIVE = "Negative"
|
|
86
91
|
|
|
@@ -281,7 +286,7 @@ class LogicGateConfiguration:
|
|
|
281
286
|
for input, (source, invert) in enumerate(
|
|
282
287
|
zip(self.sources, self.invert, strict=False)
|
|
283
288
|
):
|
|
284
|
-
input_strings.append(f"INP{input+1}={'!' if invert else ''}{source}")
|
|
289
|
+
input_strings.append(f"INP{input + 1}={'!' if invert else ''}{source}")
|
|
285
290
|
|
|
286
291
|
return ", ".join(input_strings)
|
|
287
292
|
|
|
@@ -55,7 +55,8 @@ class ZocaloTrigger:
|
|
|
55
55
|
intended to be used in bluesky callback classes. To get results from zocalo back
|
|
56
56
|
into a plan, use the ZocaloResults ophyd device.
|
|
57
57
|
|
|
58
|
-
see https://github.
|
|
58
|
+
see https://diamondlightsource.github.io/dodal/main/how-to/zocalo.html for
|
|
59
|
+
more information about zocalo."""
|
|
59
60
|
|
|
60
61
|
def __init__(self, environment: str = ZOCALO_ENV):
|
|
61
62
|
self.zocalo_environment: str = environment
|
|
@@ -11,7 +11,7 @@ import workflows.recipe
|
|
|
11
11
|
import workflows.transport
|
|
12
12
|
from bluesky.protocols import Triggerable
|
|
13
13
|
from bluesky.utils import Msg
|
|
14
|
-
from deepdiff import DeepDiff
|
|
14
|
+
from deepdiff.diff import DeepDiff
|
|
15
15
|
from ophyd_async.core import (
|
|
16
16
|
Array1D,
|
|
17
17
|
AsyncStatus,
|
|
@@ -53,6 +53,26 @@ ZOCALO_STAGE_GROUP = "clear zocalo queue"
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
class XrcResult(TypedDict):
|
|
56
|
+
"""
|
|
57
|
+
Information about a diffracting centre.
|
|
58
|
+
|
|
59
|
+
NOTE: the coordinate systems of centre_of_mass and max_voxel/bounding_box are not
|
|
60
|
+
the same; centre_of_mass coordinates are continuous whereas max_voxel and bounding_box
|
|
61
|
+
coordinates are discrete.
|
|
62
|
+
Attributes:
|
|
63
|
+
centre_of_mass: The position of the centre of mass of the crystal, adjusted so that
|
|
64
|
+
grid box centres lie on integer grid coordinates, such that a 1x1x1 crystal detected in
|
|
65
|
+
a single grid box at 0, 0, 0, has c.o.m. of 0, 0, 0, not 0.5, 0.5, 0.5
|
|
66
|
+
max_voxel: Position of the voxel with the maximum count, in integer coordinates
|
|
67
|
+
max_count: max count achieved in a single voxel for the crystal
|
|
68
|
+
n_voxels: Number of voxels (aka grid boxes) in the diffracting centre
|
|
69
|
+
total_count: Total of above-threshold spot counts in the labelled voxels
|
|
70
|
+
bounding_box: The rectangular prism that bounds the crystal, expressed
|
|
71
|
+
as the volume of whole boxes as a half-open range i.e such that
|
|
72
|
+
p1 = (x1, y1, z1) <= p < p2 = (x2, y2, z2) and
|
|
73
|
+
p2 - p1 gives the dimensions in whole voxels.
|
|
74
|
+
"""
|
|
75
|
+
|
|
56
76
|
centre_of_mass: list[float]
|
|
57
77
|
max_voxel: list[int]
|
|
58
78
|
max_count: int
|
|
@@ -133,7 +153,7 @@ class ZocaloResults(StandardReadable, Triggerable):
|
|
|
133
153
|
self.use_cpu_and_gpu = use_cpu_and_gpu
|
|
134
154
|
|
|
135
155
|
self.centre_of_mass, self._com_setter = soft_signal_r_and_setter(
|
|
136
|
-
Array1D[np.
|
|
156
|
+
Array1D[np.float64], name="centre_of_mass"
|
|
137
157
|
)
|
|
138
158
|
self.bounding_box, self._bounding_box_setter = soft_signal_r_and_setter(
|
|
139
159
|
Array1D[np.uint64], name="bounding_box"
|
dodal/log.py
CHANGED
|
@@ -152,7 +152,7 @@ def set_up_graylog_handler(logger: Logger, host: str, port: int):
|
|
|
152
152
|
def set_up_INFO_file_handler(logger, path: Path, filename: str):
|
|
153
153
|
"""Set up a file handler for the logger, at INFO level, which will keep 30 days
|
|
154
154
|
of logs, rotating once per day. Creates the directory if necessary."""
|
|
155
|
-
print(f"Logging to INFO file handler {path/filename}")
|
|
155
|
+
print(f"Logging to INFO file handler {path / filename}")
|
|
156
156
|
path.mkdir(parents=True, exist_ok=True)
|
|
157
157
|
file_handler = TimedRotatingFileHandler(
|
|
158
158
|
filename=path / filename, when="MIDNIGHT", backupCount=INFO_LOG_DAYS
|
|
@@ -169,7 +169,7 @@ def set_up_DEBUG_memory_handler(
|
|
|
169
169
|
log file when it sees a message of severity ERROR. Creates the directory if
|
|
170
170
|
necessary"""
|
|
171
171
|
debug_path = path / "debug"
|
|
172
|
-
print(f"Logging to DEBUG handler {debug_path/filename}")
|
|
172
|
+
print(f"Logging to DEBUG handler {debug_path / filename}")
|
|
173
173
|
debug_path.mkdir(parents=True, exist_ok=True)
|
|
174
174
|
file_handler = TimedRotatingFileHandler(
|
|
175
175
|
filename=debug_path / filename, when="H", backupCount=DEBUG_LOG_FILES_TO_KEEP
|
dodal/plans/wrapped.py
CHANGED
|
@@ -49,9 +49,9 @@ def count(
|
|
|
49
49
|
Wraps bluesky.plans.count(det, num, delay, md=metadata) exposing only serializable
|
|
50
50
|
parameters and metadata."""
|
|
51
51
|
if isinstance(delay, Sequence):
|
|
52
|
-
assert (
|
|
53
|
-
|
|
54
|
-
)
|
|
52
|
+
assert len(delay) == num - 1, (
|
|
53
|
+
f"Number of delays given must be {num - 1}: was given {len(delay)}"
|
|
54
|
+
)
|
|
55
55
|
metadata = metadata or {}
|
|
56
56
|
metadata["shape"] = (num,)
|
|
57
57
|
yield from bp.count(tuple(detectors), num, delay=delay, md=metadata)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|