# #173 valve experiment digest -- per run: valve receipts (PROOF of detent), # time-to-degradation-1000, equilibrium T, held speed, C5/bank finals. import re, sys, statistics as st def digest(path): myotemp = [] # (t, T) myoheat = [] # (v, a, dt) myo = [] # speedEffect samples in file order c5 = []; bank = [] presses = [] # ([valve-tx] BT_VALVE5 press lines) detents = [] # ([valve] CondenserN valve -> detent D lines) redist = [] # ([valve] condenser#N valveState=V flow=F (total=T)) for ln in open(path, encoding='latin-1', errors='replace'): m = re.search(r"\[myotemp\] t=([\d.eE+-]+) T=([\d.eE+-]+)", ln) if m: myotemp.append((float(m.group(1)), float(m.group(2)))); continue m = re.search(r"\[myoheat\] v=([\d.eE+-]+) a=([\d.eE+-]+) m=[\d.eE+-]+ g=[\d.eE+-]+ ratio=[\d.eE+-]+ dmgGain=[\d.eE+-]+ dt=([\d.eE+-]+)", ln) if m: myoheat.append(tuple(map(float, m.groups()))); continue m = re.search(r"\[myo\] Myomers.* speed=([\d.eE+-]+).* gear=(\d+)", ln) if m: myo.append((float(m.group(1)), int(m.group(2)))); continue m = re.search(r"\[heat-t\] (\S+)( \(bank\))? T=([\d.eE+-]+)", ln) if m: name, isbank, T = m.group(1), m.group(2), float(m.group(3)) if name == 'Condenser5': c5.append(T) elif isbank or name == 'HeatSink': bank.append(T) continue if '[valve-tx] BT_VALVE5' in ln: presses.append(ln.strip()); continue m = re.search(r"\[valve\] (Condenser\d+) valve -> detent (\d+)", ln) if m: detents.append((m.group(1), int(m.group(2)))); continue m = re.search(r"\[valve\] condenser#(\d) valveState=(\d+) flow=([\d.eE+-]+) \(total=(\d+)\)", ln) if m: redist.append(tuple(int(x) if i != 2 else float(x) for i, x in enumerate(m.groups()))); continue name = path.split('m173_')[-1].replace('.log', '') print("=" * 78) print("RUN %s" % name) if presses: for p in presses: print(" " + p) if detents: print(" detent walk: " + " -> ".join("%s:%d" % d for d in detents)) # final redistribute state (last 6 lines) if redist: last6 = redist[-6:] print(" final shares: " + " ".join("#%d v=%d f=%.4f" % (n, v, f) for (n, v, f, t) in last6) + " (total=%d)" % last6[-1][3]) if not myotemp: print(" NO MYOTEMP DATA"); return t_end = myotemp[-1][0] t1000 = next((t for t, T in myotemp if T >= 1000), None) t2000 = next((t for t, T in myotemp if T >= 2000), None) Tpk = max(T for _, T in myotemp) late = [T for t, T in myotemp if t > t_end - 40.0] k = max(2, len(myotemp) // 5) dT = (myotemp[-1][1] - myotemp[-k][1]) / max(1e-6, (myotemp[-1][0] - myotemp[-k][0])) # pair myoheat with myotemp by index (printed in lockstep) n = min(len(myoheat), len(myotemp)) vlate = [myoheat[i][0] for i in range(n) if myotemp[i][0] > t_end - 40.0] vpk = max(x[0] for x in myoheat) if myoheat else 0.0 selate = [s for s, g in myo[-20:]] gears = set(g for s, g in myo) print(" t1000=%s t2000=%s Tpeak=%.0f eqT(last40s)=%.0f endSlope=%+.2f/s (window %.1fs)" % ("%.1fs" % t1000 if t1000 else "NEVER", "%.1fs" % t2000 if t2000 else "never", Tpk, st.mean(late), dT, t_end)) print(" vPeak=%.1f vHeld(last40s)=%.1f u/s speedEffect(last~20 samples)=%.2f gear(s)=%s" % (vpk, st.mean(vlate) if vlate else 0.0, st.mean(selate) if selate else 0.0, sorted(gears))) print(" Condenser5 end T=%.0f bank end T=%.0f" % (c5[-1] if c5 else 0, bank[-1] if bank else 0)) if __name__ == '__main__': for f in sys.argv[1:]: digest(f)