## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• Jun 21 2019 16:00
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
• Jun 21 2019 13:31
GitLab | David Lucsanyi pushed 3 commits to Pyxel
David Lucsanyi
@david.lucsanyi_gitlab

# Welcome in the Pyxel community!

Let's discuss, share, exchange knowledge, models, ideas, tools with each other about imaging detector modelling using the Pyxel framework and community!
David Lucsanyi
@david.lucsanyi_gitlab
Elizabeth George
@lizinvt_gitlab
Hello everyone. We've agreed to keep track of which models we would like to include in Pyxel by raising an issue for each model, with a detailed enough description that anyone could take over the issue and implement the model.
Paolo Caputo
@paolcaputo_gitlab
Hello! I am trying to access the GitLab repository but it seems not to exist. Maybe is not public?
Benoît Serra
@benoit.serra_gitlab
Hi Paolo, the repository is not public -yet-. To be able to checkout PyXel you would have to access the repository and send a request to a maintainer or owner. Do you still have the error 404? The page seems to be accessible for me.
Israel Vaughn
@israel.vaughn_gitlab
Hello @benoit.serra_gitlab it is also giving me the 404. I've partially developed something similar in Matlab, which I'm porting to Python, but then I found this. I noticed that the Optics module is not propagated in the documentation, I could write some of the technical code for optical systems, but it would be not as robust as ZEMAX for example, however it can take an arbitrary wavefront aberration function in the pupil and propagate it to the image plane. Cheers,
Lawrence Jones
@l_jones_gitlab

Hello!

Thank you for the repository access, I am finding Pyxel to be an incredibly useful tool and wanted to share a small change I have made while using it.

I have been attempting to use Pyxel to generate data that matches results I am getting off of a lab CMOS image sensor. The built in pipeline works exactly as needed, however the charge_generation.photoelectrons.simple_conversion model appears to be suppressing noise, changing the $Noise = \sqrt{Signal}$ shot noise relationship expected at that point in the detector.

The current modification I have made is to models.charge_generation.photoelectrons.simple_conversion (line 35):

detector_charge[slice(0, photon_rows), slice(0, photon_cols)] = (
ph.array * ch.qe * ch.eta
)

changing it to (in a fresh function):

detector_charge[slice(0, photon_rows), slice(0, photon_cols)] = (
ph.array * ch.qe * ch.eta
)

This changes the calculation from a linear multiplication to binomial sampling, which primarily changes the noise in the output pixel values. Considering the contributions to the output noise by the input noise ($Noise_{in}$) and the noise of the charge generation model ($Noise_{model}$) (I have taken the signal to be the mean pixel value):
-
$Noise_{out}^2 = (Noise_{in}.Gain_{model})^2 + Noise_{model}^2$
-
For linear multiplication:
-
$Noise_{out}^2 = (\sqrt{Signal_{in}}.QE)^2 + 0^2$

-
$Noise_{out}^2 = (\sqrt{Signal_{out}}.\sqrt{QE})^2$
-
$Noise_{out} = \sqrt{Signal_{out}} .\sqrt{QE}$
-
Which is less than expected (when QE<1), however for binomial sampling:
-
$Noise_{out}^2 = (\sqrt{Signal_{in}}.QE)^2 + Noise_{charge generation}^2$
-
$= Signal_{in}.QE^2 + np(1-p)$ <- the variance of the binomial distribution
-
( $QE$ is the probability of success, $p$, and $Signal_{in}$(in photons) is the number of trials, $n$, of the binomial distribution)
-
$= Signal_{in}.QE^2 + Signal_{in}.QE(1-QE)$
-
$= Signal_{in}.QE^2 + Signal_{in}.QE - Signal_{in}.QE^2$
-
$= Signal_{in}.QE=$
-
$Noise_{out} = \sqrt{Signal_{in}.QE} = \sqrt{Signal_{out}}$

-
Which matches the expected signal to noise relationship. Making this change has resulted in excellent agreement between the Pyxel outputs and my lab data. For example the plot below includes three sets of PTC data, two generated by Pyxel, with this modification ('Binomial Charge Generation') and without ('Linear Charge Generation'), alongside PTC data points captured from the lab sensor ('Experimental Results'). The plot demonstrates the lower noise seen in the output data using the linear charge_generation model. Both simulation runs were made with the parametric_ptc.yaml example script with changes to the detector values to match the lab sensor, the simulation was completed with a QE of 60%.

I am aware that numpy.random.binomial will break when (ch.qe * ch.eta) > 1, or when any elements of ph.array are not ints. I have stopped the latter from crashing the program by using the numpy.random.default_rng.binomial function, but the change is less elegant.

Lawrence Jones
@l_jones_gitlab
Apologies, I have made an error while transcribing my previous comment, the changed function is:
detector_charge[slice(0, photon_rows), slice(0, photon_cols)] = (
numpy.random.binomial(n = ph.array ,p =(ch.qe * ch.eta))
)