#! /usr/bin/env python3
##Python code to simulate DQE for counting mode in a diffraction spot
import numpy as np
from math import sqrt
from sys import stderr

# Number of trials.
M = 256

# Maximum number of electrons per second.
N_max = 16384

# Framerate of the detector in Hz.
f = 250

# Low limits inclusive, high limits exclusive for both randint() and
# range().
trials = np.zeros((N_max, 2))

print("Trial ", end='', file=stderr)
for i in range(M):

    if i % 10 == 0:
        print(f"{i}... ", end='', file=stderr)
        stderr.flush()

    for N_in in range(1, N_max):
        N_out = np.unique(np.random.randint(0, high=f, size=N_in)).size
        dqe = N_out / N_in

        trials[N_in, 0] += dqe
        trials[N_in, 1] += dqe**2
print("", file=stderr)



# Preamble for Gnuplot file.
print("set output \"simulation.pdf\"")
print("set term pdfcairo dash")
print("set termopt enhanced")

print("set border 3")
print("set colors podo")
print("set format x \"10^{%T}")
print("set format y \"%3.1f")
print("set logscale x")
print("set size ratio 1.0 1.0")
print("set xlabel \"Exposure (e^{-} px^{-1} s^{-1})\"")
print("set ylabel \"DQE\"")
print("set yrange [0:1.1]")
print("set xtics out nomirror")
print("set ytics out nomirror 0.2")

# Do the statistics, plot with inline data
print("plot \"-\" using 1:2:3 with yerrorbars title \"\"")
for N_in in range(1, N_max):
    avg = trials[N_in, 0] / M
    var = trials[N_in, 1] / M - avg**2
    print(f"{N_in} {avg} {sqrt(var) if var > 0 else 0}")
print("EOF")
