summaryrefslogtreecommitdiff
path: root/core/acquisition.py
diff options
context:
space:
mode:
Diffstat (limited to 'core/acquisition.py')
-rw-r--r--core/acquisition.py41
1 files changed, 32 insertions, 9 deletions
diff --git a/core/acquisition.py b/core/acquisition.py
index a984c71..4fffb8b 100644
--- a/core/acquisition.py
+++ b/core/acquisition.py
@@ -33,13 +33,22 @@ class ChannelBuffer:
self.values.append(v)
def window(self, seconds: float) -> Tuple[List[float], List[float]]:
+ """Last `seconds` of data. Walks in from the newest sample only —
+ cost is proportional to the window size, not the full buffer
+ (which can hold far more history than is ever displayed)."""
if not self.times:
return [], []
cutoff = self.times[-1] - seconds
- ts = list(self.times)
- vs = list(self.values)
- idx = next((i for i, t in enumerate(ts) if t >= cutoff), 0)
- return ts[idx:], vs[idx:]
+ out_t: List[float] = []
+ out_v: List[float] = []
+ for t, v in zip(reversed(self.times), reversed(self.values)):
+ if t < cutoff:
+ break
+ out_t.append(t)
+ out_v.append(v)
+ out_t.reverse()
+ out_v.reverse()
+ return out_t, out_v
def all(self) -> Tuple[List[float], List[float]]:
return list(self.times), list(self.values)
@@ -61,13 +70,14 @@ class AcquisitionEngine(QObject):
Signals
-------
- new_data(device_id, channel_id, timestamp, value)
+ new_data(timestamp, readings) # readings: list[(device_id, channel_id, value)] —
+ # one batched emit per poll tick, not one per channel
device_status_changed(device_id, status_str)
log_started(filepath)
log_stopped(filepath)
"""
- new_data = pyqtSignal(str, str, float, float)
+ new_data = pyqtSignal(float, list)
device_status_changed = pyqtSignal(str, str)
log_started = pyqtSignal(str)
log_stopped = pyqtSignal(str)
@@ -109,6 +119,14 @@ class AcquisitionEngine(QObject):
# ── Start / stop ─────────────────────────────────────────────────────
+ def is_running(self) -> bool:
+ return self._running
+
+ def elapsed_now(self) -> float:
+ """Wall-clock elapsed since start() — lets the UI scroll the strip
+ chart smoothly between poll ticks instead of only on data arrival."""
+ return time.time() - self._t0 if self._running else 0.0
+
def start(self):
if self._running:
return
@@ -165,6 +183,7 @@ class AcquisitionEngine(QObject):
t_start = time.time()
elapsed = t_start - self._t0
log_row = [f"{elapsed:.4f}"]
+ batch: List[Tuple[str, str, float]] = []
for dev in list(self._devices):
active = dev.status in (DeviceStatus.CONNECTED, DeviceStatus.SIMULATED)
@@ -179,11 +198,15 @@ class AcquisitionEngine(QObject):
if val is None or not ch.enabled:
log_row.append("")
continue
+ fval = float(val)
buf = self._buffers.get(dev.info.device_id, {}).get(ch.channel_id)
if buf is not None:
- buf.append(elapsed, float(val))
- self.new_data.emit(dev.info.device_id, ch.channel_id, elapsed, float(val))
- log_row.append(f"{val:.5f}")
+ buf.append(elapsed, fval)
+ batch.append((dev.info.device_id, ch.channel_id, fval))
+ log_row.append(f"{fval:.5f}")
+
+ if batch:
+ self.new_data.emit(elapsed, batch)
if self._logging and self._csv_writer:
try: