ophyd-async 0.13.1__py3-none-any.whl → 0.13.2__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.
@@ -4,7 +4,7 @@ from ophyd_async.core import (
4
4
  StandardDetector,
5
5
  TriggerInfo,
6
6
  )
7
- from ophyd_async.epics.eiger import Odin, OdinWriter
7
+ from ophyd_async.epics.odin import Odin, OdinWriter
8
8
 
9
9
  from ._eiger_controller import EigerController
10
10
  from ._eiger_io import EigerDriverIO
@@ -0,0 +1,29 @@
1
+ from ._controller import JungfrauController
2
+ from ._jungfrau import Jungfrau
3
+ from ._signals import (
4
+ AcquisitionType,
5
+ DetectorStatus,
6
+ GainMode,
7
+ JungfrauDriverIO,
8
+ JungfrauTriggerMode,
9
+ PedestalMode,
10
+ )
11
+ from ._utils import (
12
+ create_jungfrau_external_triggering_info,
13
+ create_jungfrau_internal_triggering_info,
14
+ create_jungfrau_pedestal_triggering_info,
15
+ )
16
+
17
+ __all__ = [
18
+ "Jungfrau",
19
+ "DetectorStatus",
20
+ "create_jungfrau_external_triggering_info",
21
+ "create_jungfrau_internal_triggering_info",
22
+ "create_jungfrau_pedestal_triggering_info",
23
+ "JungfrauController",
24
+ "JungfrauDriverIO",
25
+ "JungfrauTriggerMode",
26
+ "AcquisitionType",
27
+ "GainMode",
28
+ "PedestalMode",
29
+ ]
@@ -0,0 +1,139 @@
1
+ import asyncio
2
+ import logging
3
+
4
+ from ophyd_async.core import (
5
+ DEFAULT_TIMEOUT,
6
+ DetectorController,
7
+ DetectorTrigger,
8
+ TriggerInfo,
9
+ wait_for_value,
10
+ )
11
+
12
+ from ._signals import (
13
+ JUNGFRAU_TRIGGER_MODE_MAP,
14
+ AcquisitionType,
15
+ DetectorStatus,
16
+ JungfrauDriverIO,
17
+ PedestalMode,
18
+ )
19
+
20
+ # Deadtime is dependant on a wide combination of settings and on trigger mode
21
+ # but this is safe upper-limit
22
+ JUNGFRAU_DEADTIME_S = 2e-5
23
+
24
+ logger = logging.getLogger("ophyd_async")
25
+
26
+
27
+ class JungfrauController(DetectorController):
28
+ def __init__(self, driver: JungfrauDriverIO):
29
+ self._driver = driver
30
+
31
+ def get_deadtime(self, exposure: float | None = None) -> float:
32
+ return JUNGFRAU_DEADTIME_S
33
+
34
+ async def prepare(self, trigger_info: TriggerInfo) -> None:
35
+ # ValueErrors and warnings in this function come from the jungfrau operation
36
+ # docs: https://rtd.xfel.eu/docs/jungfrau-detector-documentation/en/latest/operation.html
37
+
38
+ # Deadtime here is really used as "time between frames"
39
+
40
+ acquisition_type = await self._driver.acquisition_type.get_value()
41
+ logger.info(f"Preparing Jungfrau in {acquisition_type} mode.")
42
+
43
+ if trigger_info.trigger not in (
44
+ DetectorTrigger.INTERNAL,
45
+ DetectorTrigger.EDGE_TRIGGER,
46
+ ):
47
+ raise ValueError(
48
+ "The trigger method can only be called with internal or edge triggering"
49
+ )
50
+ if (
51
+ acquisition_type == AcquisitionType.PEDESTAL
52
+ and trigger_info.trigger != DetectorTrigger.INTERNAL
53
+ ):
54
+ raise ValueError(
55
+ "Jungfrau must be triggered internally while in pedestal mode."
56
+ )
57
+
58
+ if not isinstance(trigger_info.number_of_events, int):
59
+ raise TypeError("Number of events must be an integer")
60
+
61
+ if acquisition_type != AcquisitionType.PEDESTAL:
62
+ if (
63
+ trigger_info.trigger == DetectorTrigger.INTERNAL
64
+ and trigger_info.number_of_events != 1
65
+ ):
66
+ raise ValueError(
67
+ "Number of events must be set to 1 in internal trigger mode during "
68
+ "standard acquisitions."
69
+ )
70
+
71
+ if (
72
+ trigger_info.trigger == DetectorTrigger.EDGE_TRIGGER
73
+ and trigger_info.exposures_per_event != 1
74
+ ):
75
+ raise ValueError(
76
+ "Exposures per event must be set to 1 in edge trigger mode "
77
+ "during standard acquisitions."
78
+ )
79
+
80
+ if not trigger_info.livetime:
81
+ raise ValueError("Must set TriggerInfo.livetime")
82
+
83
+ if trigger_info.livetime < 2e-6:
84
+ logger.warning("Exposure time shorter than 2μs is not recommended")
85
+
86
+ period_between_frames = trigger_info.livetime + trigger_info.deadtime
87
+
88
+ if period_between_frames < self.get_deadtime():
89
+ raise ValueError(
90
+ f"Period between frames (exposure time - deadtime) = "
91
+ f"{period_between_frames}s cannot be lower than minimum detector "
92
+ f"deadtime {self.get_deadtime()}"
93
+ )
94
+
95
+ coros = [
96
+ self._driver.trigger_mode.set(
97
+ JUNGFRAU_TRIGGER_MODE_MAP[trigger_info.trigger]
98
+ ),
99
+ self._driver.period_between_frames.set(period_between_frames),
100
+ self._driver.exposure_time.set(trigger_info.livetime),
101
+ ]
102
+
103
+ match acquisition_type:
104
+ case AcquisitionType.STANDARD:
105
+ frames_signal = (
106
+ trigger_info.exposures_per_event
107
+ if trigger_info.trigger is DetectorTrigger.INTERNAL
108
+ else trigger_info.number_of_events
109
+ )
110
+ coros.extend(
111
+ [
112
+ self._driver.frames_per_acq.set(frames_signal),
113
+ ]
114
+ )
115
+ case AcquisitionType.PEDESTAL:
116
+ coros.extend(
117
+ [
118
+ self._driver.pedestal_mode_frames.set(
119
+ trigger_info.exposures_per_event
120
+ ),
121
+ self._driver.pedestal_mode_loops.set(
122
+ trigger_info.number_of_events
123
+ ),
124
+ self._driver.pedestal_mode_state.set(PedestalMode.ON),
125
+ ]
126
+ )
127
+
128
+ await asyncio.gather(*coros)
129
+
130
+ async def arm(self):
131
+ await self._driver.acquisition_start.trigger()
132
+
133
+ async def wait_for_idle(self):
134
+ await wait_for_value(
135
+ self._driver.detector_status, DetectorStatus.IDLE, timeout=DEFAULT_TIMEOUT
136
+ )
137
+
138
+ async def disarm(self):
139
+ await self._driver.acquisition_stop.trigger()
@@ -0,0 +1,30 @@
1
+ from ophyd_async.core import (
2
+ PathProvider,
3
+ StandardDetector,
4
+ )
5
+ from ophyd_async.epics.odin import Odin, OdinWriter
6
+ from ophyd_async.fastcs.jungfrau._controller import JungfrauController
7
+ from ophyd_async.fastcs.jungfrau._signals import JungfrauDriverIO
8
+
9
+
10
+ class Jungfrau(StandardDetector[JungfrauController, OdinWriter]):
11
+ """Ophyd-async implementation of a Jungfrau Detector."""
12
+
13
+ def __init__(
14
+ self,
15
+ prefix: str,
16
+ path_provider: PathProvider,
17
+ drv_suffix: str,
18
+ hdf_suffix: str,
19
+ odin_nodes: int,
20
+ name="",
21
+ ):
22
+ self.drv = JungfrauDriverIO(prefix + drv_suffix)
23
+ self.odin = Odin(prefix + hdf_suffix, nodes=odin_nodes)
24
+ writer = OdinWriter(
25
+ path_provider,
26
+ self.odin,
27
+ self.drv.bit_depth,
28
+ )
29
+ controller = JungfrauController(self.drv)
30
+ super().__init__(controller, writer, name=name)
@@ -0,0 +1,94 @@
1
+ from pydantic import NonNegativeInt
2
+
3
+ from ophyd_async.core import (
4
+ DetectorTrigger,
5
+ Device,
6
+ SignalR,
7
+ SignalRW,
8
+ SignalX,
9
+ StrictEnum,
10
+ soft_signal_rw,
11
+ )
12
+ from ophyd_async.fastcs.core import fastcs_connector
13
+
14
+
15
+ class JungfrauTriggerMode(StrictEnum):
16
+ INTERNAL = "Internal"
17
+
18
+ # Detector waits for external trigger to start frame series, but still
19
+ # controls exposure time and frame period internally
20
+ EXTERNAL = "External"
21
+
22
+
23
+ class DetectorStatus(StrictEnum):
24
+ IDLE = "Idle"
25
+ ERROR = "Error"
26
+ WAITING = "Waiting"
27
+ RUN_FINISHED = "RunFinished"
28
+ TRANSMITTING = "Transmitting"
29
+ RUNNING = "Running"
30
+ STOPPED = "Stopped"
31
+
32
+
33
+ class GainMode(StrictEnum):
34
+ DYNAMIC = "Dynamic"
35
+ FORCE_SWITCH_G1 = "ForceSwitchG1"
36
+ FORCE_SWITCH_G2 = "ForceSwitchG2"
37
+ FIX_G1 = "FixG1"
38
+ FIX_G2 = "FixG2"
39
+
40
+ # Use with caution - this may damage the detector
41
+ FIX_G0 = "FixG0"
42
+
43
+
44
+ class PedestalMode(StrictEnum):
45
+ ON = "On"
46
+ OFF = "Off"
47
+
48
+
49
+ class AcquisitionType(StrictEnum):
50
+ STANDARD = "Standard"
51
+ PEDESTAL = "Pedestal"
52
+
53
+
54
+ JUNGFRAU_TRIGGER_MODE_MAP = {
55
+ DetectorTrigger.EDGE_TRIGGER: JungfrauTriggerMode.EXTERNAL,
56
+ DetectorTrigger.INTERNAL: JungfrauTriggerMode.INTERNAL,
57
+ }
58
+
59
+
60
+ class JungfrauDriverIO(Device):
61
+ """Contains signals for handling IO on the Jungfrau detector."""
62
+
63
+ exposure_time: SignalRW[float] # in s
64
+
65
+ # Includes deadtime
66
+ period_between_frames: SignalRW[float] # in s
67
+
68
+ # Sets the delay for the beginning of the exposure time after
69
+ # trigger input
70
+ delay_after_trigger: SignalRW[float] # in s
71
+
72
+ # In internal trigger mode, this is frames per trigger. In external trigger mode,
73
+ # this is frames per overall acquisition. In pedestal mode, this signal is not set.
74
+ frames_per_acq: SignalRW[NonNegativeInt]
75
+
76
+ pedestal_mode_state: SignalRW[PedestalMode]
77
+ pedestal_mode_frames: SignalRW[NonNegativeInt]
78
+ pedestal_mode_loops: SignalRW[NonNegativeInt]
79
+
80
+ gain_mode: SignalRW[GainMode]
81
+
82
+ acquisition_start: SignalX
83
+
84
+ acquisition_stop: SignalX
85
+ bit_depth: SignalR[int]
86
+ trigger_mode: SignalRW[JungfrauTriggerMode]
87
+ detector_status: SignalR[DetectorStatus]
88
+
89
+ def __init__(self, uri: str, name: str = ""):
90
+ # Determines how the TriggerInfo gets mapped to the Jungfrau during prepare
91
+ self.acquisition_type = soft_signal_rw(
92
+ AcquisitionType, AcquisitionType.STANDARD
93
+ )
94
+ super().__init__(name=name, connector=fastcs_connector(self, uri))
@@ -0,0 +1,79 @@
1
+ from pydantic import PositiveInt
2
+
3
+ from ophyd_async.core import DetectorTrigger, TriggerInfo
4
+
5
+
6
+ def create_jungfrau_external_triggering_info(
7
+ total_triggers: PositiveInt,
8
+ exposure_time_s: float,
9
+ ) -> TriggerInfo:
10
+ """Create safe Jungfrau TriggerInfo for external triggering.
11
+
12
+ Uses parameters which more closely-align with Jungfrau terminology
13
+ to create TriggerInfo. This device currently only supports one frame per trigger
14
+ when being externally triggered, but support for this can be added if needed
15
+
16
+ Args:
17
+ total_triggers: Total external triggers expected before ending acquisition.
18
+ exposure_time_s: How long to expose the detector for each of its frames.
19
+
20
+ Returns:
21
+ `TriggerInfo`
22
+ """
23
+ return TriggerInfo(
24
+ number_of_events=total_triggers,
25
+ trigger=DetectorTrigger.EDGE_TRIGGER,
26
+ livetime=exposure_time_s,
27
+ )
28
+
29
+
30
+ def create_jungfrau_internal_triggering_info(
31
+ number_of_frames: PositiveInt, exposure_time_s: float
32
+ ) -> TriggerInfo:
33
+ """Create safe Jungfrau TriggerInfo for internal triggering.
34
+
35
+ Uses parameters which more closely-align with Jungfrau terminology
36
+ to create TriggerInfo.
37
+
38
+ Args:
39
+ number_of_frames: Total frames taken after starting acquisition.
40
+ exposure_time_s: How long to expose the detector for each of its frames.
41
+
42
+ Returns:
43
+ `TriggerInfo`
44
+ """
45
+ return TriggerInfo(
46
+ number_of_events=1,
47
+ trigger=DetectorTrigger.INTERNAL,
48
+ livetime=exposure_time_s,
49
+ exposures_per_event=number_of_frames,
50
+ )
51
+
52
+
53
+ def create_jungfrau_pedestal_triggering_info(
54
+ exposure_time_s: float,
55
+ pedestal_frames: PositiveInt,
56
+ pedestal_loops: PositiveInt,
57
+ ):
58
+ """Create safe Jungfrau TriggerInfo for pedestal triggering.
59
+
60
+ Uses parameters which more closely-align with Jungfrau terminology
61
+ to create TriggerInfo.
62
+
63
+ NOTE: To trigger the jungfrau in pedestal mode, you must first set the
64
+ jungfrau acquisition_type signal to AcquisitionType.PEDESTAL!
65
+
66
+ Args:
67
+ exposure_time_s: How long to expose the detector for each of its frames.
68
+ pedestal_frames: Number of frames taken once triggering begins
69
+ pedestal_loops: Number of repeats of the pedestal scan before detector disarms.
70
+
71
+ Returns:
72
+ `TriggerInfo`
73
+ """
74
+ return TriggerInfo(
75
+ number_of_events=pedestal_loops,
76
+ exposures_per_event=pedestal_frames,
77
+ trigger=DetectorTrigger.INTERNAL,
78
+ livetime=exposure_time_s,
79
+ )
ophyd_async/sim/_motor.py CHANGED
@@ -23,11 +23,19 @@ from ophyd_async.core import StandardReadableFormat as Format
23
23
  class SimMotor(StandardReadable, Stoppable, Subscribable[float], Locatable[float]):
24
24
  """For usage when simulating a motor."""
25
25
 
26
- def __init__(self, name="", instant=True) -> None:
26
+ def __init__(
27
+ self,
28
+ name: str = "",
29
+ instant: bool = True,
30
+ initial_value: float = 0.0,
31
+ units: str = "mm",
32
+ ) -> None:
27
33
  """Simulate a motor, with optional velocity.
28
34
 
29
35
  :param name: name of device
30
36
  :param instant: whether to move instantly or calculate move time using velocity
37
+ :param initial_value: initial position of the motor
38
+ :param units: units of the motor position
31
39
  """
32
40
  # Define some signals
33
41
  with self.add_children_as_readables(Format.HINTED_SIGNAL):
@@ -37,8 +45,8 @@ class SimMotor(StandardReadable, Stoppable, Subscribable[float], Locatable[float
37
45
  with self.add_children_as_readables(Format.CONFIG_SIGNAL):
38
46
  self.velocity = soft_signal_rw(float, 0 if instant else 1.0)
39
47
  self.acceleration_time = soft_signal_rw(float, 0.5)
40
- self.units = soft_signal_rw(str, "mm")
41
- self.user_setpoint = soft_signal_rw(float, 0)
48
+ self.units = soft_signal_rw(str, units)
49
+ self.user_setpoint = soft_signal_rw(float, initial_value)
42
50
 
43
51
  # Whether set() should complete successfully or not
44
52
  self._set_success = True
@@ -41,9 +41,12 @@ class SimPointDetector(StandardReadable):
41
41
  """Simalutes a point detector with multiple channels."""
42
42
 
43
43
  def __init__(
44
- self, generator: PatternGenerator, num_channels: int = 3, name: str = ""
44
+ self,
45
+ pattern_generator: PatternGenerator | None,
46
+ num_channels: int = 3,
47
+ name: str = "",
45
48
  ) -> None:
46
- self._generator = generator
49
+ self.pattern_generator = pattern_generator or PatternGenerator()
47
50
  self.acquire_time = soft_signal_rw(float, 0.1)
48
51
  self.acquiring, self._set_acquiring = soft_signal_r_and_setter(bool)
49
52
  self._value_signals = dict(
@@ -75,7 +78,7 @@ class SimPointDetector(StandardReadable):
75
78
  # Update the channel value
76
79
  for i, channel in self.channel.items():
77
80
  high_energy = modes[channel] == EnergyMode.HIGH
78
- point = self._generator.generate_point(i, high_energy)
81
+ point = self.pattern_generator.generate_point(i, high_energy)
79
82
  setter = self._value_signals[channel.value]
80
83
  setter(int(point * 10000 * update_time))
81
84
 
ophyd_async/sim/_stage.py CHANGED
@@ -8,12 +8,23 @@ class SimStage(StandardReadable):
8
8
  """A simulated sample stage with X and Y movables."""
9
9
 
10
10
  def __init__(self, pattern_generator: PatternGenerator, name="") -> None:
11
+ self.pattern_generator = pattern_generator
11
12
  # Define some child Devices
12
13
  with self.add_children_as_readables():
13
14
  self.x = SimMotor(instant=False)
14
15
  self.y = SimMotor(instant=False)
15
- # Tell the pattern generator about the motor positions
16
- self.x.user_readback.subscribe_value(pattern_generator.set_x)
17
- self.y.user_readback.subscribe_value(pattern_generator.set_y)
18
16
  # Set name of device and child devices
19
17
  super().__init__(name=name)
18
+
19
+ def stage(self):
20
+ """Stage the motors and report the position to the pattern generator."""
21
+ # Tell the pattern generator about the motor positions
22
+ self.x.user_readback.subscribe_value(self.pattern_generator.set_x)
23
+ self.y.user_readback.subscribe_value(self.pattern_generator.set_y)
24
+ return super().stage()
25
+
26
+ def unstage(self):
27
+ """Unstage the motors and remove the position subscription."""
28
+ self.x.user_readback.clear_sub(self.pattern_generator.set_x)
29
+ self.y.user_readback.clear_sub(self.pattern_generator.set_y)
30
+ return super().unstage()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ophyd-async
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
5
5
  Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -50,6 +50,7 @@ Requires-Dist: pydantic>=2.0
50
50
  Requires-Dist: pydantic-numpy
51
51
  Requires-Dist: stamina>=23.1.0
52
52
  Requires-Dist: scanspec>=1.0a1
53
+ Requires-Dist: velocity-profile
53
54
  Provides-Extra: sim
54
55
  Requires-Dist: h5py; extra == "sim"
55
56
  Provides-Extra: ca
@@ -1,9 +1,9 @@
1
1
  ophyd_async/__init__.py,sha256=dcAA3qsj1nNIMe5l-v2tlduZ_ypwBmyuHe45Lsq4k4w,206
2
2
  ophyd_async/__main__.py,sha256=n_U4O9bgm97OuboUB_9eK7eFiwy8BZSgXJ0OzbE0DqU,481
3
3
  ophyd_async/_docs_parser.py,sha256=gPYrigfSbYCF7QoSf2UvE-cpQu4snSssl7ZWN-kKDzI,352
4
- ophyd_async/_version.py,sha256=RBWKvLuPH5uJN_RJXTOaV5SvvBYz1PUZvU4D8m3gAvo,706
4
+ ophyd_async/_version.py,sha256=XZecU3ohLLhnQNT8_JmdvW2idqqOh08RIDcm2qzc5t8,706
5
5
  ophyd_async/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- ophyd_async/core/__init__.py,sha256=yRb_6ufTXFtf3fagShfmSDfiMduIhvNPgQyM-7GGwas,4929
6
+ ophyd_async/core/__init__.py,sha256=KBj8v-Fxh8V1QKJYR0xAjoziqo1vjyblx45H7Jrikd0,4979
7
7
  ophyd_async/core/_derived_signal.py,sha256=TuZza_j3J1Bw4QSqBYB9Ta2FyQP5BycO3nSHVtJ890Q,13015
8
8
  ophyd_async/core/_derived_signal_backend.py,sha256=PYyyont_nUR9LBC9eqVwueHCMwLJfQ_F7R_14sivBTU,12510
9
9
  ophyd_async/core/_detector.py,sha256=bPTQYLTjbxs7-wjV8szAZ0TQI20fV12vkq1OaA5L_z8,14938
@@ -18,7 +18,7 @@ ophyd_async/core/_protocol.py,sha256=wQ_snxhTprHqEjQb1HgFwBljwolMY6A8C3xgV1PXwdU
18
18
  ophyd_async/core/_providers.py,sha256=WBht3QCgvGc0stNcwH6z4Zr6hAz3e01-88NjsYI2w6I,9740
19
19
  ophyd_async/core/_readable.py,sha256=iBo1YwA5bsAbzLbznvmSnzKDWUuGkLh850Br3BXsgeU,11707
20
20
  ophyd_async/core/_settings.py,sha256=_ZccbXKP7j5rG6-bMKk7aaLr8hChdRDAPY_YSR71XXM,4213
21
- ophyd_async/core/_signal.py,sha256=uBeiLblabI0QUzEOrjtqS6pNnYkzAsadtm_KX628Kt4,28145
21
+ ophyd_async/core/_signal.py,sha256=ghgxtfUG9vkwgvuu6qXa_ECux5-3j9WwxB5mN5G6jqU,28421
22
22
  ophyd_async/core/_signal_backend.py,sha256=PvwTbbSVEGqM-2s5BNRrKGwM_MiYL71qMxYAgyZ7wRM,6930
23
23
  ophyd_async/core/_soft_signal_backend.py,sha256=NJUuyaCKtBZjggt8WKi7_lKQRHasToxviuQvl5xbhLU,6222
24
24
  ophyd_async/core/_status.py,sha256=h4TtWFM7wFtpxxyAYYSITgcVzArYZdYBHbya6qIX5t0,6553
@@ -26,7 +26,7 @@ ophyd_async/core/_table.py,sha256=ai-_W-_WMZcy9f69BDYRv9vjVl-AVeOPN_uHYoGCSsc,69
26
26
  ophyd_async/core/_utils.py,sha256=-iKbqsvVR7P29E6VpOgI5WfDwGBRdud_gvExIoUVlG4,12495
27
27
  ophyd_async/core/_yaml_settings.py,sha256=Qojhku9l5kPSkTnEylCRWTe0gpw6S_XP5av5dPpqFgQ,2089
28
28
  ophyd_async/epics/__init__.py,sha256=ou4yEaH9VZHz70e8oM614-arLMQvUfQyXhRJsnEpWn8,60
29
- ophyd_async/epics/motor.py,sha256=UFolYxuaePnWNJNOFzgI-He4kBTHhJqaTywtqFFSmsk,8475
29
+ ophyd_async/epics/motor.py,sha256=oRAAW-KWbMnAxHdOMKMt1ZrzgD5KzHX9iRwd0TYZXwI,8747
30
30
  ophyd_async/epics/signal.py,sha256=0A-supp9ajr63O6aD7F9oG0-Q26YmRjk-ZGh57-jo1Y,239
31
31
  ophyd_async/epics/adandor/__init__.py,sha256=dlitllrAdhvh16PAcVMUSSEytTDNMu6_HuYk8KD1EoY,343
32
32
  ophyd_async/epics/adandor/_andor.py,sha256=TijGjNVxuH-P0X7UACPt9eLLQ449DwMyVhbn1kV7Le8,1245
@@ -64,7 +64,7 @@ ophyd_async/epics/advimba/_vimba_controller.py,sha256=KSbP4LHqYkCDplpmBk7hdf0Yz9
64
64
  ophyd_async/epics/advimba/_vimba_io.py,sha256=E3XlCKLQbGOWho0dQPeD4xeEl5pZGINyYstGD43qNrM,1492
65
65
  ophyd_async/epics/core/__init__.py,sha256=q73i4aJ_0HApVNmf3eAw-q30XuazAyZW2MW5TXk-pOY,648
66
66
  ophyd_async/epics/core/_aioca.py,sha256=38aW5dd3MzwhoweNMjkOfnfZHI2JZFateO0YABGVSfQ,13230
67
- ophyd_async/epics/core/_epics_connector.py,sha256=S4z_wbj-aogVcjqCyUgjhcq5Y4gDC7y6wXbsSz2nODY,1918
67
+ ophyd_async/epics/core/_epics_connector.py,sha256=KXQ1WVpNrgQ30KiiXTYRwfoHdaU5oWv1jVZAvx3tGig,2557
68
68
  ophyd_async/epics/core/_epics_device.py,sha256=wGdR24I7GSPh3HmM7jsWKZhBZgt4IyLrCn4Ut7Wx_xo,510
69
69
  ophyd_async/epics/core/_p4p.py,sha256=Q6o4rlyrg2VXlqi1uHkGbnYc1gZ8YX5ZaJDcL0eAr_8,16385
70
70
  ophyd_async/epics/core/_pvi_connector.py,sha256=SfKkZqGCRvJJtQpJQzmfuLJQqOge0wBsMeuTSQ-KPjs,5553
@@ -80,11 +80,12 @@ ophyd_async/epics/demo/_stage.py,sha256=KPnwr5EX8f_0xxkNWT-70a0AqB0D9DoiTbxMmy0i
80
80
  ophyd_async/epics/demo/motor.db,sha256=3xb6WTXo4crrvk-M8Y16G9pUidp27vD5vIKKBpLTUlk,1017
81
81
  ophyd_async/epics/demo/point_detector.db,sha256=8kBa3XKpmfXCxetT4tq5_RFXa_XqS1Z2ZNzsa2AtLds,1366
82
82
  ophyd_async/epics/demo/point_detector_channel.db,sha256=FZ9H6HjqplhcF2jgimv_dT1nn-CBlfjs7Y--iCfHp5Y,632
83
- ophyd_async/epics/eiger/__init__.py,sha256=7kRqVzwoD8PVtp7Nj9iQWlgbLeoWE_8oiq-B0kixwTE,93
84
- ophyd_async/epics/eiger/_odin_io.py,sha256=JTnsADwNszWJoXpFmdcrZrCDc_RshGlM3Bg_aeUdrUg,6491
85
- ophyd_async/epics/pmac/__init__.py,sha256=fQAFnVtzEiPlzXI5XgB62HyburMbUKDfOgkIO_JBPYc,182
86
- ophyd_async/epics/pmac/_pmac_io.py,sha256=_lTUdNHTWOwPitAxXottyLrmiwhf36WfTbrdneqeg34,4022
87
- ophyd_async/epics/pmac/_utils.py,sha256=6bb_yKNcmWSfuaYunRv5GcA8ML4jEUsf1jkXko_LSEo,8888
83
+ ophyd_async/epics/odin/__init__.py,sha256=7kRqVzwoD8PVtp7Nj9iQWlgbLeoWE_8oiq-B0kixwTE,93
84
+ ophyd_async/epics/odin/_odin_io.py,sha256=YDBrS15PnEKe5SHmz397Emh--lZSQEnbR3G7p8pbShY,6533
85
+ ophyd_async/epics/pmac/__init__.py,sha256=GqJTiJudqE9pu050ZNED09F9tKRfazn0wBsojsMH2gg,273
86
+ ophyd_async/epics/pmac/_pmac_io.py,sha256=Nnenk7HHyzzqe0jIg2FAtxFohFnr_ByDZ0IAEI4_Ls4,4023
87
+ ophyd_async/epics/pmac/_pmac_trajectory.py,sha256=Q9Ry2xzL7FqszehhfBfhu-5-fFyPcJiD2Iu86c9pQ7w,4167
88
+ ophyd_async/epics/pmac/_utils.py,sha256=ahN5zMfO3-gNV7H1fQ5wsDeGUL9IpMQa2g27rhVf0uU,34326
88
89
  ophyd_async/epics/testing/__init__.py,sha256=aTIv4D2DYrpnGco5RQF8QuLG1SfFkIlTyM2uYEKXltA,522
89
90
  ophyd_async/epics/testing/_example_ioc.py,sha256=zb4ZEUzuB2MrSw5ETPLIiHhf-2BRU1Bdxco6Kh4iI1I,3880
90
91
  ophyd_async/epics/testing/_utils.py,sha256=9gxpwaWX0HGtacu1LTupcw7viXN8G78RmuNciU_-cjs,1702
@@ -93,9 +94,14 @@ ophyd_async/epics/testing/test_records_pva.db,sha256=HJAJSvLtPWG5B5dKv8OZ0_hPJxR
93
94
  ophyd_async/fastcs/__init__.py,sha256=qlIM9-pjJ8yWfnzTM9-T9cw7zQLKjeeNROQTni5Dr6M,80
94
95
  ophyd_async/fastcs/core.py,sha256=pL_srtTrfuoBHUjDFpxES92owFq9M4Jve0Skk1oeuFA,517
95
96
  ophyd_async/fastcs/eiger/__init__.py,sha256=RxwOFjERKy5tUD_IDGCGuMh716FaZgCq7R9elPixBwo,312
96
- ophyd_async/fastcs/eiger/_eiger.py,sha256=X6KczJ9JMdZUEnlt2ozUhlL8Tk1MfzgmPIpVFXdisNw,1104
97
+ ophyd_async/fastcs/eiger/_eiger.py,sha256=jo3K5dM3Co_RDYIyO6poCVDqp2g_1z4MqnYftwnMhUk,1103
97
98
  ophyd_async/fastcs/eiger/_eiger_controller.py,sha256=Cucj-1M-1CaxSJxHZmHs3f_OXwtTIspcqUFhRNGzn_E,2361
98
99
  ophyd_async/fastcs/eiger/_eiger_io.py,sha256=yNozTKX4CMoqIaFvyKJEs5RXXGJ4VITP_T4TIFHWRmc,1242
100
+ ophyd_async/fastcs/jungfrau/__init__.py,sha256=6BV6czpOWmDuTAKR-47tRFdM3Q5dQenHnPPAYiWOFk0,717
101
+ ophyd_async/fastcs/jungfrau/_controller.py,sha256=OiPCVwYtY_0bx5His9qVsRHzG8-Rjg087B6c71gO5Q8,4836
102
+ ophyd_async/fastcs/jungfrau/_jungfrau.py,sha256=KAHCmRHMyzIh-r2JXVJcQOGLkCOOdW5Mao_KChITO2s,929
103
+ ophyd_async/fastcs/jungfrau/_signals.py,sha256=8seZCkKTb-xJL0IdB2el8VTEbWNaCvZIhpP0609GpxI,2500
104
+ ophyd_async/fastcs/jungfrau/_utils.py,sha256=-NeIlUW7Mx9llUC6FZORc6e-IAAOL9lwzzl07wc8lTc,2509
99
105
  ophyd_async/fastcs/odin/__init__.py,sha256=da1PTClDMl-IBkrSvq6JC1lnS-K_BASzCvxVhNxN5Ls,13
100
106
  ophyd_async/fastcs/panda/__init__.py,sha256=ugrScVm4HPQFc-d1kTAfZ5UUzW9T3SPgTi0OD2s8ZH0,1003
101
107
  ophyd_async/fastcs/panda/_block.py,sha256=SM7NaWCRwLz2Pl4wgjZMrDgx3ZLdGPTw6nU0bA-65yA,2394
@@ -119,10 +125,10 @@ ophyd_async/sim/_blob_detector_controller.py,sha256=y1aSNQJUPnsT2qnj2sk254Mp18an
119
125
  ophyd_async/sim/_blob_detector_writer.py,sha256=_Pd0OaP4_mZfwxtUF35v7hsktLP_wYljR4nylr5CzJo,3346
120
126
  ophyd_async/sim/_mirror_horizontal.py,sha256=Jsqa8Snjy1jQDboZtAQFJjGor5uKk8FBC7OCe-GoZDw,1478
121
127
  ophyd_async/sim/_mirror_vertical.py,sha256=HUD44mYT0jQ0GKiQKxD7k_7y6o6OdE6TztgdPUJIK_g,2085
122
- ophyd_async/sim/_motor.py,sha256=7s2jBNwWm4CI6I6l_LEpe7z61QdWy82JdZBKSFOnYe4,8994
128
+ ophyd_async/sim/_motor.py,sha256=EUykjGfQgBnf0Pmr66XeDlhz8DU0eAIXUvIgbtJccoA,9226
123
129
  ophyd_async/sim/_pattern_generator.py,sha256=kuxvyX2gIxrywhQRhaO1g8YluBT7LBkE20IsurZS-6o,3734
124
- ophyd_async/sim/_point_detector.py,sha256=nXgL_1aJZciNBw8Zr2wMYaMbzzAEKXV3yV8FQz2nS_4,2940
125
- ophyd_async/sim/_stage.py,sha256=qaeyZbUVL1v2pTHJiZxq-y6BKpA1l_DAKyzAQppQx70,772
130
+ ophyd_async/sim/_point_detector.py,sha256=wMG_ncvm99WMCPihlFyuMEf3UknAxCpB1hpk3uKiENE,3024
131
+ ophyd_async/sim/_stage.py,sha256=fOR5HGWfqWw47-0HrMmQ5rait_qPVNneF329wCx8KKY,1233
126
132
  ophyd_async/tango/__init__.py,sha256=g9xzjlzPpUAP12YI-kYwfAoLSYPAQdL1S11R2c-cius,60
127
133
  ophyd_async/tango/core/__init__.py,sha256=IMvQ7MWcTof99h_pr483KWKvQV2-h7zo_iRpLA2PUYQ,1108
128
134
  ophyd_async/tango/core/_base_device.py,sha256=e9oqSL-fDOj8r9nUUFZkbibhRGbI6HYtlnZjK5B_2fE,5033
@@ -147,8 +153,8 @@ ophyd_async/testing/_one_of_everything.py,sha256=U9ui7B-iNHDM3H3hIWUuaCb8Gc2eLlU
147
153
  ophyd_async/testing/_single_derived.py,sha256=5-HOTzgePcZ354NK_ssVpyIbJoJmKyjVQCxSwQXUC-4,2730
148
154
  ophyd_async/testing/_utils.py,sha256=zClRo5ve8RGia7wQnby41W-Zprj-slOA5da1LfYnuhw,45
149
155
  ophyd_async/testing/_wait_for_pending.py,sha256=YZAR48n-CW0GsPey3zFRzMJ4byDAr3HvMIoawjmTrHw,732
150
- ophyd_async-0.13.1.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
151
- ophyd_async-0.13.1.dist-info/METADATA,sha256=C7N-G9XhmTuI2S1P6V1efiRZTInRDDaG9S1YXgMGA4g,7145
152
- ophyd_async-0.13.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
153
- ophyd_async-0.13.1.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
154
- ophyd_async-0.13.1.dist-info/RECORD,,
156
+ ophyd_async-0.13.2.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
157
+ ophyd_async-0.13.2.dist-info/METADATA,sha256=GwFtb0s8P44XeDTXV6U55G1tro_OERT4Vj-9aVrKomE,7177
158
+ ophyd_async-0.13.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
159
+ ophyd_async-0.13.2.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
160
+ ophyd_async-0.13.2.dist-info/RECORD,,
File without changes