From 360905301ee437036032face95a54fc58978508d Mon Sep 17 00:00:00 2001
From: Roy Smart <roytsmart@gmail.com>
Date: Tue, 14 Jan 2025 14:55:24 -0700
Subject: [PATCH] Modified `optika.sensors.electrons_measured()` to properly
 account for discretization noise.

---
 optika/sensors/_materials/_materials.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/optika/sensors/_materials/_materials.py b/optika/sensors/_materials/_materials.py
index b82c577..676a30a 100644
--- a/optika/sensors/_materials/_materials.py
+++ b/optika/sensors/_materials/_materials.py
@@ -741,9 +741,11 @@ def electrons_measured(
     photons_absorbed_expected = absorbance * photons.to(u.ph)
     photons_absorbed = na.random.poisson(photons_absorbed_expected)
     electrons_expected = iqy * photons_absorbed
-    electrons = na.random.poisson(electrons_expected / fano_noise) * fano_noise
+    d = (2 / 12) * (u.electron / u.photon) ** 2
+    f = fano_noise + d * (photons_absorbed - 1 * u.photon) / electrons_expected
+    electrons = na.random.poisson(electrons_expected / f) * f
     e_fractional, e_integral = np.modf(electrons / u.electron)
-    e_random = na.random.uniform(0, 1, electrons.shape) < e_fractional
+    e_random = na.random.binomial(1, e_fractional)
     electrons_total = e_integral + e_random
     result = na.random.binomial(electrons_total.astype(int), cce)
     return result * u.electron