From cfdff3a5460601d49a2051884846a77d9378422c Mon Sep 17 00:00:00 2001 From: Siddharth U Date: Fri, 25 Sep 2026 02:13:12 +0530 Subject: [PATCH] fix(python): set realistic default photon count and clamp in CTnoise (#780) Replaces the erroneous `nextpow2` Poisson exponent with a photon count of 60000 (or `max(proj)/5` for very bright projections), matching the MATLAB `addCTnoise.m` reference. Also adds a clamp to 1e-6 before the `log` step to prevent `NaN` outputs when simulated noise pushes the projection to zero or below. Closes #780 --- Python/tigre/utilities/CTnoise.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Python/tigre/utilities/CTnoise.py b/Python/tigre/utilities/CTnoise.py index a009132b..82f7954a 100644 --- a/Python/tigre/utilities/CTnoise.py +++ b/Python/tigre/utilities/CTnoise.py @@ -9,7 +9,9 @@ def add(projections, Gaussian=None, Poisson=None): "Poisson value should be an scalar, is " + str(type(Poisson)) + " instead." ) else: - Poisson = np.ceil(np.log2(np.max(np.abs(projections)))) # nextpow2 + Poisson = 60000.0 + if np.max(projections) > Poisson: + Poisson = float(np.max(projections) / 5.0) if Gaussian is not None: if not isinstance(Gaussian, np.ndarray): raise ValueError( @@ -24,6 +26,7 @@ def add(projections, Gaussian=None, Poisson=None): projections = RNG.add_noise(projections, Gaussian[0], Gaussian[1]) + projections[projections <= 0] = 1e-6 projections = -np.log(projections / Poisson) * max_proj projections = np.float32(projections) return projections