Trim repetitive game ts rather than arbitrary barcodes droped at the start - #356
Conversation
|
few notes:
Potential fixes to Barcodes Table (but maybe different PR) which had 2 additional edge-case failures:
|
arturoptophys
left a comment
There was a problem hiding this comment.
Maybe suggestion for additional fields which capture the fixes/ quality better:
definition = """
-> vr_barcodes.TeensyBarcodes
-> np_barcodes.ProbeBarcodeExtraction
---
slope: float64 # Slope of the linear fit mapping VR time to NP time
intercept: float64 # Intercept of the linear fit mapping VR time to NP time
r2: float64 # R-squared of the fit. NOT a quality signal -- gate on rmse_ms
rmse_ms: float64 # RMS fit residual in milliseconds; the quality gate
max_abs_residual_ms: float64 # Largest single tie-point residual, milliseconds
n_shared_barcodes: int32 # Tie points the fit actually used
n_trimmed_leading: int32 # Leading events dropped as a repetitive onset_time_unity run
n_trimmed_trailing: int32 # Trailing events dropped as a repetitive onset_time_unity run
n_rejected_outliers: int32 # Tie points dropped as residual outliers
interpol_func: <blob> # pickled scipy.interpolate.interp1d, VR time -> NP time
barcode_overlap: float64 # Fraction of NP barcodes also found on the VR side
"""
|
review from artur: https://claude.ai/code/artifact/29255316-17a9-491d-ae19-874ba7142f00 |
- Update error messages for non-decreasing time validation. - Refactor boundary trimming to return diagnostic counts for trimmed events. - Add outlier rejection functionality with diagnostics in align_barcodes. - Extend schema to include new diagnostic fields for alignment quality. - Improve unit tests to validate new features and edge cases.
lecriste
left a comment
There was a problem hiding this comment.
I noticed this:
NaN onset_time_unity is produced but not handled end-to-end
dlc_helpers.align_timestamps_to_step_time now returns NaN for timestamps outside [step_time[0], step_time[-1]] (it previously clamped to the nearest endpoint). That NaN is never handled downstream:
schema/barcodes.pyTeensyBarcodes.makeinserts the aligned value as
onset_time_unityfor every event (zip(result.events, event_step_times, strict=True)).onset_time_unityisfloat64(non-nullable).NaNis not representable in a MySQLDOUBLEand hard-errors under strict SQL mode (the default) →TeensyBarcodesfails for that dataset.- Even if it were stored,
BarcodeSync.makefetchesonset_time_unityasvr_timeswith no finite filter, and the newalign_barcodesvalidates finiteness up front
(if n_bad: raise "... NaN or infinite ..."), before trimming/intersection — so it raises for the whole session.
The new boundary trim can't absorb these: _boundary_repetitive_run_lengths compares with !=, and NaN != NaN is always True, so NaN is never seen as a repeated run and never trimmed.
Failure scenario: a session with barcode events just before the first / after the last
step_time — i.e. the boundary events this PR is explicitly about — now yields NaN
onset_time_unity → TeensyBarcodes insert errors (strict mode), or if stored,
BarcodeSync raises on the finiteness check. So the targeted sessions can regress from "clamped boundary repeats" to a hard failure. There's no end-to-end test for this (the only NaN test is at the function level).
Fix (pick one):
- In
TeensyBarcodes.make, drop events whose alignedonset_time_unityis NaN before insertingEventrows (they're out-of-game-window boundary events), or - Make
onset_time_unitynullable and havealign_barcodes/makefilter non-finite tie points (drop, don'traise) so the trimming + outlier logic runs on the finite set.
Either way, maybe add an end-to-end test with an out-of-range boundary event.
…ting related tests
lecriste
left a comment
There was a problem hiding this comment.
LGTM.
I triggered the cron_scenario test:
https://github.com/MMathisLab/FreelyMovingVR4Mice/actions/runs/32151216988
|
one more small nitpick The diagnostic columns will now read 0 on every session. Clamped values become NULL, so _trim_repetitive_boundary_timebins finds no repetitive runs — n_trimmed_leading/n_trimmed_trailing will be 0 everywhere. The signal they were added to capture (how far Unity's logging lagged the Teensy: 2–17 barcodes) has moved into n_vr_dropped, which is logged but not stored. so maybe remove n_trimmed_* replace them with n_unmapped_vr_events ? ->n_vr_dropped |

As discussed with @arturoptophys, there were also repeats of
onset_unity_timeat the end of a session (not just at the start. So the arbitrary drop at the start of a session was not sufficient. As the repeats at the end were different across sessions, we went back to removing the repeats timepoints rather than droping barcodes. This was tested on one session, same as in #343, and the overlaping increased!that's from #343 (before correct lineage)

and that's now:
