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.
Files changed (84) hide show
  1. {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/METADATA +1 -1
  2. {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/RECORD +81 -73
  3. dls_dodal-1.63.0.dist-info/entry_points.txt +3 -0
  4. dodal/_version.py +2 -2
  5. dodal/beamlines/__init__.py +1 -0
  6. dodal/beamlines/adsim.py +5 -3
  7. dodal/beamlines/b21.py +3 -1
  8. dodal/beamlines/i02_2.py +32 -0
  9. dodal/beamlines/i03.py +9 -0
  10. dodal/beamlines/i04.py +1 -1
  11. dodal/beamlines/i09.py +10 -3
  12. dodal/beamlines/i09_1.py +9 -3
  13. dodal/beamlines/i10.py +7 -69
  14. dodal/beamlines/i10_1.py +35 -0
  15. dodal/beamlines/i10_optics.py +205 -0
  16. dodal/beamlines/i15_1.py +5 -5
  17. dodal/beamlines/i17.py +50 -1
  18. dodal/beamlines/i18.py +15 -9
  19. dodal/beamlines/i19_1.py +3 -3
  20. dodal/beamlines/i19_2.py +12 -2
  21. dodal/beamlines/i19_optics.py +4 -1
  22. dodal/beamlines/i24.py +3 -3
  23. dodal/cli.py +4 -4
  24. dodal/common/visit.py +4 -4
  25. dodal/devices/aperturescatterguard.py +6 -4
  26. dodal/devices/apple2_undulator.py +211 -114
  27. dodal/devices/attenuator/filter_selections.py +6 -6
  28. dodal/devices/common_dcm.py +62 -15
  29. dodal/devices/controllers.py +8 -6
  30. dodal/devices/current_amplifiers/femto.py +4 -4
  31. dodal/devices/current_amplifiers/sr570.py +3 -3
  32. dodal/devices/fast_grid_scan.py +97 -21
  33. dodal/devices/fast_shutter.py +69 -0
  34. dodal/devices/i02_1/fast_grid_scan.py +1 -1
  35. dodal/devices/i02_2/__init__.py +0 -0
  36. dodal/devices/i03/dcm.py +4 -2
  37. dodal/devices/i04/murko_results.py +35 -14
  38. dodal/devices/i09/__init__.py +1 -2
  39. dodal/devices/i10/__init__.py +29 -0
  40. dodal/devices/i10/diagnostics.py +37 -5
  41. dodal/devices/i10/i10_apple2.py +125 -229
  42. dodal/devices/i10/slits.py +38 -6
  43. dodal/devices/i15/dcm.py +6 -44
  44. dodal/devices/i17/__init__.py +0 -0
  45. dodal/devices/i17/i17_apple2.py +51 -0
  46. dodal/devices/i19/access_controlled/__init__.py +0 -0
  47. dodal/devices/i19/{shutter.py → access_controlled/shutter.py} +7 -4
  48. dodal/devices/i19/mapt_configuration.py +38 -0
  49. dodal/devices/i19/pin_col_stages.py +170 -0
  50. dodal/devices/i22/dcm.py +2 -2
  51. dodal/devices/i24/dcm.py +2 -2
  52. dodal/devices/oav/oav_detector.py +1 -1
  53. dodal/devices/oav/oav_parameters.py +4 -4
  54. dodal/devices/oav/oav_to_redis_forwarder.py +4 -4
  55. dodal/devices/oav/pin_image_recognition/__init__.py +3 -3
  56. dodal/devices/oav/pin_image_recognition/utils.py +1 -1
  57. dodal/devices/oav/snapshots/snapshot.py +1 -1
  58. dodal/devices/oav/snapshots/snapshot_image_processing.py +12 -12
  59. dodal/devices/oav/snapshots/snapshot_with_grid.py +1 -1
  60. dodal/devices/oav/utils.py +2 -2
  61. dodal/devices/pgm.py +3 -3
  62. dodal/devices/robot.py +5 -5
  63. dodal/devices/tetramm.py +9 -5
  64. dodal/devices/thawer.py +0 -4
  65. dodal/devices/v2f.py +2 -2
  66. dodal/devices/zebra/zebra_constants_mapping.py +2 -2
  67. dodal/devices/zocalo/__init__.py +4 -4
  68. dodal/devices/zocalo/zocalo_results.py +4 -4
  69. dodal/log.py +9 -9
  70. dodal/plan_stubs/motor_utils.py +4 -4
  71. dodal/plans/configure_arm_trigger_and_disarm_detector.py +29 -7
  72. dodal/plans/save_panda.py +7 -7
  73. dodal/plans/verify_undulator_gap.py +2 -2
  74. dls_dodal-1.61.0.dist-info/entry_points.txt +0 -3
  75. dodal/beamlines/i10-1.py +0 -25
  76. dodal/devices/i09/dcm.py +0 -26
  77. {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/WHEEL +0 -0
  78. {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/licenses/LICENSE +0 -0
  79. {dls_dodal-1.61.0.dist-info → dls_dodal-1.63.0.dist-info}/top_level.txt +0 -0
  80. /dodal/devices/areadetector/plugins/{CAM.py → cam.py} +0 -0
  81. /dodal/devices/areadetector/plugins/{MJPG.py → mjpg.py} +0 -0
  82. /dodal/devices/i18/{KBMirror.py → kb_mirror.py} +0 -0
  83. /dodal/devices/i19/{blueapi_device.py → access_controlled/blueapi_device.py} +0 -0
  84. /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 {flushLevel} comes in. On flush this buffer is then passed to
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, flushLevel=logging.ERROR, target=None):
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.flushLevel = flushLevel
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.flushLevel:
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 set_up_INFO_file_handler(logger, path: Path, filename: str):
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 set_up_DEBUG_memory_handler(
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
- flushLevel=logging.ERROR,
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": set_up_INFO_file_handler(logger, logging_path, filename),
227
- "debug_memory_handler": set_up_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
  }
@@ -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 MoveTooLarge(Exception):
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 MoveTooLarge if they are outside maximum_move
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 MoveTooLarge(axis, maximum_move, position)
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 MoveTooLarge exception if any positions are maximum_move away from home_position
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 DetectorTrigger, TriggerInfo
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) # type: ignore
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
- 1 if detector_params.use_roi_mode else 0,
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
- RE = RunEngine()
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
- RE(
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[1:])
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
- RE = RunEngine()
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(RE, cast(Device, panda), file_name, output_directory)
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
- RE: RunEngine, panda: Device, file_name: str, output_directory: str
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
- RE(save_to_file())
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 BaseDCM
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: BaseDCM
12
+ dcm: DoubleCrystalMonochromatorBase
13
13
 
14
14
 
15
15
  def verify_undulator_gap(devices: CheckUndulatorDevices):
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- dodal = dodal.__main__:main
3
- save-panda = dodal.devices.util.save_panda:main
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