"""Illustrative expected noise budget; no camera measurements. Python 3 standard library."""
from pathlib import Path
import csv,json,math
HERE=Path(__file__).resolve().parent
T=3600;npix=9;rn=3.0
scenarios=[{'name':'background-rich','S':20.,'B':80.,'D':.05},{'name':'read-noise-sensitive','S':.1,'B':.01,'D':.002}]
rows=[]
for case in scenarios:
    rate=case['S']+case['B']+case['D']
    ceiling=case['S']*T/math.sqrt(rate*T)
    for exposure in [15,30,60,180,600,3600]:
        n=T//exposure;readvar=n*npix*rn**2;poissonvar=rate*T
        snr=case['S']*T/math.sqrt(poissonvar+readvar)
        rows.append({'scenario':case['name'],'exposure_s':exposure,'readouts':n,'total_s':T,'source_e':case['S']*T,'poisson_variance_e2':poissonvar,'read_variance_e2':readvar,'snr':snr,'read_noise_free_snr':ceiling,'fraction_of_ceiling':snr/ceiling})
        assert n*exposure==T and snr<=ceiling
    # Variances add: independent equally weighted, registered, unclipped sum; no noise from background estimate.
    assert all(rows[-6+i]['snr']<rows[-5+i]['snr'] for i in range(5))
with (HERE/'noise-results.csv').open('w',newline='',encoding='utf-8') as f:
    w=csv.DictWriter(f,fieldnames=rows[0].keys());w.writeheader();w.writerows(rows)
minimum=[{'scenario':c['name'],'exposure_for_95pct_ceiling_s':npix*rn**2/((1/.95**2-1)*(c['S']+c['B']+c['D']))} for c in scenarios]
(HERE/'noise-results.json').write_text(json.dumps({'total_s':T,'npix':npix,'read_noise_e_per_pixel_RMS':rn,'rates_e_per_s_aperture':scenarios,'rows':rows,'continuous_threshold_not_camera_recommendation':minimum,'assumptions':['Independent Poisson source, sky, dark counts','Gaussian independent read noise per pixel per read','No gain conversion needed: all inputs in electrons','Linear unsaturated detector, fixed aperture, equal weights, no rejected frames','No read overhead, tracking, cosmic rays, resampling correlation or estimated-sky variance'],'uncertainty':'Deterministic expected-noise model, not a fitted estimate or measured benchmark; no empirical uncertainty intervals.'},indent=2),encoding='utf-8')
print(json.dumps({'rows':rows,'thresholds':minimum},indent=2))
