from pathlib import Path
import csv,datetime,hashlib,importlib.util,json,math,sys
sys.path.insert(0,r'D:/Photometer_research_20261022/research/cloud_transport/private_readers')
from scipy.stats import poisson
from scipy.optimize import brentq

out=Path(r'D:/Photometer_research_20261022/revision_20261022_r4/analysis/analytic/auroral_counts')
src=Path(__file__).with_name('count_requirements.py')
spec=importlib.util.spec_from_file_location('read_only_count_methods',src)
m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m)
hc=6.62607015e-34*299792458.;wave=337.1e-9;energy=hc/wave
eta=.2;Rph=1e10/(4*math.pi);Rw=Rph*energy;dark=50.;tau=17e-9
rows=[];max_tail_error=0.;max_power_error=0.
for diameter in [1.,5.,25.]:
 area=math.pi*(diameter*.001)**2/4
 for fov in [60.,90.]:
  projected=math.pi*math.sin(math.radians(fov/2))**2
  G=area*projected
  for radiance_R in [15.,100.,1000.,2270.]:
   rate=radiance_R*Rph*G*eta
   for dt in [30e-6,80e-6,.0002,.003]:
    bg=(rate+dark)*dt
    for criterion,alpha in [('single_window_5sigma_tail',m.ALPHA_SINGLE),('illustrative_0p1_false_per_observing_day',m.ALPHA_OPERATIONAL)]:
     threshold,signal=m.count_at_power(bg,alpha,.95)
     sf=poisson.sf(threshold-1,bg)
     power=poisson.sf(threshold-1,bg+signal)
     assert sf<=alpha*(1+1e-7) and poisson.sf(threshold-2,bg)>alpha
     assert abs(power-.95)<1e-7
     alt_signal=brentq(lambda s:poisson.sf(threshold-1,bg+s)-.95,0,signal*2+100)
     assert abs(alt_signal-signal)<1e-5
     max_power_error=max(max_power_error,abs(power-.95));max_tail_error=max(max_tail_error,abs(sf-m.poisson_sf(threshold,bg)))
     rows.append(dict(diameter_mm=diameter,full_circular_FOV_deg=fov,projected_etendue_m2_sr=G,eta=eta,
      assumed_received_band_equivalent_R=radiance_R,nominal_four_nm_mean_W_m2_sr_nm=radiance_R*Rw/4,
      incident_linear_photoelectron_rate_s=rate,unmultiplied_mean_photocurrent_A=rate*1.602176634e-19,
      observation_window_s=dt,known_background_mean_count=bg,Poisson_sigma_count=math.sqrt(bg),
      aperture_photon_equivalent_rms=math.sqrt(bg)/eta,criterion=criterion,per_test_alpha=alpha,
      critical_observed_count=threshold,signal_mean_for_95pct_power=signal,aperture_photons_for_95pct_power=signal/eta,
      aperture_fluence_ph_m2_for_95pct_power=signal/(eta*area),
      rectangular_source_irradiance_W_m2_for_95pct_power=signal*energy/(eta*area*dt),
      hypothetical_17ns_deadtime_occupancy=rate*tau,
      hypothetical_nonparalyzable_fraction_lost=rate*tau/(1+rate*tau),
      model_validity='IdealindependentlinearPoissoncountsonly; count-losscolumnsarediagnosticsnotacorrectiontothelikelihood'))
with (out/'conditional_auroral_count_scenarios.csv').open('w',newline='',encoding='utf-8') as f:
 w=csv.DictWriter(f,fieldnames=list(rows[0]));w.writeheader();w.writerows(rows)
review={'recorded_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),
 'status':'EXECUTED_CONDITIONAL_DETECTOR_COUNTS_NOT_A_POLAR_BACKGROUND_FORECAST',
 'constants':{'photon_energy_J':energy,'one_R_ph_m2_sr_s':Rph,'one_R_W_m2_sr':Rw},
 'formulae':['G=A*pi*sin(full_circular_FOV/2)^2','r=Rband*1e10/(4*pi)*G*eta','B=(r+rdark)*dt','FindsmallestintegernwithP(Poisson(B)>=n)<=alpha; solveP(Poisson(B+S)>=n)=.95'],
 'conditions':{'uniform_received_band_radiance_R':[15,100,1000,2270],'end_to_end_efficiency':eta,'dark_cps':dark,'nominal_rectangular_width_nm':4,'arrival_counts_before_deadtime':True},
 'relation_to_observations':'2270RusesSivjee1976selectedN2(0,0)bandintensityonlyasanamplitudescale. Complete4nmcapture, uniformreceivedradianceandsharedgeometryareassumptions, notobservedbythatpaper. No1971photometerbrightnessistreatedasactual4nmR.',
 'no_silent_transfers':['NoKpclassoroccurrenceassigned','Noextrapolationfrom10degreeaircraftFOVtofull60/90degreearc','Nocloudreflectionorlimbtonadirtransfercomputed','Noactualsourcephotonfluenceorpopulationinferred','Noactualfilter/PDE/temperature/radiationdrift','NoPMTmultiplicationexcessnoise,SiPMcorrelatednoise,particles,baselineuncertaintyordeadtimeinPoissonlikelihood','Single-window5sigmatailisnotglobalfalse-triggercontrol; operationalallocationishypothetical50kstarts/s*86400s*3families'],
 'validation':{'scipy_independent_tail_and_root_checks':len(rows),'max_absolute_tail_difference':max_tail_error,'max_absolute_power_error':max_power_error,'read_only_original_method_sha256':hashlib.sha256(src.read_bytes()).hexdigest()},
 'examples':[r for r in rows if r['diameter_mm']==25 and r['full_circular_FOV_deg']==60 and r['observation_window_s']==30e-6 and r['criterion']=='single_window_5sigma_tail']}
(out/'conditional_auroral_count_scenarios.json').write_text(json.dumps(review,indent=2),encoding='utf-8')
print(json.dumps({'rows':len(rows),'constants':review['constants'],'examples':review['examples'],'validation':review['validation']},indent=2))
