Skip to content

Commit 32a1f85

Browse files
committed
fix: prefer empirical fs over header, extend measurement to 1.5s, warn on mismatch
1 parent 81f872e commit 32a1f85

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

examples/joint_angle_regression/open_ephys_lsl_streamer.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ def _wait_for_channels(self, timeout=3.0):
181181
start = _t.time()
182182
prev_count = 0
183183
stable_since = start
184+
channels_stable = False
184185

185186
# snapshot sample counter at start
186187
with self.client._lock:
@@ -192,8 +193,16 @@ def _wait_for_channels(self, timeout=3.0):
192193
if n != prev_count:
193194
prev_count = n
194195
stable_since = _t.time()
195-
elif (_t.time() - stable_since) >= 0.5:
196-
break
196+
elif not channels_stable and (_t.time() - stable_since) >= 0.5:
197+
channels_stable = True
198+
# Keep looping a bit longer to accumulate a better fs estimate.
199+
# We want at least 1 s of data total for a reliable rate.
200+
min_end = start + 1.5
201+
if _t.time() >= min_end:
202+
break
203+
elif channels_stable:
204+
if _t.time() >= start + 1.5:
205+
break
197206
_t.sleep(0.05)
198207

199208
elapsed = max(_t.time() - start, 1e-6)
@@ -255,7 +264,8 @@ def start(self):
255264
# 3. Header-reported sample_rate (client.fs)
256265
# The empirical rate is the most trustworthy when available because
257266
# it reflects actual data throughput rather than a header field that
258-
# some plugins may set incorrectly.
267+
# some plugins may set incorrectly (e.g. reporting the hardware Intan
268+
# chip rate of 30/40 kHz instead of the software-decimated rate).
259269
header_fs = float(self.client.fs)
260270
self._header_fs = header_fs
261271
self._measured_fs = round(measured_fs)
@@ -265,7 +275,16 @@ def start(self):
265275
self.detected_fs = self.expected_fs
266276
elif measured_fs > 100:
267277
# Round to nearest "nice" rate (multiple of 250 or 1000)
268-
self.detected_fs = self._round_fs(measured_fs)
278+
rounded = self._round_fs(measured_fs)
279+
self.detected_fs = rounded
280+
# Warn if header claims something very different
281+
if header_fs > 0 and abs(header_fs - rounded) / max(header_fs, 1) > 0.15:
282+
import warnings
283+
warnings.warn(
284+
f"ZMQ header reports sample_rate={header_fs:.0f} Hz but "
285+
f"empirical throughput is ~{rounded:.0f} Hz. "
286+
f"Using measured rate. Override with --fs if needed."
287+
)
269288
elif header_fs > 0:
270289
self.detected_fs = header_fs
271290
else:

0 commit comments

Comments
 (0)