main
John Lauer Add Astra ESC current and thermal screening source and native evidence b668e68 23d ago
from pathlib import Path
import os,sys,json,collections,pickle
D=Path(__file__).resolve().parent;sys.path.insert(0,str(D/'vendor'));sys.path.insert(0,str(D.parent));os.chdir(D.parent)
from geometry import *
import shapely
r=parse((D/'astra-analysis-refilled.kicad_pcb').read_text());parts=collections.defaultdict(list);sums=collections.defaultdict(float)
for z in allof(r,'zone'):
 n=val(z,'net','')
 for f in allof(z,'filled_polygon'):
  layer=val(f,'layer');g=Polygon([p[1:3] for p in one(f,'pts')[1:]]).buffer(0)
  sums[layer]+=g.area;parts[n,layer].append(g)
zones={k:unary_union(v) for k,v in parts.items()};saved=json.load(open('evidence/final-zone-state.json'))['filledAreaByLayerMm2'];audit={l:dict(rebuiltFilledMm2=a,recordedFilledMm2=saved[l],differenceMm2=a-saved[l]) for l,a in sums.items()};print(json.dumps(audit,indent=2));(D/'filled-area-parity.json').write_text(json.dumps(audit,indent=2))
s=json.load(open('evidence/final-routing-state.json'));layers=['F.Cu','In1.Cu','In2.Cu','B.Cu'];drills=[];bars=[]
for p in pads:
 for l in layers:
  if l in p['layers'] or '*.Cu' in p['layers']:parts[p['net'],l].append(p['g'])
 if p['hole']:
  drills.append(Point(p['x'],p['y']).buffer(p['hole']/2))
  if p['type']=='thru_hole':bars.append(dict(net=p['net'],x=p['x'],y=p['y'],drill=p['hole'],diameter=min(p['g'].bounds[2]-p['g'].bounds[0],p['g'].bounds[3]-p['g'].bounds[1]),kind='pad'))
for t in s['segments']:parts[t['net_name'],t['layer']].append(LineString([list(t['start'].values()),list(t['end'].values())]).buffer(t['width']/2))
for v in s['vias']:
 x,y=v['position']['x'],v['position']['y'];g=Point(x,y).buffer(v['size']/2)
 for l in layers:parts[v['net_name'],l].append(g)
 drills.append(Point(x,y).buffer(v['drill']/2));bars.append(dict(net=v['net_name'],x=x,y=y,drill=v['drill'],diameter=v['size'],kind='via'))
holes=unary_union(drills);cu={k:unary_union(v).difference(holes) for k,v in parts.items()};pickle.dump(dict(copper=cu,zones=zones,pads=pads,bars=bars,holes=holes),open(D/'copper.pkl','wb'))
summary={l:unary_union([g for (n,la),g in cu.items() if la==l]).area for l in layers};(D/'copper-union-area.json').write_text(json.dumps(summary,indent=2));print('whole conductor area',summary)