dls-dodal 1.57.0__py3-none-any.whl → 1.59.1__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 (63) hide show
  1. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/METADATA +2 -1
  2. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/RECORD +63 -46
  3. dodal/_version.py +2 -2
  4. dodal/beamlines/b07.py +10 -5
  5. dodal/beamlines/b07_1.py +10 -5
  6. dodal/beamlines/b21.py +22 -0
  7. dodal/beamlines/i02_1.py +80 -0
  8. dodal/beamlines/i03.py +7 -4
  9. dodal/beamlines/i04.py +20 -3
  10. dodal/beamlines/i09.py +10 -9
  11. dodal/beamlines/i09_1.py +10 -5
  12. dodal/beamlines/i10-1.py +25 -0
  13. dodal/beamlines/i10.py +17 -1
  14. dodal/beamlines/i11.py +0 -17
  15. dodal/beamlines/i19_2.py +20 -0
  16. dodal/beamlines/i21.py +27 -0
  17. dodal/beamlines/i22.py +12 -2
  18. dodal/beamlines/i24.py +32 -3
  19. dodal/beamlines/k07.py +31 -0
  20. dodal/beamlines/p60.py +10 -9
  21. dodal/common/beamlines/commissioning_mode.py +33 -0
  22. dodal/common/watcher_utils.py +1 -1
  23. dodal/devices/apple2_undulator.py +18 -142
  24. dodal/devices/attenuator/attenuator.py +48 -2
  25. dodal/devices/attenuator/filter.py +3 -0
  26. dodal/devices/attenuator/filter_selections.py +26 -0
  27. dodal/devices/baton.py +4 -0
  28. dodal/devices/eiger.py +2 -1
  29. dodal/devices/electron_analyser/__init__.py +4 -0
  30. dodal/devices/electron_analyser/abstract/base_driver_io.py +30 -18
  31. dodal/devices/electron_analyser/energy_sources.py +101 -0
  32. dodal/devices/electron_analyser/specs/detector.py +6 -6
  33. dodal/devices/electron_analyser/specs/driver_io.py +7 -15
  34. dodal/devices/electron_analyser/vgscienta/detector.py +6 -6
  35. dodal/devices/electron_analyser/vgscienta/driver_io.py +7 -14
  36. dodal/devices/fast_grid_scan.py +130 -64
  37. dodal/devices/focusing_mirror.py +30 -0
  38. dodal/devices/i02_1/__init__.py +0 -0
  39. dodal/devices/i02_1/fast_grid_scan.py +61 -0
  40. dodal/devices/i02_1/sample_motors.py +19 -0
  41. dodal/devices/i04/murko_results.py +69 -23
  42. dodal/devices/i10/i10_apple2.py +282 -140
  43. dodal/devices/i19/backlight.py +17 -0
  44. dodal/devices/i21/__init__.py +3 -0
  45. dodal/devices/i21/enums.py +8 -0
  46. dodal/devices/i22/nxsas.py +2 -0
  47. dodal/devices/i24/commissioning_jungfrau.py +114 -0
  48. dodal/devices/smargon.py +0 -56
  49. dodal/devices/temperture_controller/__init__.py +3 -0
  50. dodal/devices/temperture_controller/lakeshore/__init__.py +0 -0
  51. dodal/devices/temperture_controller/lakeshore/lakeshore.py +204 -0
  52. dodal/devices/temperture_controller/lakeshore/lakeshore_io.py +112 -0
  53. dodal/devices/tetramm.py +38 -16
  54. dodal/devices/undulator.py +13 -9
  55. dodal/devices/v2f.py +39 -0
  56. dodal/devices/xbpm_feedback.py +12 -6
  57. dodal/devices/zebra/zebra.py +1 -0
  58. dodal/devices/zebra/zebra_constants_mapping.py +1 -1
  59. dodal/parameters/experiment_parameter_base.py +1 -5
  60. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/WHEEL +0 -0
  61. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/entry_points.txt +0 -0
  62. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/licenses/LICENSE +0 -0
  63. {dls_dodal-1.57.0.dist-info → dls_dodal-1.59.1.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ from bluesky.protocols import Movable
5
5
  from numpy import ndarray
6
6
  from ophyd_async.core import (
7
7
  AsyncStatus,
8
+ Reference,
8
9
  StandardReadable,
9
10
  StandardReadableFormat,
10
11
  soft_signal_r_and_setter,
@@ -15,6 +16,7 @@ from ophyd_async.epics.motor import Motor
15
16
  from dodal.common.enums import EnabledDisabledUpper
16
17
  from dodal.log import LOGGER
17
18
 
19
+ from .baton import Baton
18
20
  from .util.lookup_tables import energy_distance_table
19
21
 
20
22
 
@@ -22,11 +24,6 @@ class AccessError(Exception):
22
24
  pass
23
25
 
24
26
 
25
- # Enable to allow testing when the beamline is down, do not change in production!
26
- TEST_MODE = False
27
- # will be made more generic in https://github.com/DiamondLightSource/dodal/issues/754
28
-
29
-
30
27
  # The acceptable difference, in mm, between the undulator gap and the DCM
31
28
  # energy, when the latter is converted to mm using lookup tables
32
29
  UNDULATOR_DISCREPANCY_THRESHOLD_MM = 2e-3
@@ -54,6 +51,7 @@ class Undulator(StandardReadable, Movable[float]):
54
51
  name: str = "",
55
52
  poles: int | None = None,
56
53
  length: float | None = None,
54
+ baton: Baton | None = None,
57
55
  ) -> None:
58
56
  """Constructor
59
57
 
@@ -64,6 +62,7 @@ class Undulator(StandardReadable, Movable[float]):
64
62
  name (str, optional): Name for device. Defaults to "".
65
63
  """
66
64
 
65
+ self.baton_ref = Reference(baton) if baton else None
67
66
  self.id_gap_lookup_table_path = id_gap_lookup_table_path
68
67
  with self.add_children_as_readables():
69
68
  self.gap_motor = Motor(prefix + "BLGAPMTR")
@@ -105,7 +104,8 @@ class Undulator(StandardReadable, Movable[float]):
105
104
 
106
105
  async def raise_if_not_enabled(self):
107
106
  access_level = await self.gap_access.get_value()
108
- if access_level is EnabledDisabledUpper.DISABLED and not TEST_MODE:
107
+ commissioning_mode = await self._is_commissioning_mode_enabled()
108
+ if access_level is EnabledDisabledUpper.DISABLED and not commissioning_mode:
109
109
  raise AccessError("Undulator gap access is disabled. Contact Control Room")
110
110
 
111
111
  async def _set_undulator_gap(self, energy_kev: float) -> None:
@@ -124,21 +124,25 @@ class Undulator(StandardReadable, Movable[float]):
124
124
  f"Undulator gap mismatch. {difference:.3f}mm is outside tolerance.\
125
125
  Moving gap to nominal value, {target_gap:.3f}mm"
126
126
  )
127
- if not TEST_MODE:
127
+ commissioning_mode = await self._is_commissioning_mode_enabled()
128
+ if not commissioning_mode:
128
129
  # Only move if the gap is sufficiently different to the value from the
129
- # DCM lookup table AND we're not in TEST_MODE
130
+ # DCM lookup table AND we're not in commissioning mode
130
131
  await self.gap_motor.set(
131
132
  target_gap,
132
133
  timeout=STATUS_TIMEOUT_S,
133
134
  )
134
135
  else:
135
- LOGGER.debug("In test mode, not moving ID gap")
136
+ LOGGER.warning("In test mode, not moving ID gap")
136
137
  else:
137
138
  LOGGER.debug(
138
139
  "Gap is already in the correct place for the new energy value "
139
140
  f"{energy_kev}, no need to ask it to move"
140
141
  )
141
142
 
143
+ async def _is_commissioning_mode_enabled(self):
144
+ return self.baton_ref and await self.baton_ref().commissioning.get_value()
145
+
142
146
  async def _get_gap_to_match_energy(self, energy_kev: float) -> float:
143
147
  """
144
148
  get a 2d np.array from lookup table that
dodal/devices/v2f.py ADDED
@@ -0,0 +1,39 @@
1
+ from ophyd_async.core import StandardReadable, StandardReadableFormat, StrictEnum
2
+ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
3
+
4
+
5
+ class V2FGain(StrictEnum):
6
+ LOW_NOISE3 = "10^3 low noise"
7
+ LOW_NOISE4 = "10^4 low noise"
8
+ LOW_NOISE5 = "10^5 low noise"
9
+ LOW_NOISE6 = "10^6 low noise"
10
+ LOW_NOISE7 = "10^7 low noise"
11
+ LOW_NOISE8 = "10^8 low noise"
12
+ LOW_NOISE9 = "10^9 low noise"
13
+ HIGHSPEED5 = "10^5 high speed"
14
+ HIGHSPEED6 = "10^6 high speed"
15
+ HIGHSPEED7 = "10^7 high speed"
16
+ HIGHSPEED8 = "10^8 high speed"
17
+ HIGHSPEED9 = "10^9 high speed"
18
+ HIGHSPEED10 = "10^10 high spd"
19
+ HIGHSPEED11 = "10^11 high spd"
20
+
21
+
22
+ class QDV2F(StandardReadable):
23
+ """
24
+ A Quantum Detectors V2F low noise voltage to frequency converter.
25
+ Two channel V2F - 50mHz
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ prefix: str,
31
+ name: str = "",
32
+ I_suffix="I",
33
+ ) -> None:
34
+ with self.add_children_as_readables(StandardReadableFormat.HINTED_SIGNAL):
35
+ self.intensity = epics_signal_r(float, f"{prefix}{I_suffix}")
36
+ with self.add_children_as_readables():
37
+ self.gain = epics_signal_rw(V2FGain, f"{prefix}GAIN")
38
+
39
+ super().__init__(name)
@@ -1,8 +1,10 @@
1
1
  from bluesky.protocols import Triggerable
2
- from ophyd_async.core import AsyncStatus, Device, StrictEnum, observe_value
2
+ from ophyd_async.core import AsyncStatus, Device, Reference, StrictEnum, observe_value
3
3
  from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
4
4
 
5
5
  from dodal.common.device_utils import periodic_reminder
6
+ from dodal.devices.baton import Baton
7
+ from dodal.log import LOGGER
6
8
 
7
9
 
8
10
  class Pause(StrictEnum):
@@ -14,15 +16,19 @@ class XBPMFeedback(Device, Triggerable):
14
16
  """The XBPM feedback device is an IOC that moves the DCM, HFM and VFM to automatically
15
17
  hold the beam into place, as measured by the XBPM sensor."""
16
18
 
17
- def __init__(self, prefix: str, name: str = "") -> None:
19
+ def __init__(self, prefix: str, name: str = "", baton: Baton | None = None) -> None:
18
20
  self.pos_ok = epics_signal_r(float, prefix + "XBPM2POSITION_OK")
19
21
  self.pos_stable = epics_signal_r(float, prefix + "XBPM2_STABLE")
20
22
  self.pause_feedback = epics_signal_rw(Pause, prefix + "FB_PAUSE")
23
+ self.baton_ref = Reference(baton) if baton else None
21
24
  super().__init__(name=name)
22
25
 
23
26
  @AsyncStatus.wrap
24
27
  async def trigger(self):
25
- async with periodic_reminder("Waiting for XBPM"):
26
- async for value in observe_value(self.pos_stable):
27
- if value:
28
- return
28
+ if self.baton_ref and await self.baton_ref().commissioning.get_value():
29
+ LOGGER.warning("Commissioning mode enabled, ignoring feedback")
30
+ else:
31
+ async with periodic_reminder("Waiting for XBPM"):
32
+ async for value in observe_value(self.pos_stable):
33
+ if value:
34
+ return
@@ -82,6 +82,7 @@ class ArmDemand(Enum):
82
82
  DISARM = 0
83
83
 
84
84
 
85
+ # Replace with ophyd-async enum after https://github.com/bluesky/ophyd-async/pull/1067
85
86
  class SoftInState(StrictEnum):
86
87
  YES = "Yes"
87
88
  NO = "No"
@@ -77,7 +77,7 @@ class ZebraMapping(ZebraMappingValidations):
77
77
  Zebra's hardware configuration and wiring.
78
78
  """
79
79
 
80
- # Zebra ophyd signal for connection can be accessed
80
+ # Zebra ophyd signal for output can be accessed
81
81
  # with, eg, zebra.output.out_pvs[zebra.mapping.outputs.TTL_DETECTOR]
82
82
  outputs: ZebraTTLOutputs = ZebraTTLOutputs()
83
83
 
@@ -1,4 +1,4 @@
1
- from abc import ABC, abstractmethod
1
+ from abc import ABC
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
@@ -9,7 +9,3 @@ class AbstractExperimentParameterBase(BaseModel, ABC):
9
9
 
10
10
  class AbstractExperimentWithBeamParams(AbstractExperimentParameterBase):
11
11
  transmission_fraction: float
12
-
13
- @abstractmethod
14
- def get_num_images(self) -> int:
15
- pass