dls-dodal 1.61.0__py3-none-any.whl → 1.63.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.61.0.dist-info → dls_dodal-1.63.0.dist-info}/METADATA +1 -1
- {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/RECORD +81 -73
- dls_dodal-1.63.0.dist-info/entry_points.txt +3 -0
- dodal/_version.py +2 -2
- dodal/beamlines/__init__.py +1 -0
- dodal/beamlines/adsim.py +5 -3
- dodal/beamlines/b21.py +3 -1
- dodal/beamlines/i02_2.py +32 -0
- dodal/beamlines/i03.py +9 -0
- dodal/beamlines/i04.py +1 -1
- dodal/beamlines/i09.py +10 -3
- dodal/beamlines/i09_1.py +9 -3
- dodal/beamlines/i10.py +7 -69
- dodal/beamlines/i10_1.py +35 -0
- dodal/beamlines/i10_optics.py +205 -0
- dodal/beamlines/i15_1.py +5 -5
- dodal/beamlines/i17.py +50 -1
- dodal/beamlines/i18.py +15 -9
- dodal/beamlines/i19_1.py +3 -3
- dodal/beamlines/i19_2.py +12 -2
- dodal/beamlines/i19_optics.py +4 -1
- dodal/beamlines/i24.py +3 -3
- dodal/cli.py +4 -4
- dodal/common/visit.py +4 -4
- dodal/devices/aperturescatterguard.py +6 -4
- dodal/devices/apple2_undulator.py +211 -114
- dodal/devices/attenuator/filter_selections.py +6 -6
- dodal/devices/common_dcm.py +62 -15
- dodal/devices/controllers.py +8 -6
- dodal/devices/current_amplifiers/femto.py +4 -4
- dodal/devices/current_amplifiers/sr570.py +3 -3
- dodal/devices/fast_grid_scan.py +97 -21
- dodal/devices/fast_shutter.py +69 -0
- dodal/devices/i02_1/fast_grid_scan.py +1 -1
- dodal/devices/i02_2/__init__.py +0 -0
- dodal/devices/i03/dcm.py +4 -2
- dodal/devices/i04/murko_results.py +35 -14
- dodal/devices/i09/__init__.py +1 -2
- dodal/devices/i10/__init__.py +29 -0
- dodal/devices/i10/diagnostics.py +37 -5
- dodal/devices/i10/i10_apple2.py +125 -229
- dodal/devices/i10/slits.py +38 -6
- dodal/devices/i15/dcm.py +6 -44
- dodal/devices/i17/__init__.py +0 -0
- dodal/devices/i17/i17_apple2.py +51 -0
- dodal/devices/i19/access_controlled/__init__.py +0 -0
- dodal/devices/i19/{shutter.py → access_controlled/shutter.py} +7 -4
- dodal/devices/i19/mapt_configuration.py +38 -0
- dodal/devices/i19/pin_col_stages.py +170 -0
- dodal/devices/i22/dcm.py +2 -2
- dodal/devices/i24/dcm.py +2 -2
- dodal/devices/oav/oav_detector.py +1 -1
- dodal/devices/oav/oav_parameters.py +4 -4
- dodal/devices/oav/oav_to_redis_forwarder.py +4 -4
- dodal/devices/oav/pin_image_recognition/__init__.py +3 -3
- dodal/devices/oav/pin_image_recognition/utils.py +1 -1
- dodal/devices/oav/snapshots/snapshot.py +1 -1
- dodal/devices/oav/snapshots/snapshot_image_processing.py +12 -12
- dodal/devices/oav/snapshots/snapshot_with_grid.py +1 -1
- dodal/devices/oav/utils.py +2 -2
- dodal/devices/pgm.py +3 -3
- dodal/devices/robot.py +5 -5
- dodal/devices/tetramm.py +9 -5
- dodal/devices/thawer.py +0 -4
- dodal/devices/v2f.py +2 -2
- dodal/devices/zebra/zebra_constants_mapping.py +2 -2
- dodal/devices/zocalo/__init__.py +4 -4
- dodal/devices/zocalo/zocalo_results.py +4 -4
- dodal/log.py +9 -9
- dodal/plan_stubs/motor_utils.py +4 -4
- dodal/plans/configure_arm_trigger_and_disarm_detector.py +29 -7
- dodal/plans/save_panda.py +7 -7
- dodal/plans/verify_undulator_gap.py +2 -2
- dls_dodal-1.61.0.dist-info/entry_points.txt +0 -3
- dodal/beamlines/i10-1.py +0 -25
- dodal/devices/i09/dcm.py +0 -26
- {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/WHEEL +0 -0
- {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/licenses/LICENSE +0 -0
- {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/top_level.txt +0 -0
- /dodal/devices/areadetector/plugins/{CAM.py → cam.py} +0 -0
- /dodal/devices/areadetector/plugins/{MJPG.py → mjpg.py} +0 -0
- /dodal/devices/i18/{KBMirror.py → kb_mirror.py} +0 -0
- /dodal/devices/i19/{blueapi_device.py → access_controlled/blueapi_device.py} +0 -0
- /dodal/devices/i19/{hutch_access.py → access_controlled/hutch_access.py} +0 -0
dodal/log.py
CHANGED
|
@@ -57,22 +57,22 @@ class CircularMemoryHandler(logging.Handler):
|
|
|
57
57
|
"""Loosely based on the MemoryHandler, which keeps a buffer and writes it when full
|
|
58
58
|
or when there is a record of specific level. This instead keeps a circular buffer
|
|
59
59
|
that always contains the last {capacity} number of messages, this is only flushed
|
|
60
|
-
when a log of specific {
|
|
60
|
+
when a log of specific {flush_level} comes in. On flush this buffer is then passed to
|
|
61
61
|
the {target} handler.
|
|
62
62
|
|
|
63
63
|
The CircularMemoryHandler becomes the owner of the target handler which will be closed
|
|
64
64
|
on close of this handler.
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
|
-
def __init__(self, capacity,
|
|
67
|
+
def __init__(self, capacity, flush_level=logging.ERROR, target=None):
|
|
68
68
|
logging.Handler.__init__(self)
|
|
69
69
|
self.buffer: deque[logging.LogRecord] = deque(maxlen=capacity)
|
|
70
|
-
self.
|
|
70
|
+
self.flush_level = flush_level
|
|
71
71
|
self.target = target
|
|
72
72
|
|
|
73
73
|
def emit(self, record):
|
|
74
74
|
self.buffer.append(record)
|
|
75
|
-
if record.levelno >= self.
|
|
75
|
+
if record.levelno >= self.flush_level:
|
|
76
76
|
self.flush()
|
|
77
77
|
|
|
78
78
|
def flush(self):
|
|
@@ -149,7 +149,7 @@ def set_up_graylog_handler(logger: Logger, host: str, port: int):
|
|
|
149
149
|
return graylog_handler
|
|
150
150
|
|
|
151
151
|
|
|
152
|
-
def
|
|
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
155
|
print(f"Logging to INFO file handler {path / filename}")
|
|
@@ -162,7 +162,7 @@ def set_up_INFO_file_handler(logger, path: Path, filename: str):
|
|
|
162
162
|
return file_handler
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
def
|
|
165
|
+
def set_up_debug_memory_handler(
|
|
166
166
|
logger: Logger, path: Path, filename: str, capacity: int
|
|
167
167
|
):
|
|
168
168
|
"""Set up a Memory handler which holds 200k lines, and writes them to an hourly
|
|
@@ -178,7 +178,7 @@ def set_up_DEBUG_memory_handler(
|
|
|
178
178
|
file_handler.setFormatter(DEFAULT_FORMATTER)
|
|
179
179
|
memory_handler = CircularMemoryHandler(
|
|
180
180
|
capacity=capacity,
|
|
181
|
-
|
|
181
|
+
flush_level=logging.ERROR,
|
|
182
182
|
target=file_handler,
|
|
183
183
|
)
|
|
184
184
|
memory_handler.setLevel(logging.DEBUG)
|
|
@@ -223,8 +223,8 @@ def set_up_all_logging_handlers(
|
|
|
223
223
|
"graylog_handler": set_up_graylog_handler(
|
|
224
224
|
logger, *get_graylog_configuration(dev_mode, graylog_port)
|
|
225
225
|
),
|
|
226
|
-
"info_file_handler":
|
|
227
|
-
"debug_memory_handler":
|
|
226
|
+
"info_file_handler": set_up_info_file_handler(logger, logging_path, filename),
|
|
227
|
+
"debug_memory_handler": set_up_debug_memory_handler(
|
|
228
228
|
logger, debug_logging_path or logging_path, filename, error_log_buffer_lines
|
|
229
229
|
),
|
|
230
230
|
}
|
dodal/plan_stubs/motor_utils.py
CHANGED
|
@@ -9,7 +9,7 @@ from ophyd_async.core import Device
|
|
|
9
9
|
from ophyd_async.epics.motor import Motor
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class
|
|
12
|
+
class MoveTooLargeError(Exception):
|
|
13
13
|
def __init__(
|
|
14
14
|
self,
|
|
15
15
|
axis: Motor,
|
|
@@ -29,14 +29,14 @@ def check_and_cache_values(
|
|
|
29
29
|
maximum_move: float,
|
|
30
30
|
) -> Generator[Msg, Any, dict[Motor, float]]:
|
|
31
31
|
"""Caches the positions of all Motors on specified device if they are within
|
|
32
|
-
smallest_move of home_position. Throws
|
|
32
|
+
smallest_move of home_position. Throws MoveTooLargeError if they are outside maximum_move
|
|
33
33
|
of the home_position
|
|
34
34
|
"""
|
|
35
35
|
positions = {}
|
|
36
36
|
for axis, new_position in devices_and_positions.items():
|
|
37
37
|
position = yield from bps.rd(axis)
|
|
38
38
|
if abs(position - new_position) > maximum_move:
|
|
39
|
-
raise
|
|
39
|
+
raise MoveTooLargeError(axis, maximum_move, position)
|
|
40
40
|
if abs(position - new_position) > smallest_move:
|
|
41
41
|
positions[axis] = position
|
|
42
42
|
return positions
|
|
@@ -68,7 +68,7 @@ def move_and_reset_wrapper(
|
|
|
68
68
|
) -> MsgGenerator:
|
|
69
69
|
"""Wrapper that does the following:
|
|
70
70
|
1. Caches the positions of all Motors on device
|
|
71
|
-
2. Throws a
|
|
71
|
+
2. Throws a MoveTooLargeError exception if any positions are maximum_move away from home_position
|
|
72
72
|
2. Moves any motor that is more than smallest_move away from the home_position to home_position
|
|
73
73
|
3. Runs the specified plan
|
|
74
74
|
4. Moves all motors back to their cached positions
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import time
|
|
2
|
+
from pathlib import PurePath
|
|
2
3
|
|
|
3
4
|
import bluesky.plan_stubs as bps
|
|
4
5
|
from bluesky import preprocessors as bpp
|
|
5
6
|
from bluesky.run_engine import RunEngine
|
|
6
|
-
from ophyd_async.core import
|
|
7
|
+
from ophyd_async.core import (
|
|
8
|
+
DetectorTrigger,
|
|
9
|
+
StaticFilenameProvider,
|
|
10
|
+
StaticPathProvider,
|
|
11
|
+
TriggerInfo,
|
|
12
|
+
)
|
|
7
13
|
from ophyd_async.fastcs.eiger import EigerDetector
|
|
8
14
|
|
|
9
|
-
from dodal.beamlines.i03 import fastcs_eiger
|
|
15
|
+
from dodal.beamlines.i03 import fastcs_eiger, set_path_provider
|
|
10
16
|
from dodal.devices.detector import DetectorParams
|
|
11
17
|
from dodal.log import LOGGER, do_default_logging_setup
|
|
12
18
|
|
|
@@ -28,9 +34,17 @@ def configure_arm_trigger_and_disarm_detector(
|
|
|
28
34
|
yield from change_roi_mode(eiger, detector_params, wait=True)
|
|
29
35
|
LOGGER.info(f"Changing ROI Mode: {time.time() - start}s")
|
|
30
36
|
start = time.time()
|
|
31
|
-
yield from bps.abs_set(eiger.odin.num_frames_chunks, 1)
|
|
37
|
+
yield from bps.abs_set(eiger.odin.num_frames_chunks, 1, wait=True)
|
|
32
38
|
LOGGER.info(f"Setting # of Frame Chunks: {time.time() - start}s")
|
|
33
39
|
start = time.time()
|
|
40
|
+
yield from bps.abs_set(
|
|
41
|
+
eiger.drv.detector.photon_energy, detector_params.expected_energy_ev, wait=True
|
|
42
|
+
)
|
|
43
|
+
LOGGER.info(f"Setting Photon Energy: {time.time() - start}s")
|
|
44
|
+
start = time.time()
|
|
45
|
+
yield from bps.abs_set(eiger.drv.detector.ntrigger, 1, wait=True)
|
|
46
|
+
LOGGER.info(f"Setting Number of Triggers: {time.time() - start}s")
|
|
47
|
+
start = time.time()
|
|
34
48
|
yield from set_mx_settings_pvs(eiger, detector_params, wait=True)
|
|
35
49
|
LOGGER.info(f"Setting MX PVs: {time.time() - start}s")
|
|
36
50
|
start = time.time()
|
|
@@ -40,7 +54,7 @@ def configure_arm_trigger_and_disarm_detector(
|
|
|
40
54
|
yield from bps.kickoff(eiger, wait=True)
|
|
41
55
|
LOGGER.info(f"Kickoff Eiger: {time.time() - start}s")
|
|
42
56
|
start = time.time()
|
|
43
|
-
yield from bps.trigger(eiger.drv.detector.trigger)
|
|
57
|
+
yield from bps.trigger(eiger.drv.detector.trigger, wait=True)
|
|
44
58
|
LOGGER.info(f"Triggering Eiger: {time.time() - start}s")
|
|
45
59
|
start = time.time()
|
|
46
60
|
yield from bps.complete(eiger, wait=True)
|
|
@@ -82,7 +96,7 @@ def change_roi_mode(
|
|
|
82
96
|
|
|
83
97
|
yield from bps.abs_set(
|
|
84
98
|
eiger.drv.detector.roi_mode,
|
|
85
|
-
|
|
99
|
+
"4M" if detector_params.use_roi_mode else "disabled",
|
|
86
100
|
group=group,
|
|
87
101
|
)
|
|
88
102
|
yield from bps.abs_set(
|
|
@@ -141,10 +155,18 @@ def set_mx_settings_pvs(
|
|
|
141
155
|
|
|
142
156
|
|
|
143
157
|
if __name__ == "__main__":
|
|
144
|
-
|
|
158
|
+
run_engine = RunEngine()
|
|
145
159
|
do_default_logging_setup()
|
|
160
|
+
|
|
161
|
+
path_provider = StaticPathProvider(
|
|
162
|
+
StaticFilenameProvider("eiger_test_file12.h5"),
|
|
163
|
+
PurePath("/dls/i03/data/2025/cm40607-2/test_new_eiger/"),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
set_path_provider(path_provider)
|
|
167
|
+
|
|
146
168
|
eiger = fastcs_eiger(connect_immediately=True)
|
|
147
|
-
|
|
169
|
+
run_engine(
|
|
148
170
|
configure_arm_trigger_and_disarm_detector(
|
|
149
171
|
eiger=eiger,
|
|
150
172
|
detector_params=DetectorParams(
|
dodal/plans/save_panda.py
CHANGED
|
@@ -15,7 +15,7 @@ from dodal.beamlines import module_name_for_beamline
|
|
|
15
15
|
from dodal.utils import make_device
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def main(argv: list[str]):
|
|
18
|
+
def main(argv: list[str] | None = None):
|
|
19
19
|
"""CLI Utility to save the panda configuration."""
|
|
20
20
|
parser = ArgumentParser(description="Save an ophyd_async panda to yaml")
|
|
21
21
|
parser.add_argument(
|
|
@@ -39,7 +39,7 @@ def main(argv: list[str]):
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
# this exit()s with message/help unless args parsed successfully
|
|
42
|
-
args = parser.parse_args(argv
|
|
42
|
+
args = parser.parse_args(argv)
|
|
43
43
|
|
|
44
44
|
beamline = args.beamline
|
|
45
45
|
device_name = args.device_name
|
|
@@ -71,7 +71,7 @@ def main(argv: list[str]):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def _save_panda(beamline, device_name, output_directory, file_name):
|
|
74
|
-
|
|
74
|
+
run_engine = RunEngine()
|
|
75
75
|
print("Creating devices...")
|
|
76
76
|
module_name = module_name_for_beamline(beamline)
|
|
77
77
|
try:
|
|
@@ -86,18 +86,18 @@ def _save_panda(beamline, device_name, output_directory, file_name):
|
|
|
86
86
|
print(
|
|
87
87
|
f"Saving to {output_directory}/{file_name} from {device_name} on {beamline}..."
|
|
88
88
|
)
|
|
89
|
-
_save_panda_to_yaml(
|
|
89
|
+
_save_panda_to_yaml(run_engine, cast(Device, panda), file_name, output_directory)
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
def _save_panda_to_yaml(
|
|
93
|
-
|
|
93
|
+
run_engine: RunEngine, panda: Device, file_name: str, output_directory: str
|
|
94
94
|
):
|
|
95
95
|
def save_to_file():
|
|
96
96
|
provider = YamlSettingsProvider(output_directory)
|
|
97
97
|
yield from store_settings(provider, file_name, panda)
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
run_engine(save_to_file())
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
if __name__ == "__main__": # pragma: no cover
|
|
103
|
-
sys.exit(main(sys.argv))
|
|
103
|
+
sys.exit(main(sys.argv[1:]))
|
|
@@ -2,14 +2,14 @@ from typing import Protocol, runtime_checkable
|
|
|
2
2
|
|
|
3
3
|
from bluesky import plan_stubs as bps
|
|
4
4
|
|
|
5
|
-
from dodal.devices.common_dcm import
|
|
5
|
+
from dodal.devices.common_dcm import DoubleCrystalMonochromatorBase
|
|
6
6
|
from dodal.devices.undulator import Undulator
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@runtime_checkable
|
|
10
10
|
class CheckUndulatorDevices(Protocol):
|
|
11
11
|
undulator: Undulator
|
|
12
|
-
dcm:
|
|
12
|
+
dcm: DoubleCrystalMonochromatorBase
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def verify_undulator_gap(devices: CheckUndulatorDevices):
|
dodal/beamlines/i10-1.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from dodal.common.beamlines.beamline_utils import (
|
|
2
|
-
device_factory,
|
|
3
|
-
)
|
|
4
|
-
from dodal.common.beamlines.beamline_utils import set_beamline as set_utils_beamline
|
|
5
|
-
from dodal.devices.synchrotron import Synchrotron
|
|
6
|
-
from dodal.devices.temperture_controller import Lakeshore336
|
|
7
|
-
from dodal.log import set_beamline as set_log_beamline
|
|
8
|
-
from dodal.utils import BeamlinePrefix, get_beamline_name
|
|
9
|
-
|
|
10
|
-
BL = get_beamline_name("i10-1")
|
|
11
|
-
PREFIX = BeamlinePrefix(BL, suffix="J")
|
|
12
|
-
set_log_beamline(BL)
|
|
13
|
-
set_utils_beamline(BL)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@device_factory()
|
|
17
|
-
def synchrotron() -> Synchrotron:
|
|
18
|
-
return Synchrotron()
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@device_factory()
|
|
22
|
-
def em_temperature_controller() -> Lakeshore336:
|
|
23
|
-
return Lakeshore336(
|
|
24
|
-
prefix=f"{PREFIX.beamline_prefix}-EA-TCTRL-41:",
|
|
25
|
-
)
|
dodal/devices/i09/dcm.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from ophyd_async.core import derived_signal_r
|
|
2
|
-
|
|
3
|
-
from dodal.devices.common_dcm import BaseDCM, PitchAndRollCrystal, StationaryCrystal
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class DCM(BaseDCM[PitchAndRollCrystal, StationaryCrystal]):
|
|
7
|
-
"""
|
|
8
|
-
I09 double crystal monochromator (DCM), used to select the energy of the beam.
|
|
9
|
-
Differences:
|
|
10
|
-
|
|
11
|
-
1. Can provide energy in eV via dcm.energy_in_ev read signal
|
|
12
|
-
|
|
13
|
-
This DCM is available on i09 and i09_1 endstations.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, prefix: str, name: str = "") -> None:
|
|
17
|
-
super().__init__(prefix, PitchAndRollCrystal, StationaryCrystal, name)
|
|
18
|
-
self.energy_in_ev = derived_signal_r(
|
|
19
|
-
self._convert_keV_to_eV, energy_signal=self.energy_in_kev.user_readback
|
|
20
|
-
)
|
|
21
|
-
# Set name so that new child signals get correct name
|
|
22
|
-
# need to do it until https://github.com/bluesky/ophyd-async/pull/899 merged
|
|
23
|
-
self.set_name(self.name)
|
|
24
|
-
|
|
25
|
-
def _convert_keV_to_eV(self, energy_signal: float) -> float:
|
|
26
|
-
return energy_signal * 1000
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|