feat(convert): add task 05 sqlite converter with variant B keys" -m "- convert: convert_sqlite.py builds tribo.db (composite PKs, enforced FKs, Q1-Q7 indexes, track_summary)
- tools: common/track_summary.py fixes the cross-engine steady-state algorithm - rules: db-sql-schema records the FK enforcement decision and track_summary definition - specs: 05 aligned with data-naming-units, simtra_profiles added - docs: FK key-schema study added under docs/research/, README updated - replace manual CSV reading with CorpusReader for better data handling - streamline argument parsing and dependency checks using common pipeline functions - enhance marker writing for task completion tracking - remove unused regex and validation error classes for cleaner code
This commit is contained in:
48
common/track_summary.py
Normal file
48
common/track_summary.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Per-track steady-state summary (docs/rules/db-sql-schema.md section 5).
|
||||
|
||||
Both engines must produce identical values: SQLite calls this function
|
||||
during load (task 05); the PostgreSQL materialized view (task 06)
|
||||
implements the same three steps in SQL. Plain sequential float arithmetic
|
||||
keeps results within the 1e-9 checksum tolerance across implementations.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
TAIL_START_CYCLE = 501 # steady-state proxy window: cycles 501..N
|
||||
|
||||
|
||||
def summarize_track(cofs: list[float]) -> tuple[float, float, int]:
|
||||
"""Return (cof_ss_mean, cof_ss_std, run_in_cycles) for cofs[i] = cof at cycle i+1."""
|
||||
n = len(cofs)
|
||||
tail = cofs[TAIL_START_CYCLE - 1:]
|
||||
m = _mean(tail)
|
||||
s = _stddev_pop(tail, m)
|
||||
|
||||
run_in = TAIL_START_CYCLE - 1 # fallback when no cycle enters the 2-sigma band
|
||||
band = 2.0 * s
|
||||
for c in range(1, n + 1):
|
||||
if abs(cofs[c - 1] - m) < band:
|
||||
run_in = c
|
||||
break
|
||||
|
||||
ss = cofs[run_in:] # cycles strictly greater than run_in
|
||||
ss_mean = _mean(ss)
|
||||
ss_std = _stddev_pop(ss, ss_mean)
|
||||
return ss_mean, ss_std, run_in
|
||||
|
||||
|
||||
def _mean(values: list[float]) -> float:
|
||||
total = 0.0
|
||||
for v in values:
|
||||
total += v
|
||||
return total / len(values)
|
||||
|
||||
|
||||
def _stddev_pop(values: list[float], mean: float) -> float:
|
||||
acc = 0.0
|
||||
for v in values:
|
||||
d = v - mean
|
||||
acc += d * d
|
||||
return math.sqrt(acc / len(values))
|
||||
Reference in New Issue
Block a user