"""Report only measured 200-sample scores; aggregate across all five seeds.""" import csv, hashlib, json, statistics, sys from pathlib import Path ROOT=Path(__file__).resolve().parents[1] sys.path.insert(0,str(ROOT/'runtime')) METHODS=['dinowm','pldm','fast-lewm','gcbc','gciql','gcivl'] TASKS=['tworoom','cube','pusht'] OFFSETS=[25,50,75,100] SEEDS=[42,43,44,45,46] def result_path(method,task,offset,seed): suffix='' if seed==42 else f'_seed{seed}' return ROOT/'results'/f'{method}_{task}_{offset}{suffix}.json' def atomic_json(path,data): tmp=path.with_suffix('.tmp');tmp.write_text(json.dumps(data,indent=2));tmp.replace(path) def aggregate(rows): values=[r['success_percent'] for r in rows if r['status']=='complete'] complete=len(values)==len(SEEDS) return len(values),statistics.mean(values) if complete else None,statistics.stdev(values) if complete else None def save_sheet(): rows=[];summary=[] plan_path=ROOT/'results/training_plan.json' planned={(p['model'],p['dataset']) for p in json.loads(plan_path.read_text()) if p['train']} if plan_path.exists() else set() for method in METHODS: for task in TASKS: for offset in OFFSETS: group=[] for seed in SEEDS: p=result_path(method,task,offset,seed) d=json.loads(p.read_text()) if p.exists() else {} count=len(d.get('successes',[])) assert count<=200 status='complete' if count==200 else ('running' if count else 'queued') if not count and not (method=='fast-lewm' or (method=='dinowm' and task=='pusht')): status='unavailable: compatible checkpoint not found' if not count and (method,task) in planned: training_path=ROOT/'results'/f'training_{method}_{task}.json' training=json.loads(training_path.read_text()) if training_path.exists() else {} status='training' if training.get('status')=='training' else ('queued evaluation' if training.get('status')=='trained' else 'queued training') r=dict(model=method,dataset=task,offset=offset,seed=seed,samples_completed=count,samples_required=200,successes=sum(d['successes']) if count else None,success_percent=100*sum(d['successes'])/count if count==200 else None,status=status,execution_budget=50,checkpoint_release=d.get('checkpoint_release','naiverer/fast-leworldmodel' if method=='fast-lewm' and count else None)) r.update(training_epochs=d.get('training',{}).get('epochs_completed'),training_seed=d.get('training',{}).get('training_seed'),model_variant=d.get('training',{}).get('variant')) rows.append(r);group.append(r) n,mean,std=aggregate(group) summary.append(dict(model=method,dataset=task,offset=offset,**{f'seed_{r["seed"]}':r['success_percent'] for r in group},seeds_completed=n,mean_percent=mean,std_percent=std,mean_plus_std=f'{mean:.2f} ± {std:.2f}' if mean is not None else None)) for name,data in [('planning_success',rows),('planning_summary',summary)]: atomic_json(ROOT/'results'/f'{name}.json',data) p=ROOT/'results'/f'{name}.csv';tmp=p.with_suffix('.tmp') with tmp.open('w',newline='') as f: w=csv.DictWriter(f,fieldnames=list(data[0]));w.writeheader();w.writerows(data) tmp.replace(p) import openpyxl wb=openpyxl.Workbook();wb.remove(wb.active) for name,data in [('Seeds and mean std',summary),('Planning success',rows)]: ws=wb.create_sheet(name);ws.append(list(data[0])) for r in data:ws.append(['null' if v is None else v for v in r.values()]) ws.freeze_panes='D2';ws.auto_filter.ref=ws.dimensions for col in ws.columns:ws.column_dimensions[col[0].column_letter].width=min(60,max(len(str(c.value)) for c in col)+2) ws=wb.create_sheet('Protocol');ws.append(['Setting','Value']) for row in [('Seeds','42, 43, 44, 45, 46'),('Samples per seed / offset',200),('Goal offsets','25, 50, 75, 100'),('Mean and std','Across all five completed seed success percentages; sample std, ddof=1'),('Sampling','Different pairs per seed; identical pairs across models'),('CEM seed','Run seed + batch starting index'),('Execution budget',50),('Planning window',25),('CEM candidates',300),('CEM iterations',30),('CEM elites',30),('Environment batch',2),('Checkpoint deletion','After all five seeds and four offsets for that model/task finish'),('Meaning of null','Unavailable or incomplete; aggregate requires all five seeds'),('Full protocol','See PROTOCOL.md')]:ws.append(row) ws.column_dimensions['A'].width=30;ws.column_dimensions['B'].width=95 workbook=ROOT/'results/planning_success.xlsx';tmp=workbook.with_suffix('.tmp.xlsx');wb.save(tmp);tmp.replace(workbook) atomic_json(ROOT/'results/validation.json',dict(completed_runs=sum(r['status']=='complete' for r in rows),completed_samples=sum(r['samples_completed'] for r in rows if r['status']=='complete'),in_progress_samples=sum(r['samples_completed'] for r in rows if r['status']!='complete'),xlsx_sha256=hashlib.sha256(workbook.read_bytes()).hexdigest(),downloaded_checkpoints_remaining=len([p for p in (ROOT/'checkpoints').rglob('*') if p.suffix in ['.pth','.pt','.ckpt']]),scores=[r for r in rows if r['status']=='complete'])) if __name__=='__main__':save_sheet()