Review index · Download editable notebook
Executed top-to-bottom in a fresh kernel.
Cell 0 · 9a9d370e842e
01. Units, photon budget, optics and receiver algebra
This executable notebook independently derives and checks the design calculations. It is written for inspection as well as execution: the equations are in the markdown cells, the numerical implementation is in modules/design_review.py, and the detailed derivations/source locators are in methods/design_and_diagnostics.md.
Scope: the parameters are explicit hypothetical design inputs. A checked calculation does not turn a toy Gaussian into an N2 spectrum, a dark-only NEP into a device specification, or a photon fluence into a source luminosity function. Run all cells from a kernel with NumPy, Matplotlib and IPython. No network requests or installations are performed. Original result tables are comparison targets, not copied calculation outputs.
Cell 1 · 4ca836c3f4a3 · execution 1
from pathlib import Path
import sys, os, json, math, hashlib
import numpy as np
from io import BytesIO
from IPython.display import display, Image, Markdown
candidates = [Path.cwd(), *Path.cwd().parents]
ROOT = next(p for p in candidates if (p/'data/design_results.json').exists() and (p/'modules/design_review.py').exists())
if (ROOT/'runtime/deps').is_dir(): sys.path.insert(0, str(ROOT/'runtime/deps'))
sys.path.insert(0, str(ROOT))
os.environ.setdefault('MPLCONFIGDIR', str(ROOT/'checks/design_mplconfig'))
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from modules import design_review as v
from modules.common import table
plt.rcParams.update({'figure.figsize': (8.2, 4.3), 'font.size': 10, 'axes.grid': True, 'grid.alpha': .22})
def show(fig):
b=BytesIO(); fig.savefig(b, format='png', dpi=125, bbox_inches='tight')
display(Image(data=b.getvalue())); plt.close(fig)
design = v.load('design_results.json')
analytic = v.load('analytic_results.json')
print('Independent module:', ROOT/'modules/design_review.py')
print('SHA256:', hashlib.sha256((ROOT/'modules/design_review.py').read_bytes()).hexdigest())
Independent module: D:\Photometer_research_20261022\verification_20261022_r1\modules\design_review.py
SHA256: af4c3056a61716d48c5eb8eec3f1abb67be7dee123d78c6bbc7c6f6cc37322ca
Cell 2 · eb3262c87a3c
D01. Energy and reference planes
For a vacuum wavelength in metres, (joules). A received energy fluence in J m divided by this energy gives photon fluence in photons m. The nominal wavelength is retained from the legacy model; this is not an air-to-vacuum spectral-registration correction.
Keep four planes separate: emitted source; atmospheric output; entrance aperture; and detected counts. A spacecraft fluence already includes real cloud/air delivery. Never multiply it by atmospheric transmission a second time.
Cell 3 · 90a2722bc6fd · execution 2
table([{'wavelength_nm': w, 'photon_energy_J': v.photon_energy(w*1e-9),
'photons_per_J': 1/v.photon_energy(w*1e-9)} for w in [337.1,777.4]])
print('One Rayleigh:', v.RAYLEIGH_PHOTONS, 'photons m^-2 sr^-1 s^-1, integrated over the feature')
print('At nominal 337.1 nm:',v.RAYLEIGH_PHOTONS*v.photon_energy(337.1e-9),'W m^-2 sr^-1 per R')
| wavelength_nm | photon_energy_J | photons_per_J |
|---|
| 337.1 | 5.8927495e-19 | 1.6970007e+18 |
| 777.4 | 2.5552429e-19 | 3.9135222e+18 |
2 rows total; 2 shown.
One Rayleigh: 795774715.4594767 photons m^-2 sr^-1 s^-1, integrated over the feature
At nominal 337.1 nm: 4.689301058286399e-10 W m^-2 sr^-1 per R
Cell 4 · 20d0cc442a7e
D02-D03. Ordinary and projected solid angle
For a circular cone, while . A flat aperture viewing uniform radiance uses .
MMIA's quoted field is a square diagonal, not a circular cone diameter. The independent square integral below shows why this distinction affects background and etendue. Steradians are retained in the bookkeeping even though they are dimensionless in SI.
Cell 5 · 2ea78a8afa16 · execution 3
rows=[]
for full in [30.,60.,80.,90.,180.]:
ordinary,projected=v.circular_angles(math.radians(full/2))
rows.append({'field':'circular','full_or_diagonal_deg':full,'Omega_sr':ordinary,'projected_Omega_sr':projected})
ordinary,projected=v.square_angles(math.radians(40))
rows.append({'field':'square diagonal','full_or_diagonal_deg':80.,'Omega_sr':ordinary,'projected_Omega_sr':projected})
table(rows)
angles=np.linspace(1,120,150)
fig,ax=plt.subplots()
ax.plot(angles,[v.circular_angles(math.radians(a/2))[0] for a in angles],label='ordinary solid angle')
ax.plot(angles,[v.circular_angles(math.radians(a/2))[1] for a in angles],label='projected angular integral')
ax.scatter([80],[projected],label='square 80° diagonal: projected',color='black')
ax.set(xlabel='Full circular field (degrees)',ylabel='Angular integral (sr)',title='Projection matters for a wide field');ax.legend();show(fig)
| field | full_or_diagonal_deg | Omega_sr | projected_Omega_sr |
|---|
| circular | 30 | 0.21409435 | 0.2104468 |
| circular | 60 | 0.84178721 | 0.78539816 |
| circular | 80 | 1.4699861 | 1.2980304 |
| circular | 90 | 1.8403024 | 1.5707963 |
| circular | 180 | 6.2831853 | 3.1415927 |
| square diagonal | 80 | 1.0536595 | 0.96305504 |
6 rows total; 6 shown.
Cell 6 · cb54fc7125a5
D04-D05. A worked received-fluence and background conversion
At nadir, . For uniform spectral energy radiance and a flat response, and .
The following example assumes a 25 mm entrance, 60 degree circular full field, 20% end-to-end probability, a 4 nm rectangular/equivalent band, and 50 primary dark detections per second. The value is a reference continuum scale, not a polar cloud background measurement. No false-alarm or detection-power criterion is imposed here.
Cell 7 · 08d31b2a2e8d · execution 4
area=v.aperture_area(.025);eta=.2;L=1.77e-9
rate=v.continuum_rate(L,4.,area,math.pi/6,eta,337.1e-9)
table([{'window_us':T*1e6,'sky_primary_s':rate,'dark_primary_s':50.,
'background_mean_count':(rate+50)*T,'ideal_known_background_RMS_count':math.sqrt((rate+50)*T)}
for T in [30e-6,80e-6,200e-6,.003]])
print('Input received photon fluence of 1e8 photons/m² ->',v.counts_from_received_fluence(1e8,area,eta),'expected detected photons')
print('Required aperture photons for an explicitly chosen 100 detected photons:',100/eta)
print('That count choice is not a validated detection threshold.')
| window_us | sky_primary_s | dark_primary_s | background_mean_count | ideal_known_background_RMS_count |
|---|
| 30 | 926413.88 | 50 | 27.793916 | 5.2719936 |
| 80 | 926413.88 | 50 | 74.11711 | 8.6091295 |
| 200 | 926413.88 | 50 | 185.29278 | 13.612229 |
| 3000 | 926413.88 | 50 | 2779.3916 | 52.719936 |
4 rows total; 4 shown.
Input received photon fluence of 1e8 photons/m² -> 9817.477042468105 expected detected photons
Required aperture photons for an explicitly chosen 100 detected photons: 500.0
That count choice is not a validated detection threshold.
Cell 8 · b6786f70a6f9
D06. Etendue is a necessary constraint
In uniform air-to-air geometrical optics, . A detector hemisphere gives ; a filter internal half-cone requires .
This does not specify a lens, detector numerical aperture, vignetting or a usable 1U layout. The MMIA 25 mm photocathode is not a 25 mm UV entrance. The proposed larger entrance is a new phase-space design.
Cell 9 · 76f98fb6441d · execution 5
rows=[]
for full in [30.,60.,80.,90.]:
g,ad,dd,df=v.etendue_bounds(.025,math.radians(full/2),math.radians(10))
rows.append({'full_circular_deg':full,'G_m2_sr':g,'detector_min_mm2':ad*1e6,
'detector_min_diameter_mm':dd*1e3,'filter_min_diameter_mm':df*1e3})
table(rows)
beta=np.linspace(4,25,100);fig,ax=plt.subplots()
for full in [60,90]:
ax.plot(beta,[v.etendue_bounds(.025,math.radians(full/2),math.radians(b))[3]*1e3 for b in beta],label=f'{full}° full circular field')
ax.set(xlabel='Allowed internal filter half-cone (degrees)',ylabel='Necessary clear filter diameter (mm)',title='25 mm entrance: ideal air-to-air bounds');ax.legend();show(fig)
| full_circular_deg | G_m2_sr | detector_min_mm2 | detector_min_diameter_mm | filter_min_diameter_mm |
|---|
| 30 | 0.00010330283 | 32.882313 | 6.4704761 | 37.261987 |
| 60 | 0.00038553142 | 122.71846 | 12.5 | 71.984631 |
| 80 | 0.00063716919 | 202.81725 | 16.06969 | 92.541658 |
| 90 | 0.00077106284 | 245.43693 | 17.67767 | 101.80164 |
4 rows total; 4 shown.
Cell 10 · c1b3863ef434
D07-D09. Filter walk and a hypothetical Gaussian overlap
The effective-index approximation is . Here is an assumption. A normalized Gaussian photon source and unit-peak Gaussian filter have capture
Inspect original LaTeX
C={\sigma_f\over\sqrt{\sigma_s^2+\sigma_f^2}}\exp[-\delta^2/(2(\sigma_s^2+\sigma_f^2))],\qquad W_{eq}=\sqrt{2\pi}\sigma_f.
The capture formula is independently compared with 48 direct Gaussian-product quadratures. The relative diagnostic holds the photon-background density per wavelength fixed. It is not a reconstructed N2 band or a flight filter optimum. A real cone, polarization, temperature and source population must be folded with measured transmission.
Cell 11 · 285646e8c490 · execution 6
fig,ax=plt.subplots();angles=np.linspace(0,30,121);ss=v.sigma_from_fwhm(1e-9)
for width in [1,2,4,8]:
sf=v.sigma_from_fwhm(width*1e-9)
cap=[v.gaussian_overlap(ss,sf,v.shifted_center(337.1e-9,math.radians(a),1.8)-337.1e-9) for a in angles]
ax.plot(angles,cap,label=f'filter FWHM {width} nm')
ax.set(xlabel='Single-ray incidence (degrees)',ylabel='Unit-peak photon capture fraction',title='Hypothetical 1 nm Gaussian source; effective-index toy');ax.legend();show(fig)
print('4 nm Gaussian FWHM equivalent width:',v.gaussian_equivalent_band(v.sigma_from_fwhm(4e-9))*1e9,'nm')
q=[]
for sw in [.5,1.,2.]:
for fw in [1.,2.,4.,8.]:
for angle in [0.,5.,10.,20.]:
ss=v.sigma_from_fwhm(sw*1e-9);sf=v.sigma_from_fwhm(fw*1e-9);delta=v.shifted_center(337.1e-9,math.radians(angle),1.8)-337.1e-9
q.append(abs(v.gaussian_overlap_integral(ss,sf,delta)-v.gaussian_overlap(ss,sf,delta)))
print('Independent quadratures:',len(q),'maximum absolute capture disagreement:',max(q))

4 nm Gaussian FWHM equivalent width: 4.257868077724905 nm
Independent quadratures: 48 maximum absolute capture disagreement: 8.881784197001252e-16
Cell 12 · d3c8196b2c3e
D10-D12. NEP, noise bandwidth and leak rejection
For one-sided PSD, . A first-order electrical low-pass has ENBW ; an exposure average has ENBW . These Hz widths are unrelated to filter widths in nanometres.
The ideal dark-primary model gives . The following values use assumed , and , not published candidate device specifications. Amplifier noise, sky, radiation, correlations and readout are absent.
Uniform out-of-band blocking requires for the actual detector-weighted unblocked out/in ratio and allowed fraction . R is not known from an OD certificate alone.
Cell 13 · d91d0034881b · execution 7
table([{'wavelength_nm':w,'eta_assumed':.2,'dark_primary_s_assumed':d,'F_assumed':F,
'dark_only_NEP_W_sqrtHz':v.dark_nep(w*1e-9,.2,d,F)}
for w in [337.1,777.4] for d in [1.,50.,1000.] for F in [1.,1.5]],max_rows=12)
table([{'electrical_fc_Hz':fc,'one_sided_ENBW_Hz':v.electrical_enbw_first_order(fc)} for fc in [1e4,5e4]])
print('3 ms boxcar ENBW:',v.boxcar_enbw(.003),'Hz')
table([{'unblocked_detector_weighted_ratio':r,'allowed_leak_fraction':.01,'uniform_OD_required':v.blocking_od(r,.01)} for r in [1e2,1e5,1e9]])
| wavelength_nm | eta_assumed | dark_primary_s_assumed | F_assumed | dark_only_NEP_W_sqrtHz |
|---|
| 337.1 | 0.2 | 1 | 1 | 4.1668031e-18 |
| 337.1 | 0.2 | 1 | 1.5 | 5.1032708e-18 |
| 337.1 | 0.2 | 50 | 1 | 2.9463748e-17 |
| 337.1 | 0.2 | 50 | 1.5 | 3.6085574e-17 |
| 337.1 | 0.2 | 1000 | 1 | 1.3176588e-16 |
| 337.1 | 0.2 | 1000 | 1.5 | 1.6137959e-16 |
| 777.4 | 0.2 | 1 | 1 | 1.8068296e-18 |
| 777.4 | 0.2 | 1 | 1.5 | 2.2129053e-18 |
| 777.4 | 0.2 | 50 | 1 | 1.2776215e-17 |
| 777.4 | 0.2 | 50 | 1.5 | 1.5647603e-17 |
| 777.4 | 0.2 | 1000 | 1 | 5.7136969e-17 |
| 777.4 | 0.2 | 1000 | 1.5 | 6.997821e-17 |
12 rows total; 12 shown.
| electrical_fc_Hz | one_sided_ENBW_Hz |
|---|
| 10000 | 15707.963 |
| 50000 | 78539.816 |
2 rows total; 2 shown.
3 ms boxcar ENBW: 166.66666666666666 Hz
| unblocked_detector_weighted_ratio | allowed_leak_fraction | uniform_OD_required |
|---|
| 100 | 0.01 | 4 |
| 100000 | 0.01 | 7 |
| 1e+09 | 0.01 | 11 |
3 rows total; 3 shown.
Cell 14 · 564725cdbe9a
D13-D14. A pulse plateau, sampling cadence and integration phase
Analog high-pass droop obeys . This step response is different from AC shaping of individual counted photon pulses.
The deterministic sampling example averages a unit ramp over exact exposures, assigns each sample to its midpoint, and interpolates the 10%/90% crossings. At 10 kS/s, samples are 100 microseconds apart; at 50 kS/s, 20 microseconds. A 50 kHz analog signal cannot be assumed unaliased at a 50 kS/s baseband cadence. Noise and unknown source onset make the real problem harder than this calculation.
Cell 15 · 4d4b6d0fae17 · execution 8
table([{'plateau_ms':3.,'allowed_droop':f,'tau_min_s':v.hp_droop_timeconstant(.003,f)[0],
'fc_max_Hz':v.hp_droop_timeconstant(.003,f)[1]} for f in [.01,.05,.1]])
phases=np.linspace(0,.99,100);fig,ax=plt.subplots()
for fs in [1e4,5e4,1e5]:
ax.plot(phases,[v.sampled_rise(30e-6,fs,p)*1e6 for p in phases],label=f'{fs/1000:g}kS/s')
ax.axhline(30,color='black',ls='--',lw=1,label='true30 µs')
ax.set(xlabel='Onset phase within one exposure',ylabel='Interpolated 10-90 rise (µs)',title='Noiseless exact exposure averages; phase bias is estimator-specific');ax.legend();show(fig)
| plateau_ms | allowed_droop | tau_min_s | fc_max_Hz |
|---|
| 3 | 0.01 | 0.29849749 | 0.53318688 |
| 3 | 0.05 | 0.058487177 | 2.7211938 |
| 3 | 0.1 | 0.028473665 | 5.589549 |
3 rows total; 3 shown.
Cell 16 · 4fa07108b0b2
Full-table independent verification
This cell checks every straight-algebra output in all 1,639 rows, all constants, the 48 selected numerical Gaussian integrations and unit/limiting cases. It does not reuse original code functions. It raises if any declared comparison fails. The JSON comparison receipts also retain hashes, field-appropriate tolerances and explicit scope. Tiny SI quantities have no permissive generic absolute floor. Separate in-memory fault controls must reject wrong photon energies, NEP and capture values; reproduce them with python checks/design_negative_controls.py. Notebook execution uses write=False to avoid overwriting the separate verification receipts.
Cell 17 · 2ad4d7974f6f · execution 9
result,recomputed=v.check_design(write=False)
assert result['status']=='PASS',result['failures']
table([{'table':k,'rows_checked':n} for k,n in result['rows_checked'].items()])
print('Status:',result['status'],'scalar comparisons:',result['comparisons'],'independent integrals:',result['independent_Gaussian_quadratures'])
table([{'hand_or_unit_limit':k,'passes':ok} for k,ok in result['unit_and_limiting_checks'].items()],max_rows=30)
| table | rows_checked |
|---|
| etendue | 36 |
| parametric_filter | 372 |
| sampling_phase | 900 |
| ac_coupling | 9 |
| blocking_allocation | 58 |
| dark_only_nep | 72 |
| browser_budget_reference | 192 |
7 rows total; 7 shown.
Status: PASS scalar comparisons: 3679 independent integrals: 48
| hand_or_unit_limit | passes |
|---|
| dimension_Egamma_J | True |
| dimension_radiance_integral_rate_per_s | True |
| dimension_fluence_area_count | True |
| dimension_Rayleigh_tau | True |
| dimension_pressure_column_m-2 | True |
| dimension_NEP_W_per_sqrtHz | True |
| dimension_NEP_squared_ENBW_power_variance | True |
| dimension_diffusion_first_exit_per_s | True |
| dimension_killing_exponent | True |
| dimension_deadtime_occupancy | True |
| nonfinite_comparison_rejected | True |
| SI_photon_J | True |
| hemisphere_solid_2pi_projected_pi | True |
| square80diag_smaller_than_circle80 | True |
| isotropic_aperture_dimensionless | True |
| fluence_referred_count | True |
| Gaussian_identical_centered_1oversqrt2 | True |
| Gaussian_4nm_equivalent_4p2579nm | True |
| ENBW_onepole_10kHz | True |
| NEP_boxcar_variance | True |
| AC_3ms_1pct_tau_0p2985s | True |
| deadtime_zero_gives_unit_rise | True |
| Lambert_zero_height_gain3_escape1 | True |
| diffusion_degenerate_family | True |
24 rows total; 24 shown.
Cell 18 · c8b862ab31c2
Primary references and limits
The full source applicability, equation derivations, units, original-file/function map and residual measured inputs are in methods/design_and_diagnostics.md and checks/design_method_map.json. No published device NEP, lifetime damage, calibrated band capture or useful rate is established by these assumed scenarios.