"""Independent finite-grid checks over the declared astronomical camera controls."""
import argparse,json,math
from pathlib import Path
import numpy as np
from synthetic_optics import pupil_fields,finite_band

def compare(first,second,source):
 yy,xx=np.indices((80,80));aperture=np.hypot((xx-40)*.25-source[0],(40-yy)*.25-source[1])<=.7
 return {'relative_l1':float(np.sum(abs(first-second))/second.sum()),'absolute_l1_entrance_fraction':float(np.sum(abs(first-second))),
  'absolute_transmission_difference':float(abs(first.sum()-second.sum())),
  'aperture_relative_difference':float(first[aperture].sum()/second[aperture].sum()-1),
  'reference_transmission':float(second.sum())}

def main(output):
 rows=[]
 for separation in (3.,4.,5.,7.):
  for angle in (0.,45.,90.):
   source=(separation*math.cos(math.radians(angle)),separation*math.sin(math.radians(angle)))
   for wavelength in (1.14,1.34):
    for static in (0.,40.):
     for exposure in (0,4):
      settings={'staticOpdNm':static,'evolvingOpdNm':20}
      current=pupil_fields(settings,wavelength,source,exposure,size=512,diameter=64)
      reference=pupil_fields(settings,wavelength,source,exposure,size=1024,diameter=128)
      focal=pupil_fields(settings,wavelength,source,exposure,size=1024,diameter=64)
      rows.append({'separation':separation,'angle_degrees':angle,'wavelength':wavelength,'static_opd_nm':static,'evolving_opd_nm':20,'exposure':exposure,
       'production512_64_vs_reference1024_128':compare(current,reference,source),'production512_64_vs_focal1024_64':compare(current,focal,source)})
      print('optical control case',len(rows),flush=True)
 maxima={key:max(abs(r['production512_64_vs_reference1024_128'][key])for r in rows)for key in ['relative_l1','absolute_l1_entrance_fraction','absolute_transmission_difference','aperture_relative_difference']}
 result={'scope':'Finite independent NumPy grid comparisons at the complete declared control corners, not a uniform continuum error bound or precision GPI optical model. Near-mask separation below3 is excluded from inference.','production':{'transform':512,'pupil':64,'pixel_rule':'2x2 Gauss; cubic complex amplitude; physical entrance area'},'reference':{'transform':1024,'pupil':128},'cases':len(rows),'maxima':maxima,'rows':rows}
 output.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(maxima),flush=True)
if __name__=='__main__':
 p=argparse.ArgumentParser(description=__doc__);p.add_argument('--output',type=Path,default=Path('supported-optics.json'));args=p.parse_args();main(args.output)
