ophyd-async 0.10.1__py3-none-any.whl → 0.12__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 (39) hide show
  1. ophyd_async/_version.py +2 -2
  2. ophyd_async/core/__init__.py +12 -1
  3. ophyd_async/core/_derived_signal.py +68 -22
  4. ophyd_async/core/_derived_signal_backend.py +46 -24
  5. ophyd_async/core/_detector.py +3 -3
  6. ophyd_async/core/_device.py +24 -16
  7. ophyd_async/core/_flyer.py +39 -5
  8. ophyd_async/core/_hdf_dataset.py +11 -10
  9. ophyd_async/core/_signal.py +58 -30
  10. ophyd_async/core/_table.py +3 -3
  11. ophyd_async/core/_utils.py +25 -0
  12. ophyd_async/core/_yaml_settings.py +3 -3
  13. ophyd_async/epics/adandor/__init__.py +7 -1
  14. ophyd_async/epics/adandor/_andor_controller.py +5 -8
  15. ophyd_async/epics/adandor/_andor_io.py +12 -19
  16. ophyd_async/epics/adcore/_hdf_writer.py +12 -19
  17. ophyd_async/epics/core/_signal.py +8 -3
  18. ophyd_async/epics/eiger/_odin_io.py +4 -2
  19. ophyd_async/epics/motor.py +47 -97
  20. ophyd_async/epics/pmac/__init__.py +3 -0
  21. ophyd_async/epics/pmac/_pmac_io.py +100 -0
  22. ophyd_async/fastcs/eiger/__init__.py +1 -2
  23. ophyd_async/fastcs/eiger/_eiger.py +3 -9
  24. ophyd_async/fastcs/panda/_trigger.py +8 -8
  25. ophyd_async/fastcs/panda/_writer.py +15 -13
  26. ophyd_async/plan_stubs/__init__.py +0 -8
  27. ophyd_async/plan_stubs/_fly.py +0 -204
  28. ophyd_async/sim/__init__.py +1 -2
  29. ophyd_async/sim/_blob_detector_writer.py +6 -12
  30. ophyd_async/sim/_mirror_horizontal.py +3 -2
  31. ophyd_async/sim/_mirror_vertical.py +1 -0
  32. ophyd_async/sim/_motor.py +13 -43
  33. ophyd_async/testing/__init__.py +2 -0
  34. ophyd_async/testing/_assert.py +34 -6
  35. {ophyd_async-0.10.1.dist-info → ophyd_async-0.12.dist-info}/METADATA +4 -3
  36. {ophyd_async-0.10.1.dist-info → ophyd_async-0.12.dist-info}/RECORD +39 -37
  37. {ophyd_async-0.10.1.dist-info → ophyd_async-0.12.dist-info}/WHEEL +0 -0
  38. {ophyd_async-0.10.1.dist-info → ophyd_async-0.12.dist-info}/licenses/LICENSE +0 -0
  39. {ophyd_async-0.10.1.dist-info → ophyd_async-0.12.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,6 @@ from bluesky.protocols import (
14
14
  Stoppable,
15
15
  Subscribable,
16
16
  )
17
- from pydantic import BaseModel, Field
18
17
 
19
18
  from ophyd_async.core import (
20
19
  CALCULATE_TIMEOUT,
@@ -22,16 +21,18 @@ from ophyd_async.core import (
22
21
  AsyncStatus,
23
22
  CalculatableTimeout,
24
23
  Callback,
24
+ FlyMotorInfo,
25
25
  StandardReadable,
26
26
  StrictEnum,
27
27
  WatchableAsyncStatus,
28
28
  WatcherUpdate,
29
+ error_if_none,
29
30
  observe_value,
30
31
  )
31
32
  from ophyd_async.core import StandardReadableFormat as Format
32
33
  from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_w
33
34
 
34
- __all__ = ["MotorLimitsException", "FlyMotorInfo", "Motor"]
35
+ __all__ = ["MotorLimitsException", "Motor"]
35
36
 
36
37
 
37
38
  class MotorLimitsException(Exception):
@@ -40,26 +41,6 @@ class MotorLimitsException(Exception):
40
41
  pass
41
42
 
42
43
 
43
- class FlyMotorInfo(BaseModel):
44
- """Minimal set of information required to fly a motor."""
45
-
46
- start_position: float = Field(frozen=True)
47
- """Absolute position of the motor once it finishes accelerating to desired
48
- velocity, in motor EGUs"""
49
-
50
- end_position: float = Field(frozen=True)
51
- """Absolute position of the motor once it begins decelerating from desired
52
- velocity, in EGUs"""
53
-
54
- time_for_move: float = Field(frozen=True, gt=0)
55
- """Time taken for the motor to get from start_position to end_position, excluding
56
- run-up and run-down, in seconds."""
57
-
58
- timeout: CalculatableTimeout = Field(frozen=True, default=CALCULATE_TIMEOUT)
59
- """Maximum time for the complete motor move, including run up and run down.
60
- Defaults to `time_for_move` + run up and run down times + 10s."""
61
-
62
-
63
44
  class OffsetMode(StrictEnum):
64
45
  VARIABLE = "Variable"
65
46
  FROZEN = "Frozen"
@@ -111,15 +92,12 @@ class Motor(
111
92
  # Whether set() should complete successfully or not
112
93
  self._set_success = True
113
94
 
114
- # end_position of a fly move, with run_up_distance added on.
115
- self._fly_completed_position: float | None = None
95
+ # Currently requested fly info, stored in prepare
96
+ self._fly_info: FlyMotorInfo | None = None
116
97
 
117
98
  # Set on kickoff(), complete when motor reaches self._fly_completed_position
118
99
  self._fly_status: WatchableAsyncStatus | None = None
119
100
 
120
- # Set during prepare
121
- self._fly_timeout: CalculatableTimeout | None = CALCULATE_TIMEOUT
122
-
123
101
  super().__init__(name=name)
124
102
 
125
103
  def set_name(self, name: str, *, child_name_separator: str | None = None) -> None:
@@ -130,42 +108,65 @@ class Motor(
130
108
 
131
109
  @AsyncStatus.wrap
132
110
  async def prepare(self, value: FlyMotorInfo):
133
- """Move to the beginning of a suitable run-up distance ready for a flyscan."""
134
- self._fly_timeout = value.timeout
111
+ """Move to the beginning of a suitable run-up distance ready for a fly scan."""
112
+ self._fly_info = value
135
113
 
136
114
  # Velocity, at which motor travels from start_position to end_position, in motor
137
115
  # egu/s.
138
- fly_velocity = await self._prepare_velocity(
139
- value.start_position,
140
- value.end_position,
141
- value.time_for_move,
116
+ max_speed, egu = await asyncio.gather(
117
+ self.max_velocity.get_value(), self.motor_egu.get_value()
142
118
  )
119
+ if abs(value.velocity) > max_speed:
120
+ raise MotorLimitsException(
121
+ f"Velocity {abs(value.velocity)} {egu}/s was requested for a motor "
122
+ f" with max speed of {max_speed} {egu}/s"
123
+ )
124
+
125
+ acceleration_time = await self.acceleration_time.get_value()
126
+ ramp_up_start_pos = value.ramp_up_start_pos(acceleration_time)
127
+ ramp_down_end_pos = value.ramp_down_end_pos(acceleration_time)
143
128
 
144
- # start_position with run_up_distance added on.
145
- fly_prepared_position = await self._prepare_motor_path(
146
- abs(fly_velocity), value.start_position, value.end_position
129
+ motor_lower_limit, motor_upper_limit, egu = await asyncio.gather(
130
+ self.low_limit_travel.get_value(),
131
+ self.high_limit_travel.get_value(),
132
+ self.motor_egu.get_value(),
147
133
  )
148
134
 
149
- await self.set(fly_prepared_position)
150
- await self.velocity.set(abs(fly_velocity))
135
+ if (
136
+ not motor_upper_limit >= ramp_up_start_pos >= motor_lower_limit
137
+ or not motor_upper_limit >= ramp_down_end_pos >= motor_lower_limit
138
+ ):
139
+ raise MotorLimitsException(
140
+ f"Motor trajectory for requested fly is from "
141
+ f"{ramp_up_start_pos}{egu} to "
142
+ f"{ramp_down_end_pos}{egu} but motor limits are "
143
+ f"{motor_lower_limit}{egu} <= x <= {motor_upper_limit}{egu} "
144
+ )
145
+
146
+ # move to prepare position at maximum velocity
147
+ await self.velocity.set(abs(max_speed))
148
+ await self.set(ramp_up_start_pos)
149
+
150
+ # Set velocity we will be using for the fly scan
151
+ await self.velocity.set(abs(value.velocity))
151
152
 
152
153
  @AsyncStatus.wrap
153
154
  async def kickoff(self):
154
155
  """Begin moving motor from prepared position to final position."""
155
- if not self._fly_completed_position:
156
- msg = "Motor must be prepared before attempting to kickoff"
157
- raise RuntimeError(msg)
156
+ fly_info = error_if_none(
157
+ self._fly_info, "Motor must be prepared before attempting to kickoff"
158
+ )
158
159
 
160
+ acceleration_time = await self.acceleration_time.get_value()
159
161
  self._fly_status = self.set(
160
- self._fly_completed_position, timeout=self._fly_timeout
162
+ fly_info.ramp_down_end_pos(acceleration_time),
163
+ timeout=fly_info.timeout,
161
164
  )
162
165
 
163
166
  def complete(self) -> WatchableAsyncStatus:
164
167
  """Mark as complete once motor reaches completed position."""
165
- if not self._fly_status:
166
- msg = "kickoff not called"
167
- raise RuntimeError(msg)
168
- return self._fly_status
168
+ fly_status = error_if_none(self._fly_status, "kickoff not called")
169
+ return fly_status
169
170
 
170
171
  @WatchableAsyncStatus.wrap
171
172
  async def set( # type: ignore
@@ -220,22 +221,6 @@ class Motor(
220
221
  # the move above, so need to pass wait=False
221
222
  await self.motor_stop.set(1, wait=False)
222
223
 
223
- async def _prepare_velocity(
224
- self, start_position: float, end_position: float, time_for_move: float
225
- ) -> float:
226
- fly_velocity = (end_position - start_position) / time_for_move
227
- max_speed, egu = await asyncio.gather(
228
- self.max_velocity.get_value(), self.motor_egu.get_value()
229
- )
230
- if abs(fly_velocity) > max_speed:
231
- raise MotorLimitsException(
232
- f"Motor speed of {abs(fly_velocity)} {egu}/s was requested for a motor "
233
- f" with max speed of {max_speed} {egu}/s"
234
- )
235
- # move to prepare position at maximum velocity
236
- await self.velocity.set(abs(max_speed))
237
- return fly_velocity
238
-
239
224
  async def locate(self) -> Location[float]:
240
225
  """Return the current setpoint and readback of the motor."""
241
226
  setpoint, readback = await asyncio.gather(
@@ -250,38 +235,3 @@ class Motor(
250
235
  def clear_sub(self, function: Callback[dict[str, Reading[float]]]) -> None:
251
236
  """Unsubscribe."""
252
237
  self.user_readback.clear_sub(function)
253
-
254
- async def _prepare_motor_path(
255
- self, fly_velocity: float, start_position: float, end_position: float
256
- ) -> float:
257
- # Distance required for motor to accelerate from stationary to fly_velocity, and
258
- # distance required for motor to decelerate from fly_velocity to stationary
259
- run_up_distance = (
260
- (await self.acceleration_time.get_value()) * fly_velocity * 0.5
261
- )
262
-
263
- direction = 1 if end_position > start_position else -1
264
- self._fly_completed_position = end_position + (run_up_distance * direction)
265
-
266
- # Prepared position not used after prepare, so no need to store in self
267
- fly_prepared_position = start_position - (run_up_distance * direction)
268
-
269
- motor_lower_limit, motor_upper_limit, egu = await asyncio.gather(
270
- self.low_limit_travel.get_value(),
271
- self.high_limit_travel.get_value(),
272
- self.motor_egu.get_value(),
273
- )
274
-
275
- if (
276
- not motor_upper_limit >= fly_prepared_position >= motor_lower_limit
277
- or not motor_upper_limit
278
- >= self._fly_completed_position
279
- >= motor_lower_limit
280
- ):
281
- raise MotorLimitsException(
282
- f"Motor trajectory for requested fly is from "
283
- f"{fly_prepared_position}{egu} to "
284
- f"{self._fly_completed_position}{egu} but motor limits are "
285
- f"{motor_lower_limit}{egu} <= x <= {motor_upper_limit}{egu} "
286
- )
287
- return fly_prepared_position
@@ -0,0 +1,3 @@
1
+ from ._pmac_io import PmacAxisIO, PmacCoordIO, PmacIO, PmacTrajectoryIO
2
+
3
+ __all__ = ["PmacAxisIO", "PmacCoordIO", "PmacIO", "PmacTrajectoryIO"]
@@ -0,0 +1,100 @@
1
+ from collections.abc import Sequence
2
+
3
+ import numpy as np
4
+
5
+ from ophyd_async.core import Array1D, Device, DeviceVector, StandardReadable
6
+ from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
7
+
8
+ CS_LETTERS = "ABCUVWXYZ"
9
+
10
+
11
+ class PmacTrajectoryIO(StandardReadable):
12
+ """Device that moves a PMAC Motor record."""
13
+
14
+ def __init__(self, prefix: str, name: str = "") -> None:
15
+ self.time_array = epics_signal_rw(
16
+ Array1D[np.float64], prefix + ":ProfileTimeArray"
17
+ )
18
+ self.user_array = epics_signal_rw(Array1D[np.int32], prefix + ":UserArray")
19
+ # 1 indexed CS axes so we can index into them from the compound motor input link
20
+ self.positions = DeviceVector(
21
+ {
22
+ i + 1: epics_signal_rw(
23
+ Array1D[np.float64], f"{prefix}:{letter}:Positions"
24
+ )
25
+ for i, letter in enumerate(CS_LETTERS)
26
+ }
27
+ )
28
+ self.use_axis = DeviceVector(
29
+ {
30
+ i + 1: epics_signal_rw(bool, f"{prefix}:{letter}:UseAxis")
31
+ for i, letter in enumerate(CS_LETTERS)
32
+ }
33
+ )
34
+ self.velocities = DeviceVector(
35
+ {
36
+ i + 1: epics_signal_rw(
37
+ Array1D[np.float64], f"{prefix}:{letter}:Velocities"
38
+ )
39
+ for i, letter in enumerate(CS_LETTERS)
40
+ }
41
+ )
42
+ self.points_to_build = epics_signal_rw(int, prefix + ":ProfilePointsToBuild")
43
+ self.build_profile = epics_signal_rw(bool, prefix + ":ProfileBuild")
44
+ self.execute_profile = epics_signal_rw(bool, prefix + ":ProfileExecute")
45
+ self.scan_percent = epics_signal_r(float, prefix + ":TscanPercent_RBV")
46
+ self.abort_profile = epics_signal_rw(bool, prefix + ":ProfileAbort")
47
+ self.profile_cs_name = epics_signal_rw(str, prefix + ":ProfileCsName")
48
+ self.calculate_velocities = epics_signal_rw(bool, prefix + ":ProfileCalcVel")
49
+
50
+ super().__init__(name=name)
51
+
52
+
53
+ class PmacAxisIO(Device):
54
+ """A Device that (direct) moves a PMAC Coordinate System Motor.
55
+
56
+ Note that this does not go through a motor record.
57
+ """
58
+
59
+ def __init__(self, prefix: str, name: str = "") -> None:
60
+ self.cs_axis_letter = epics_signal_r(str, f"{prefix}:CsAxis_RBV")
61
+ self.cs_port = epics_signal_r(str, f"{prefix}:CsPort_RBV")
62
+ super().__init__(name=name)
63
+
64
+
65
+ class PmacCoordIO(Device):
66
+ """A Device that represents a Pmac Coordinate System."""
67
+
68
+ def __init__(self, prefix: str, name: str = "") -> None:
69
+ self.defer_moves = epics_signal_r(bool, f"{prefix}:DeferMoves")
70
+ self.cs_axis_setpoint = DeviceVector(
71
+ {
72
+ i + 1: epics_signal_rw(
73
+ Array1D[np.float64], f"{prefix}:M{i + 1}:DirectDemand"
74
+ )
75
+ for i in range(len(CS_LETTERS))
76
+ }
77
+ )
78
+ super().__init__(name=name)
79
+
80
+
81
+ class PmacIO(Device):
82
+ """Device that represents a pmac controller."""
83
+
84
+ def __init__(
85
+ self,
86
+ prefix: str,
87
+ axis_nums: Sequence[int],
88
+ coord_nums: Sequence[int],
89
+ name: str = "",
90
+ ) -> None:
91
+ self.axis = DeviceVector(
92
+ {axis: PmacAxisIO(f"{prefix}:M{axis}") for axis in axis_nums}
93
+ )
94
+ self.coord = DeviceVector(
95
+ {coord: PmacCoordIO(f"{prefix}:CS{coord}") for coord in coord_nums}
96
+ )
97
+ # Trajectory PVs have the same prefix as the pmac device
98
+ self.trajectory = PmacTrajectoryIO(prefix)
99
+
100
+ super().__init__(name=name)
@@ -1,4 +1,4 @@
1
- from ._eiger import EigerDetector, EigerTriggerInfo
1
+ from ._eiger import EigerDetector
2
2
  from ._eiger_controller import EigerController
3
3
  from ._eiger_io import EigerDetectorIO, EigerDriverIO, EigerMonitorIO, EigerStreamIO
4
4
 
@@ -6,7 +6,6 @@ __all__ = [
6
6
  "EigerDetector",
7
7
  "EigerController",
8
8
  "EigerDriverIO",
9
- "EigerTriggerInfo",
10
9
  "EigerDetectorIO",
11
10
  "EigerMonitorIO",
12
11
  "EigerStreamIO",
@@ -1,5 +1,3 @@
1
- from pydantic import Field
2
-
3
1
  from ophyd_async.core import (
4
2
  AsyncStatus,
5
3
  PathProvider,
@@ -12,10 +10,6 @@ from ._eiger_controller import EigerController
12
10
  from ._eiger_io import EigerDriverIO
13
11
 
14
12
 
15
- class EigerTriggerInfo(TriggerInfo):
16
- energy_ev: float = Field(gt=0)
17
-
18
-
19
13
  class EigerDetector(StandardDetector):
20
14
  """Ophyd-async implementation of an Eiger Detector."""
21
15
 
@@ -28,10 +22,11 @@ class EigerDetector(StandardDetector):
28
22
  path_provider: PathProvider,
29
23
  drv_suffix="-EA-EIGER-01:",
30
24
  hdf_suffix="-EA-EIGER-01:OD:",
25
+ odin_nodes: int = 4,
31
26
  name="",
32
27
  ):
33
28
  self.drv = EigerDriverIO(prefix + drv_suffix)
34
- self.odin = Odin(prefix + hdf_suffix)
29
+ self.odin = Odin(prefix + hdf_suffix, nodes=odin_nodes)
35
30
 
36
31
  super().__init__(
37
32
  EigerController(self.drv),
@@ -44,6 +39,5 @@ class EigerDetector(StandardDetector):
44
39
  )
45
40
 
46
41
  @AsyncStatus.wrap
47
- async def prepare(self, value: EigerTriggerInfo) -> None: # type: ignore
48
- await self._controller.set_energy(value.energy_ev)
42
+ async def prepare(self, value: TriggerInfo) -> None:
49
43
  await super().prepare(value)
@@ -1,8 +1,8 @@
1
1
  import asyncio
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import Field
4
4
 
5
- from ophyd_async.core import FlyerController, wait_for_value
5
+ from ophyd_async.core import ConfinedModel, FlyerController, wait_for_value
6
6
 
7
7
  from ._block import (
8
8
  PandaBitMux,
@@ -14,8 +14,8 @@ from ._block import (
14
14
  from ._table import SeqTable
15
15
 
16
16
 
17
- class SeqTableInfo(BaseModel):
18
- """Info for the PandA `SeqTable` for flyscanning."""
17
+ class SeqTableInfo(ConfinedModel):
18
+ """Info for the PandA `SeqTable` for fly scanning."""
19
19
 
20
20
  sequence_table: SeqTable = Field(strict=True)
21
21
  repeats: int = Field(ge=0)
@@ -23,7 +23,7 @@ class SeqTableInfo(BaseModel):
23
23
 
24
24
 
25
25
  class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
26
- """For controlling the PandA `SeqTable` when flyscanning."""
26
+ """For controlling the PandA `SeqTable` when fly scanning."""
27
27
 
28
28
  def __init__(self, seq: SeqBlock) -> None:
29
29
  self.seq = seq
@@ -51,8 +51,8 @@ class StaticSeqTableTriggerLogic(FlyerController[SeqTableInfo]):
51
51
  await wait_for_value(self.seq.active, False, timeout=1)
52
52
 
53
53
 
54
- class PcompInfo(BaseModel):
55
- """Info for the PandA `PcompBlock` for flyscanning."""
54
+ class PcompInfo(ConfinedModel):
55
+ """Info for the PandA `PcompBlock` for fly scanning."""
56
56
 
57
57
  start_postion: int = Field(description="start position in counts")
58
58
  pulse_width: int = Field(description="width of a single pulse in counts", gt=0)
@@ -76,7 +76,7 @@ class PcompInfo(BaseModel):
76
76
 
77
77
 
78
78
  class StaticPcompTriggerLogic(FlyerController[PcompInfo]):
79
- """For controlling the PandA `PcompBlock` when flyscanning."""
79
+ """For controlling the PandA `PcompBlock` when fly scanning."""
80
80
 
81
81
  def __init__(self, pcomp: PcompBlock) -> None:
82
82
  self.pcomp = pcomp
@@ -33,12 +33,12 @@ class PandaHDFWriter(DetectorWriter):
33
33
 
34
34
  # Triggered on PCAP arm
35
35
  async def open(self, name: str, exposures_per_event: int = 1) -> dict[str, DataKey]:
36
+ self._composer = None
36
37
  """Retrieve and get descriptor of all PandA signals marked for capture."""
37
38
  self._exposures_per_event = exposures_per_event
38
39
  # Ensure flushes are immediate
39
40
  await self.panda_data_block.flush_period.set(0)
40
41
 
41
- self._composer = None
42
42
  info = self._path_provider(device_name=name)
43
43
 
44
44
  # Set create dir depth first to guarantee that callback when setting
@@ -64,7 +64,15 @@ class PandaHDFWriter(DetectorWriter):
64
64
  # Wait for it to start, stashing the status that tells us when it finishes
65
65
  await self.panda_data_block.capture.set(True)
66
66
 
67
- return await self._describe(name)
67
+ describe = await self._describe(name)
68
+
69
+ self._composer = HDFDocumentComposer(
70
+ Path(await self.panda_data_block.hdf_directory.get_value())
71
+ / Path(await self.panda_data_block.hdf_file_name.get_value()),
72
+ self._datasets,
73
+ )
74
+
75
+ return describe
68
76
 
69
77
  async def _describe(self, name: str) -> dict[str, DataKey]:
70
78
  """Return a describe based on the datasets PV."""
@@ -145,17 +153,11 @@ class PandaHDFWriter(DetectorWriter):
145
153
  self, name: str, indices_written: int
146
154
  ) -> AsyncIterator[StreamAsset]:
147
155
  # TODO: fail if we get dropped frames
148
- if indices_written:
149
- if not self._composer:
150
- self._composer = HDFDocumentComposer(
151
- Path(await self.panda_data_block.hdf_directory.get_value())
152
- / Path(await self.panda_data_block.hdf_file_name.get_value()),
153
- self._datasets,
154
- )
155
- for doc in self._composer.stream_resources():
156
- yield "stream_resource", doc
157
- for doc in self._composer.stream_data(indices_written):
158
- yield "stream_datum", doc
156
+ if self._composer is None:
157
+ msg = f"open() not called on {self}"
158
+ raise RuntimeError(msg)
159
+ for doc in self._composer.make_stream_docs(indices_written):
160
+ yield doc
159
161
 
160
162
  # Could put this function as default for StandardDetector
161
163
  async def close(self):
@@ -1,11 +1,6 @@
1
1
  """Plan stubs for connecting, setting up and flying devices."""
2
2
 
3
3
  from ._ensure_connected import ensure_connected
4
- from ._fly import (
5
- fly_and_collect,
6
- prepare_static_seq_table_flyer_and_detectors_with_same_trigger,
7
- time_resolved_fly_and_collect_with_static_seq_table,
8
- )
9
4
  from ._nd_attributes import setup_ndattributes, setup_ndstats_sum
10
5
  from ._panda import apply_panda_settings
11
6
  from ._settings import (
@@ -17,9 +12,6 @@ from ._settings import (
17
12
  )
18
13
 
19
14
  __all__ = [
20
- "fly_and_collect",
21
- "prepare_static_seq_table_flyer_and_detectors_with_same_trigger",
22
- "time_resolved_fly_and_collect_with_static_seq_table",
23
15
  "ensure_connected",
24
16
  "setup_ndattributes",
25
17
  "setup_ndstats_sum",