import sys, re path = sys.argv[1] pat = re.compile(r'flood=(\d+) eye=\(([^)]+)\) player=\(([^)]+)\) rawPlayer=\(([^)]+)\) yaw=([-\d.]+)') rows = [] with open(path, encoding='utf-8', errors='ignore') as fh: for l in fh: m = pat.search(l) if m: rows.append((int(m.group(1)), tuple(float(x) for x in m.group(2).split(',')), float(m.group(5)))) print("total pv-input rows:", len(rows)) # find first window of 25 frames containing >=4 flood changes (an oscillation burst) def changes(seg): return sum(1 for i in range(1, len(seg)) if seg[i][0] != seg[i-1][0]) W = 25 start = None for i in range(len(rows)-W): if changes(rows[i:i+W]) >= 4: start = i; break if start is None: print("no oscillation burst found"); sys.exit() print(f"burst at row {start}; dumping {W+8} frames (flood, eyeX,eyeY,eyeZ, dEyeX_mm,dEyeY_mm, yaw):") prev = None for r in rows[start:start+W+8]: fl, e, yaw = r dx = (e[0]-prev[0])*1000 if prev else 0.0 dy = (e[1]-prev[1])*1000 if prev else 0.0 mark = " <" if (prev and fl != prevfl) else "" print(f" flood={fl} eye=({e[0]:.6f},{e[1]:.6f},{e[2]:.6f}) dX={dx:+7.3f}mm dY={dy:+7.3f}mm yaw={yaw:.6f}{mark}") prev = e; prevfl = fl