ophyd-async 0.13.3__py3-none-any.whl → 0.13.4__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.
@@ -1,4 +1,4 @@
1
- from ._controller import JungfrauController
1
+ from ._controller import JUNGFRAU_DEADTIME_S, JungfrauController
2
2
  from ._jungfrau import Jungfrau
3
3
  from ._signals import (
4
4
  AcquisitionType,
@@ -26,4 +26,5 @@ __all__ = [
26
26
  "AcquisitionType",
27
27
  "GainMode",
28
28
  "PedestalMode",
29
+ "JUNGFRAU_DEADTIME_S",
29
30
  ]
@@ -113,20 +113,34 @@ class JungfrauController(DetectorController):
113
113
  ]
114
114
  )
115
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
- )
116
+ if trigger_info.number_of_events % 2 == 0:
117
+ coros.extend(
118
+ [
119
+ self._driver.pedestal_mode_frames.set(
120
+ trigger_info.exposures_per_event
121
+ ),
122
+ # No. events is double the pedestal loops,
123
+ # since pedestal scan does the entire loop
124
+ # twice.
125
+ self._driver.pedestal_mode_loops.set(
126
+ int(trigger_info.number_of_events / 2)
127
+ ),
128
+ ]
129
+ )
130
+ else:
131
+ raise ValueError(
132
+ f"Invalid trigger info for pedestal mode. "
133
+ f"{trigger_info.number_of_events=} must be divisible by two. "
134
+ f"Was create_jungfrau_pedestal_triggering_info used?"
135
+ )
127
136
 
128
137
  await asyncio.gather(*coros)
129
138
 
139
+ # Setting signals once the detector is in pedestal mode can cause errors,
140
+ # so do this last
141
+ if acquisition_type == AcquisitionType.PEDESTAL:
142
+ await self._driver.pedestal_mode_state.set(PedestalMode.ON)
143
+
130
144
  async def arm(self):
131
145
  await self._driver.acquisition_start.trigger()
132
146
 
@@ -137,3 +151,7 @@ class JungfrauController(DetectorController):
137
151
 
138
152
  async def disarm(self):
139
153
  await self._driver.acquisition_stop.trigger()
154
+ await asyncio.gather(
155
+ self._driver.pedestal_mode_state.set(PedestalMode.OFF),
156
+ self._driver.acquisition_type.set(AcquisitionType.STANDARD),
157
+ )
@@ -2,6 +2,8 @@ from pydantic import PositiveInt
2
2
 
3
3
  from ophyd_async.core import DetectorTrigger, TriggerInfo
4
4
 
5
+ from ._controller import JUNGFRAU_DEADTIME_S
6
+
5
7
 
6
8
  def create_jungfrau_external_triggering_info(
7
9
  total_triggers: PositiveInt,
@@ -11,7 +13,7 @@ def create_jungfrau_external_triggering_info(
11
13
 
12
14
  Uses parameters which more closely-align with Jungfrau terminology
13
15
  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
16
+ when being externally triggered.
15
17
 
16
18
  Args:
17
19
  total_triggers: Total external triggers expected before ending acquisition.
@@ -24,6 +26,7 @@ def create_jungfrau_external_triggering_info(
24
26
  number_of_events=total_triggers,
25
27
  trigger=DetectorTrigger.EDGE_TRIGGER,
26
28
  livetime=exposure_time_s,
29
+ deadtime=JUNGFRAU_DEADTIME_S,
27
30
  )
28
31
 
29
32
 
@@ -60,6 +63,11 @@ def create_jungfrau_pedestal_triggering_info(
60
63
  Uses parameters which more closely-align with Jungfrau terminology
61
64
  to create TriggerInfo.
62
65
 
66
+ When the Jungfrau is triggered in pedestal mode, it will run pedestal_frames-1
67
+ frames in dynamic gain mode, then one frame in gain mode 1, then repeat this for
68
+ pedelestal_loops number of times. This entire pattern is then repeated,
69
+ but gain mode 2 is used instead of gain mode 1 for the "one frame" part.
70
+
63
71
  NOTE: To trigger the jungfrau in pedestal mode, you must first set the
64
72
  jungfrau acquisition_type signal to AcquisitionType.PEDESTAL!
65
73
 
@@ -72,7 +80,7 @@ def create_jungfrau_pedestal_triggering_info(
72
80
  `TriggerInfo`
73
81
  """
74
82
  return TriggerInfo(
75
- number_of_events=pedestal_loops,
83
+ number_of_events=pedestal_loops * 2,
76
84
  exposures_per_event=pedestal_frames,
77
85
  trigger=DetectorTrigger.INTERNAL,
78
86
  livetime=exposure_time_s,
@@ -1,9 +1,11 @@
1
1
  from ._block import (
2
2
  CommonPandaBlocks,
3
3
  DataBlock,
4
+ InencBlock,
4
5
  PandaBitMux,
5
6
  PandaCaptureMode,
6
7
  PandaPcompDirection,
8
+ PandaPosMux,
7
9
  PandaTimeUnits,
8
10
  PcapBlock,
9
11
  PcompBlock,
@@ -20,6 +22,9 @@ from ._table import (
20
22
  )
21
23
  from ._trigger import (
22
24
  PcompInfo,
25
+ PosOutScaleOffset,
26
+ ScanSpecInfo,
27
+ ScanSpecSeqTableTriggerLogic,
23
28
  SeqTableInfo,
24
29
  StaticPcompTriggerLogic,
25
30
  StaticSeqTableTriggerLogic,
@@ -29,11 +34,13 @@ from ._writer import PandaHDFWriter
29
34
  __all__ = [
30
35
  "CommonPandaBlocks",
31
36
  "DataBlock",
37
+ "InencBlock",
32
38
  "PandaBitMux",
33
39
  "PandaCaptureMode",
34
40
  "PcapBlock",
35
41
  "PcompBlock",
36
42
  "PandaPcompDirection",
43
+ "PandaPosMux",
37
44
  "PulseBlock",
38
45
  "SeqBlock",
39
46
  "PandaTimeUnits",
@@ -48,4 +55,7 @@ __all__ = [
48
55
  "SeqTableInfo",
49
56
  "StaticPcompTriggerLogic",
50
57
  "StaticSeqTableTriggerLogic",
58
+ "ScanSpecInfo",
59
+ "ScanSpecSeqTableTriggerLogic",
60
+ "PosOutScaleOffset",
51
61
  ]
@@ -58,6 +58,12 @@ class PandaBitMux(SubsetEnum):
58
58
  ONE = "ONE"
59
59
 
60
60
 
61
+ class PandaPosMux(SubsetEnum):
62
+ """Pos input in the PandA."""
63
+
64
+ ZERO = "ZERO"
65
+
66
+
61
67
  class PcompBlock(Device):
62
68
  """Position compare block in the PandA."""
63
69
 
@@ -88,6 +94,7 @@ class SeqBlock(Device):
88
94
  prescale: SignalRW[float]
89
95
  prescale_units: SignalRW[PandaTimeUnits]
90
96
  enable: SignalRW[PandaBitMux]
97
+ posa: SignalRW[PandaPosMux]
91
98
 
92
99
 
93
100
  class PcapBlock(Device):
@@ -97,6 +104,13 @@ class PcapBlock(Device):
97
104
  arm: SignalRW[bool]
98
105
 
99
106
 
107
+ class InencBlock(Device):
108
+ """In encoder block in the PandA."""
109
+
110
+ val_scale: SignalRW[float]
111
+ val_offset: SignalRW[float]
112
+
113
+
100
114
  class CommonPandaBlocks(Device):
101
115
  """Pandablocks device with blocks which are common and required on introspection."""
102
116
 
@@ -1,17 +1,33 @@
1
+ from __future__ import annotations
2
+
1
3
  import asyncio
4
+ from dataclasses import dataclass
5
+ from typing import cast
2
6
 
7
+ import numpy as np
3
8
  from pydantic import Field
4
-
5
- from ophyd_async.core import ConfinedModel, FlyerController, wait_for_value
9
+ from scanspec.core import Path
10
+ from scanspec.specs import Spec
11
+
12
+ from ophyd_async.core import (
13
+ ConfinedModel,
14
+ FlyerController,
15
+ SignalRW,
16
+ error_if_none,
17
+ wait_for_value,
18
+ )
19
+ from ophyd_async.epics.motor import Motor
6
20
 
7
21
  from ._block import (
22
+ CommonPandaBlocks,
8
23
  PandaBitMux,
9
24
  PandaPcompDirection,
25
+ PandaPosMux,
10
26
  PandaTimeUnits,
11
27
  PcompBlock,
12
28
  SeqBlock,
13
29
  )
14
- from ._table import SeqTable
30
+ from ._table import SeqTable, SeqTrigger
15
31
 
16
32
 
17
33
  class SeqTableInfo(ConfinedModel):
@@ -22,6 +38,11 @@ class SeqTableInfo(ConfinedModel):
22
38
  prescale_as_us: float = Field(default=1, ge=0) # microseconds
23
39
 
24
40
 
41
+ class ScanSpecInfo(ConfinedModel):
42
+ spec: Spec[Motor]
43
+ deadtime: float
44
+
45
+
25
46
  class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
26
47
  """For controlling the PandA `SeqTable` when fly scanning."""
27
48
 
@@ -51,6 +72,105 @@ class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
51
72
  await wait_for_value(self.seq.active, False, timeout=1)
52
73
 
53
74
 
75
+ @dataclass
76
+ class PosOutScaleOffset:
77
+ name: str
78
+ scale: SignalRW[float]
79
+ offset: SignalRW[float]
80
+
81
+ @classmethod
82
+ def from_inenc(cls, panda: CommonPandaBlocks, number: int) -> PosOutScaleOffset:
83
+ inenc = panda.inenc[number] # type: ignore
84
+ return cls(
85
+ name=f"INENC{number}.VAL",
86
+ scale=inenc.val_scale, # type: ignore
87
+ offset=inenc.val_offset, # type: ignore
88
+ )
89
+
90
+
91
+ class ScanSpecSeqTableTriggerLogic(FlyerController[ScanSpecInfo]):
92
+ def __init__(
93
+ self,
94
+ seq: SeqBlock,
95
+ motor_pos_outs: dict[Motor, PosOutScaleOffset] | None = None,
96
+ ) -> None:
97
+ self.seq = seq
98
+ self.motor_pos_outs = motor_pos_outs or {}
99
+
100
+ async def prepare(self, value: ScanSpecInfo):
101
+ await self.seq.enable.set(PandaBitMux.ZERO)
102
+ slice = Path(value.spec.calculate()).consume()
103
+ slice_duration = error_if_none(slice.duration, "Slice must have duration")
104
+
105
+ # Start of window is where the is a gap to the previous point
106
+ window_start = np.nonzero(slice.gap)[0]
107
+ # End of window is either the next gap, or the end of the scan
108
+ window_end = np.append(window_start[1:], len(slice))
109
+ fast_axis = slice.axes()[-1]
110
+ pos_out = self.motor_pos_outs.get(fast_axis)
111
+ # If we have a motor to compare against, get its scale and offset
112
+ # otherwise don't connect POSA to anything
113
+ if pos_out is not None:
114
+ scale, offset = await asyncio.gather(
115
+ pos_out.scale.get_value(),
116
+ pos_out.offset.get_value(),
117
+ )
118
+ compare_pos_name = cast(PandaPosMux, pos_out.name)
119
+ else:
120
+ scale, offset = 1, 0
121
+ compare_pos_name = PandaPosMux.ZERO
122
+
123
+ rows = SeqTable.empty()
124
+ for start, end in zip(window_start, window_end, strict=True):
125
+ # GPIO goes low then high
126
+ rows += SeqTable.row(trigger=SeqTrigger.BITA_0)
127
+ rows += SeqTable.row(trigger=SeqTrigger.BITA_1)
128
+ # Wait for position if we are comparing against a motor
129
+ if pos_out is not None:
130
+ lower = (slice.lower[fast_axis][start] - offset) / scale
131
+ midpoint = (slice.midpoints[fast_axis][start] - offset) / scale
132
+ if midpoint > lower:
133
+ trigger = SeqTrigger.POSA_GT
134
+ elif midpoint < lower:
135
+ trigger = SeqTrigger.POSA_LT
136
+ else:
137
+ trigger = None
138
+ if trigger is not None:
139
+ rows += SeqTable.row(
140
+ trigger=trigger,
141
+ position=int(lower),
142
+ )
143
+
144
+ # Time based Triggers
145
+ rows += SeqTable.row(
146
+ repeats=end - start,
147
+ trigger=SeqTrigger.IMMEDIATE,
148
+ time1=int((slice_duration[0] - value.deadtime) * 10**6),
149
+ time2=int(value.deadtime * 10**6),
150
+ outa1=True,
151
+ outa2=False,
152
+ )
153
+ # Need to do units before value for PandA, otherwise it scales the current value
154
+ await self.seq.prescale_units.set(PandaTimeUnits.US)
155
+ await asyncio.gather(
156
+ self.seq.posa.set(compare_pos_name),
157
+ self.seq.prescale.set(1.0),
158
+ self.seq.repeats.set(1),
159
+ self.seq.table.set(rows),
160
+ )
161
+
162
+ async def kickoff(self) -> None:
163
+ await self.seq.enable.set(PandaBitMux.ONE)
164
+ await wait_for_value(self.seq.active, True, timeout=1)
165
+
166
+ async def complete(self) -> None:
167
+ await wait_for_value(self.seq.active, False, timeout=None)
168
+
169
+ async def stop(self):
170
+ await self.seq.enable.set(PandaBitMux.ZERO)
171
+ await wait_for_value(self.seq.active, False, timeout=1)
172
+
173
+
54
174
  class PcompInfo(ConfinedModel):
55
175
  """Info for the PandA `PcompBlock` for fly scanning."""
56
176
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ophyd-async
3
- Version: 0.13.3
3
+ Version: 0.13.4
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
@@ -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=MG7dROnfeBA5y43Gv6z8LsZSoCLYybK6UCAQ7R0xks4,706
4
+ ophyd_async/_version.py,sha256=jkUE3cKd2dkiA6VGIHg5JjUEnRJjfyS9aYL_45rUBmo,706
5
5
  ophyd_async/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- ophyd_async/core/__init__.py,sha256=KBj8v-Fxh8V1QKJYR0xAjoziqo1vjyblx45H7Jrikd0,4979
6
+ ophyd_async/core/__init__.py,sha256=xugzZ-bLD11qdk_bJYxPXEeDMRTxEPZzxxhMjp6KqW8,5015
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
@@ -22,7 +22,7 @@ ophyd_async/core/_signal.py,sha256=ghgxtfUG9vkwgvuu6qXa_ECux5-3j9WwxB5mN5G6jqU,2
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
25
- ophyd_async/core/_table.py,sha256=ai-_W-_WMZcy9f69BDYRv9vjVl-AVeOPN_uHYoGCSsc,6905
25
+ ophyd_async/core/_table.py,sha256=ryJ7AwJBglQUzwP9_aSjR8cu8EKvYXfo1q1byhke3Uc,7248
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
@@ -39,7 +39,7 @@ ophyd_async/epics/adaravis/_aravis_io.py,sha256=af639qsO2V8NU5I0LgxK8jrxuhXgM6eM
39
39
  ophyd_async/epics/adcore/__init__.py,sha256=NWNLe2uFqU86P5mYbKINfHHrUVoTHeDN6829-7lBHxE,1631
40
40
  ophyd_async/epics/adcore/_core_detector.py,sha256=m821Ji4WVMYd0CI5NOXSkHMiHzkO1aA0mvQzWrig6Z0,2592
41
41
  ophyd_async/epics/adcore/_core_io.py,sha256=hEz_yFB2pr7CyTN9JjC7RlLUPfhxjJ1r380XhYEcId4,9647
42
- ophyd_async/epics/adcore/_core_logic.py,sha256=L3XUPoTdGjNSh-DUKWS8Fkw-qhp1MzGI8GGDVPSuW0I,8884
42
+ ophyd_async/epics/adcore/_core_logic.py,sha256=QVphp-N2o0j4HrzSRISa21cb1oJdYdbFgwj8eFXwOGM,8972
43
43
  ophyd_async/epics/adcore/_core_writer.py,sha256=iQV5xodp63Fsoww1ply5dyQMIysVY_f6_EryzoNkjbk,8383
44
44
  ophyd_async/epics/adcore/_hdf_writer.py,sha256=nKXOjVZfM6_BlYv5f1l8nwo7tjenYjx-3AN18gzhUBA,6074
45
45
  ophyd_async/epics/adcore/_jpeg_writer.py,sha256=VYpUWQGEjrKG2kiRGQZlBCPXVJ1BzWb9GyB9KhxPWgo,688
@@ -83,9 +83,10 @@ ophyd_async/epics/demo/point_detector_channel.db,sha256=FZ9H6HjqplhcF2jgimv_dT1n
83
83
  ophyd_async/epics/odin/__init__.py,sha256=7kRqVzwoD8PVtp7Nj9iQWlgbLeoWE_8oiq-B0kixwTE,93
84
84
  ophyd_async/epics/odin/_odin_io.py,sha256=YDBrS15PnEKe5SHmz397Emh--lZSQEnbR3G7p8pbShY,6533
85
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=e1WNyHd-Tn1JENYGfDJJ5o66B9z8qYZXV3khNo9YStk,4118
88
- ophyd_async/epics/pmac/_utils.py,sha256=ahN5zMfO3-gNV7H1fQ5wsDeGUL9IpMQa2g27rhVf0uU,34326
86
+ ophyd_async/epics/pmac/_pmac_io.py,sha256=E7tdaq9FAM6BeGQG1L8ALEYpXOlyqTXl_NLLSWzmCdk,4345
87
+ ophyd_async/epics/pmac/_pmac_trajectory.py,sha256=7wTaetNNy9uj7C_skcs0VH5BthuY4Ec5zn-m4ROxd8k,7866
88
+ ophyd_async/epics/pmac/_pmac_trajectory_generation.py,sha256=l-jFlJCs2-LowoF6vJn2ex0Evcon2OeYPMHWzEZnEgk,27136
89
+ ophyd_async/epics/pmac/_utils.py,sha256=n4vh9n7hmaWe9g02FtguF2oDsYuVvsTgmK7fYEyGuIE,6092
89
90
  ophyd_async/epics/testing/__init__.py,sha256=aTIv4D2DYrpnGco5RQF8QuLG1SfFkIlTyM2uYEKXltA,522
90
91
  ophyd_async/epics/testing/_example_ioc.py,sha256=zb4ZEUzuB2MrSw5ETPLIiHhf-2BRU1Bdxco6Kh4iI1I,3880
91
92
  ophyd_async/epics/testing/_utils.py,sha256=9gxpwaWX0HGtacu1LTupcw7viXN8G78RmuNciU_-cjs,1702
@@ -97,18 +98,18 @@ ophyd_async/fastcs/eiger/__init__.py,sha256=RxwOFjERKy5tUD_IDGCGuMh716FaZgCq7R9e
97
98
  ophyd_async/fastcs/eiger/_eiger.py,sha256=jo3K5dM3Co_RDYIyO6poCVDqp2g_1z4MqnYftwnMhUk,1103
98
99
  ophyd_async/fastcs/eiger/_eiger_controller.py,sha256=Cucj-1M-1CaxSJxHZmHs3f_OXwtTIspcqUFhRNGzn_E,2361
99
100
  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
101
+ ophyd_async/fastcs/jungfrau/__init__.py,sha256=xwTaPiqvtyyljP2acz07FSlUW79Io8EsKks9ENgbumA,765
102
+ ophyd_async/fastcs/jungfrau/_controller.py,sha256=TvUxRuP3NJFTOcyHeMn5-1Va7HzOJswWCYSGdp1NMFI,5778
102
103
  ophyd_async/fastcs/jungfrau/_jungfrau.py,sha256=KAHCmRHMyzIh-r2JXVJcQOGLkCOOdW5Mao_KChITO2s,929
103
104
  ophyd_async/fastcs/jungfrau/_signals.py,sha256=8seZCkKTb-xJL0IdB2el8VTEbWNaCvZIhpP0609GpxI,2500
104
- ophyd_async/fastcs/jungfrau/_utils.py,sha256=-NeIlUW7Mx9llUC6FZORc6e-IAAOL9lwzzl07wc8lTc,2509
105
+ ophyd_async/fastcs/jungfrau/_utils.py,sha256=QpdWbPT_31Jwyi7INFMRq9hncSZIK_4J3l6wpuppzn8,2875
105
106
  ophyd_async/fastcs/odin/__init__.py,sha256=da1PTClDMl-IBkrSvq6JC1lnS-K_BASzCvxVhNxN5Ls,13
106
- ophyd_async/fastcs/panda/__init__.py,sha256=ugrScVm4HPQFc-d1kTAfZ5UUzW9T3SPgTi0OD2s8ZH0,1003
107
- ophyd_async/fastcs/panda/_block.py,sha256=SM7NaWCRwLz2Pl4wgjZMrDgx3ZLdGPTw6nU0bA-65yA,2394
107
+ ophyd_async/fastcs/panda/__init__.py,sha256=GbnPqH_13wvyPK1CvRHGAViamKVWHY9n-sTmfAdcnMA,1229
108
+ ophyd_async/fastcs/panda/_block.py,sha256=ejWajojXpP85kdWoB4zl6Z4s9S-Izs4brBdxosfjYbA,2645
108
109
  ophyd_async/fastcs/panda/_control.py,sha256=xtW3dH_MLQoycgP-4vJtYx1M9alHjWo13iu9UFTgwzY,1306
109
110
  ophyd_async/fastcs/panda/_hdf_panda.py,sha256=tL_OWHxlMQcMZGq9sxHLSeag6hP9MRIbTPn1W0u0iNI,1237
110
111
  ophyd_async/fastcs/panda/_table.py,sha256=maKGoKypEuYqTSVWGgDO6GMEKOtlDm9Dn5YiYdBzu6c,2486
111
- ophyd_async/fastcs/panda/_trigger.py,sha256=TLd0ST-ZgsCGpONGUe76qHOaH74TlZNIGNkh-10eRa8,3404
112
+ ophyd_async/fastcs/panda/_trigger.py,sha256=iBxW4YMfRYrpg7AoQaHb7rHKCE95UbSxguRuR9FOgw8,7610
112
113
  ophyd_async/fastcs/panda/_writer.py,sha256=UqsU44u0uIqkDNky3mIzhW3OhLeZ8TSqFS666qrRdmA,6181
113
114
  ophyd_async/plan_stubs/__init__.py,sha256=sRe1Jna_6i7aKjE3pPzsP4iNMWeWdtiptLnOq9pov9M,619
114
115
  ophyd_async/plan_stubs/_ensure_connected.py,sha256=YR6VRj7koccJ4x35NV-Ugl4ZbxgAoGN9PjVIjhv0gpw,894
@@ -153,8 +154,8 @@ ophyd_async/testing/_one_of_everything.py,sha256=U9ui7B-iNHDM3H3hIWUuaCb8Gc2eLlU
153
154
  ophyd_async/testing/_single_derived.py,sha256=5-HOTzgePcZ354NK_ssVpyIbJoJmKyjVQCxSwQXUC-4,2730
154
155
  ophyd_async/testing/_utils.py,sha256=zClRo5ve8RGia7wQnby41W-Zprj-slOA5da1LfYnuhw,45
155
156
  ophyd_async/testing/_wait_for_pending.py,sha256=YZAR48n-CW0GsPey3zFRzMJ4byDAr3HvMIoawjmTrHw,732
156
- ophyd_async-0.13.3.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
157
- ophyd_async-0.13.3.dist-info/METADATA,sha256=MJyMUgxAYadbFX6irChsIsegu_39gLCH0DKzhB8qOhs,7222
158
- ophyd_async-0.13.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
159
- ophyd_async-0.13.3.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
160
- ophyd_async-0.13.3.dist-info/RECORD,,
157
+ ophyd_async-0.13.4.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
158
+ ophyd_async-0.13.4.dist-info/METADATA,sha256=gy3t1HyZjSGBSDOguEsn4LV_SQ8duzNLIXhZgpm9qoI,7222
159
+ ophyd_async-0.13.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
160
+ ophyd_async-0.13.4.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
161
+ ophyd_async-0.13.4.dist-info/RECORD,,