You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've also experienced labstreaminglayer/pylsl#67, so was happy to see this new feature (#150, #158, #160). However, in my data it seems to drop valid samples more often than I'd like!
A quick fix could be to expose the time_thresh and value_thresh parameters in the top-level load_xdf().
But digging a little deeper, good samples seem to be dropped most often in streams running on the same host as LabRecorder. As these typically have tiny clock offsets (±4e-05) it's quite easy for reasonable jitter (e.g. ±2e-05) to be flagged as an outlier according to the MAD threshold.
As I understand it _detect_corrupted_clock_offset() is effectively looking for a clock reset between the entire clock offset history and the final measurement. As such, significant drift and genuine clock resets could also bias the statistic. The logic is similar to _detect_clock_resets(), but an important difference there is we take the first derivative of clock offsets as the basis for MAD.
Adding some np.diff() calls to "Strategy 2" in _detect_corrupted_clock_offset() seems to restore my dropped samples, but I'm not sure to what extent the current implementation is necessary in addition to what _detect_clock_resets() already does.
Hmmm, thanks for the input and the tests. We should think about the current mechanism and how we could make it more robust. I had the impression that this was a fix for something very obviously wrong, but if this is affecting (i.e., dropping) perfectly valid samples, we should come up with a better solution ASAP. @mscheltienne WDYT?
I should add the data I'm looking at was recorded prior to labstreaminglayer/App-LabRecorder#123, so all my footer sample counts are off-by-one - making this partly a backwards compatibility issue.
As far as I can see #167 makes the existing _detect_clock_resets() handle corrupt offsets correctly, without dropping any samples. However, this doesn't guarantee the final sample is valid, beyond ensuring it's detected as part of a different clock segment if the sample time-stamp is closer to the start of the corrupt clock segment than the end of the valid clock segment.
If your data requires continuing to handle corrupt offsets as a special case, one possibility to avoid adding two new parameters to load_xdf() could be to use _detect_clock_resets() instead of the dedicated _detect_corrupted_clock_offset() function. Or at least make the calculation of MAD consistent across both functions so they can both use the existing reset_threshold* parameters?
FWIW I just tried replacing this:
if len(stream.clock_times) >= 3:
clock_corrupted = _detect_corrupted_clock_offset(
stream.clock_times, stream.clock_values
)
with:
clock_segments = _detect_clock_resets(
stream,
reset_threshold_stds,
reset_threshold_seconds,
reset_threshold_offset_stds,
reset_threshold_offset_seconds
)
if len(clock_segments) > 0:
final_segment = clock_segments[-1]
if final_segment[0] == final_segment[1]:
# Redundant (=corrupt) final clock segment.
clock_corrupted = True
and the existing truncate_corrupted_offsets tests still passed.
Hey, @jamieforth - can you give a shot to #178 ?
On our file (I actually manage to find only one of the files I used in the past..) it seems to work while removing the truncation entirely thanks to a better fix in #167
Activity
cbrnr commentedon Sep 10, 2026
Hmmm, thanks for the input and the tests. We should think about the current mechanism and how we could make it more robust. I had the impression that this was a fix for something very obviously wrong, but if this is affecting (i.e., dropping) perfectly valid samples, we should come up with a better solution ASAP. @mscheltienne WDYT?
jamieforth commentedon Sep 10, 2026
I should add the data I'm looking at was recorded prior to labstreaminglayer/App-LabRecorder#123, so all my footer sample counts are off-by-one - making this partly a backwards compatibility issue.
As far as I can see #167 makes the existing
_detect_clock_resets()handle corrupt offsets correctly, without dropping any samples. However, this doesn't guarantee the final sample is valid, beyond ensuring it's detected as part of a different clock segment if the sample time-stamp is closer to the start of the corrupt clock segment than the end of the valid clock segment.If your data requires continuing to handle corrupt offsets as a special case, one possibility to avoid adding two new parameters to
load_xdf()could be to use_detect_clock_resets()instead of the dedicated_detect_corrupted_clock_offset()function. Or at least make the calculation of MAD consistent across both functions so they can both use the existingreset_threshold*parameters?FWIW I just tried replacing this:
with:
and the existing
truncate_corrupted_offsetstests still passed.mscheltienne commentedon Sep 29, 2026
Hey, @jamieforth - can you give a shot to #178 ?
On our file (I actually manage to find only one of the files I used in the past..) it seems to work while removing the truncation entirely thanks to a better fix in #167