"""Reuse R1 traces for28; calculate frozen R1 only for independently reset P02."""
import json,sys,math
from pathlib import Path
sys.path.insert(0,'/evidence/2026-11-01_contextra-fall-spatial-28clips_r01/helpers')
from common import OUT,read,save,sha,load,evidence
from fall_candidate import features,SpatialState
from depth_features import measure

FROZEN=Path('/evidence/2026-11-01_contextra-fall-spatial-28clips_r01');config=read(FROZEN/'conditions.json')
for path,digest in read(OUT/'baseline_fingerprints.json').items():assert sha(evidence(path))==digest
specs=read(OUT/'specs.json');cases=read(OUT/'cases.json')['cases'];count=0;full=0
for clip,spec in specs.items():
 rows,selected,_,cache,maps=load(clip);folder=OUT/'work'/clip;folder.mkdir(parents=True,exist_ok=True)
 trace=folder/'features.jsonl';assert not trace.exists()
 if spec['r1_trace']:
  baseline=[json.loads(s) for s in evidence(spec['r1_trace']).open()];assert len(baseline)==len(rows)
 else:
  assert clip=='SELF_L02' and len(rows)==7261 and rows[0]['sample']==0 and rows[0]['source_frame']==2543
  assert abs(rows[0]['seconds']-105.352669)<1e-9
  state=SpatialState(config,'SELF_L02_P02_R1');baseline=[]
  for row in rows:
   people=[features(p,config) for p in row['persons']];r1=state.evaluate(row['seconds'],people,monotonic_now=row['seconds']-rows[0]['seconds'])
   review=int(maps[row['sample']]['review_frame_1based']);active=[c for c in cases if c['review_anchor_range'][0]<=review<=c['review_anchor_range'][1]]
   baseline.append(dict(sample=row['sample'],source_frame=row['source_frame'],seconds=row['seconds'],displayed=True,
    l02_frame=row['source_frame']-2542,part_id='L01_P02',tracking_mode='stored10',people=people,candidate=r1,
    annotation=dict(reference='negative_reference',region='body' if active else 'unexplained',review_frame=review,case_ids=[c['case_id'] for c in active],dedupe_key='SELF01:'+str(review),exact_gt=False)))
  with (folder/'r1_baseline.jsonl').open('x') as f:
   for r in baseline:f.write(json.dumps(r,ensure_ascii=False,separators=(',',':'))+'\n')
 with trace.open('x') as f:
  for row,r1 in zip(rows,baseline):
   assert (row['sample'],row['source_frame'],row['seconds'])==(r1['sample'],r1['source_frame'],r1['seconds'])
   assert len(row['persons'])==len(r1['people'])
   extra=[]
   for p,b in zip(row['persons'],r1['people']):
    assert p['query']==b['query'] and p['bbox']==b['bbox'] and p['score']==b['score']
    extra.append(measure(p,b))
   f.write(json.dumps(dict(sample=row['sample'],source_frame=row['source_frame'],seconds=row['seconds'],displayed=r1['displayed'],annotation=r1['annotation'],r1=r1['candidate'],people=r1['people'],extra=extra,part_id=spec.get('part_id'),l02_frame=row['source_frame']-2542 if clip=='SELF_L02' else None),ensure_ascii=False,separators=(',',':'),allow_nan=False)+'\n')
   full+=1;count+=r1['displayed']
 save(folder/'features_validation.json',dict(status='PASS',source_cache_sha256=spec['cache_sha256'],trace_sha256=sha(trace),full=len(rows),displayed=len(selected),baseline_recomputed=clip=='SELF_L02'))
 print('FEATURE_PASS',clip,len(selected),flush=True)
assert count==17242
save(OUT/'reports/feature_validation.json',dict(status='PASS',displayed=count,full=full,inputs=29,r1_reexecution_inputs=['SELF_L02'],model_pose_tracking_executions=0))
