"""Recompute descriptive comparisons from the frozen 75-row CSV. No new runs."""
import csv, hashlib, json, statistics
from pathlib import Path
P=Path(__file__).resolve().parent
rows=list(csv.DictReader((P/'episodes.csv').open()))
assert len(rows)==75
modes=['astra_only','astra_vla','vla_only']
paired={}
for r in rows:
    key=(int(r['round']),r['task'],r['layout_id'])
    assert r['mode'] not in paired.setdefault(key,{})
    paired[key][r['mode']]=r
assert len(paired)==25 and all(set(g)==set(modes) for g in paired.values())
assert all(len({r['source_sha256'] for r in g.values()})==1 for g in paired.values())
def summary(a):
    return {'n':len(a),'successes':sum(r['success']=='True' for r in a),'mean_score_100':100*statistics.mean(float(r['native_score_0_1']) for r in a),'astra_calls_total':sum(int(r['model_calls']) for r in a),'astra_calls_median':statistics.median(int(r['model_calls']) for r in a),'native_actions_median':statistics.median(int(r['actions']) for r in a)}
comparisons=[]
for left,right in [('astra_vla','astra_only'),('astra_vla','vla_only'),('astra_only','vla_only')]:
    count={'both_success':0,'left_only_success':0,'right_only_success':0,'both_failure':0}
    score={'left_wins':0,'ties':0,'right_wins':0};diffs=[]
    for g in paired.values():
        a,b=g[left],g[right];x,y=a['success']=='True',b['success']=='True'
        count['both_success' if x and y else 'left_only_success' if x else 'right_only_success' if y else 'both_failure']+=1
        d=100*(float(a['native_score_0_1'])-float(b['native_score_0_1']));diffs.append(d)
        score['left_wins' if d>1e-7 else 'right_wins' if d< -1e-7 else 'ties']+=1
    comparisons.append({'left':left,'right':right,'pairs':25,'success_pairs':count,'score_pairs':score,'mean_score_difference':statistics.mean(diffs)})
rounds=[]
for k in range(1,6):
    a=[r for r in rows if int(r['round'])==k]
    rounds.append({'round':k,'source_sha256':sorted({r['source_sha256'] for r in a}),'arms':{m:summary([r for r in a if r['mode']==m]) for m in modes}})
out={'schema':'roborsi.descriptive-analysis.v1','input_file':'episodes.csv','input_sha256':hashlib.sha256((P/'episodes.csv').read_bytes()).hexdigest(),'scope':'25 paired task-layout observations across four frozen source revisions; descriptive only. Model-call counts describe selected completed episodes, excluding original interrupted attempts and offline reviews.','arms':{m:summary([r for r in rows if r['mode']==m]) for m in modes},'comparisons':comparisons,'rounds':rounds}
(P/'analysis.json').write_text(json.dumps(out,ensure_ascii=False,indent=2)+'\n')
print(json.dumps({'arms':out['arms'],'comparisons':comparisons},ensure_ascii=False,indent=2))
