Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
PeakOTron
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
UHHDetLab
SiPM
PeakOTron
Commits
6fa17cf2
Commit
6fa17cf2
authored
2 years ago
by
Jack Christopher Hutchinson Rolph
Browse files
Options
Downloads
Patches
Plain Diff
Delete Model.py
parent
e43c2a67
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Model.py
+0
-505
0 additions, 505 deletions
Model.py
with
0 additions
and
505 deletions
Model.py
deleted
100644 → 0
+
0
−
505
View file @
e43c2a67
from
scipy.signal
import
fftconvolve
as
convolve
from
scipy.interpolate
import
interp1d
from
scipy.stats
import
poisson
,
norm
,
binom
from
AdditionalPDFs
import
gpoisson
,
borel
from
scipy.integrate
import
simps
from
numba
import
njit
import
numpy
as
np
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
########################################################################################################
## DETECTOR RESPONSE MODEL
########################################################################################################
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
########################################################################################################
## VARIABLES:
########################################################################################################
########################################################################################################
## Q: bin centres of studied charge distribution in arb. units;
## Q_0: pedestal position in arb. units
## G: gain in arb. units
## mu: mean number of Geiger discharges in n.p.e
## lbda: GP-branching parameter (unitless)
## sigma_0: electonics noise/pedestal width in arb. units
## sigma_1: gain spread width in arb. units;
## tau_Ap: afterpulse time constant in nanoseconds;
## p_Ap: afterpulse scaling parameter (unitless)
## DCR: dark count rate in gigahertz;
## tau: slow-component time constant of SiPM pulse in nanoseconds
## tau_R: recovery time of SiPM in nanoseconds
## t_gate: gate length in nanoseconds
## t_0: pre-gate integration window in nanoseconds.
## k_max: estimated maximum number of peaks to fit, based on percentile of Poisson distribution with estimated mean in PeakOTron.
## len_pad: number of bins to pad for convolution. Default value: 100 bins.
##
########################################################################################################
########################################################################################################
## FUNCTION DEFINITIONS:
########################################################################################################
########################################################################################################
## epsilon()
########################################################################################################
##
## Returns machine epsilon for thresholding zeros
##
########################################################################################################
@njit
(
'
float64()
'
)
def
epsilon
():
return
np
.
finfo
(
np
.
float64
).
eps
########################################################################################################
## sigmak(k, sigma_0, sigma_1)
########################################################################################################
##
## Returns width of peak number k, sigma_k(k, sigma_0, sigma_1) = sqrt(sigma_0^2 + k*sigma__1^2)
##
########################################################################################################
@njit
def
sigmak
(
k
,
sigma_0
,
sigma_1
):
return
np
.
sqrt
(
sigma_0
**
2
+
k
*
sigma_1
**
2
)
########################################################################################################
## dabsQdt(t, tau, t_gate))
########################################################################################################
##
## Returns |dQ/dt|(t, tau, t_gate) see Chmill Et Al.
##
########################################################################################################
@njit
def
dabsQdt
(
t
,
tau
,
t_gate
):
return
2
*
np
.
exp
(
-
t_gate
/
(
2
*
tau
))
*
np
.
abs
(
np
.
sinh
((
t_gate
/
2
-
t
)
/
tau
))
/
tau
########################################################################################################
## dp1dt(t, tau_R, tau_Ap, t_gate)
########################################################################################################
##
## Returns dα/dt(t, tau_R, tau_Ap, t_gate) see Chmill Et Al.
##
########################################################################################################
@njit
def
dp1dt
(
t
,
tau_R
,
tau_Ap
,
t_gate
):
return
((
tau_Ap
+
tau_R
)
/
(
tau_Ap
*
(
tau_Ap
-
np
.
exp
(
-
t_gate
/
tau_Ap
)
*
(
tau_Ap
+
tau_R
*
(
1
-
np
.
exp
(
-
t_gate
/
tau_Ap
))))))
*
(
1
-
np
.
exp
(
-
t
/
tau_R
))
*
np
.
exp
(
-
t
/
tau_Ap
)
########################################################################################################
## tQ( Q, tau, t_gate)
########################################################################################################
##
## Returns time as a function of charge.
##
########################################################################################################
@njit
def
tQ
(
Q
,
tau
,
t_gate
):
return
t_gate
/
2
-
tau
*
np
.
arccosh
(((
1
-
Q
)
*
np
.
exp
(
t_gate
/
(
2
*
tau
))
+
np
.
exp
(
-
t_gate
/
(
2
*
tau
)))
/
2
)
########################################################################################################
## PH_max(t_gate, tau)
########################################################################################################
##
## Returns maximum pulse height of afterpulse
##
########################################################################################################
@njit
def
PH_max
(
t_gate
,
tau
):
return
(
1
-
np
.
exp
(
-
t_gate
/
(
2
*
tau
)))
**
2
########################################################################################################
## Alpha(tau_R, tau_Ap, t_gate, p_Ap)
########################################################################################################
##
## Returns total afterpulse probability, α, occuring between 0 and t_gate.
##
########################################################################################################
@njit
def
Alpha
(
tau_R
,
tau_Ap
,
t_gate
,
p_Ap
):
return
(
p_Ap
/
(
tau_Ap
+
tau_R
))
*
(
tau_Ap
-
np
.
exp
(
-
t_gate
/
tau_Ap
)
*
(
tau_Ap
+
tau_R
*
(
1
-
np
.
exp
(
-
t_gate
/
tau_R
))))
########################################################################################################
## dAlpha(tau_R, tau_Ap, t_gate, p_Ap)
########################################################################################################
##
## Returns error on total afterpulse probability, α, occuring between 0 and t_gate.
##
########################################################################################################
@njit
def
dAlpha
(
tau_R
,
tau_Ap
,
t_gate
,
p_Ap
,
dtau_Ap
,
dp_Ap
):
dalphadtauAp
=
p_Ap
*
((
t_gate
*
(
-
tau_Ap
-
tau_R
*
(
1
-
np
.
exp
(
-
t_gate
/
tau_R
)))
*
np
.
exp
(
-
t_gate
/
tau_Ap
))
/
tau_Ap
**
2
+
1
-
np
.
exp
(
-
t_gate
/
tau_Ap
))
/
(
tau_Ap
+
tau_R
)
-
p_Ap
*
(
tau_Ap
-
(
tau_Ap
+
tau_R
*
(
1
-
np
.
exp
(
-
t_gate
/
tau_R
)))
*
np
.
exp
(
-
t_gate
/
tau_Ap
))
/
(
tau_Ap
+
tau_R
)
**
2
dalphadpAp
=
(
tau_Ap
-
(
tau_Ap
+
tau_R
*
(
1
-
np
.
exp
(
-
t_gate
/
tau_R
)))
*
np
.
exp
(
-
t_gate
/
tau_Ap
))
/
(
tau_Ap
+
tau_R
)
dalpha
=
np
.
sqrt
((
dalphadtauAp
**
2
)
*
(
dtau_Ap
**
2
)
+
(
dalphadpAp
**
2
)
*
(
dp_Ap
**
2
))
return
dalpha
########################################################################################################
## DiracDelta(length, idx_0, dx)
########################################################################################################
##
## Returns Dirac Delta Function at the bin, with probability density 1/dx.
##
########################################################################################################
@njit
def
DiracDelta
(
length
,
idx_0
,
dx
):
delta
=
np
.
zeros
(
length
)
delta
[
idx_0
]
=
1
/
dx
return
delta
########################################################################################################
## dp1dQ(Q, tau, tau_R, tau_Ap, t_gate)
########################################################################################################
##
## Returns afterpulse p.d.f as a function of n.p.e
## Note: as in Chmill et al. However, the two branches of solutions given by t and t_gate -t are summed together. This demonstrably yields a normalised probability distribution.
##
########################################################################################################
@njit
def
dp1dQ
(
Q
,
tau
,
tau_R
,
tau_Ap
,
t_gate
):
_PH_max
=
PH_max
(
t_gate
,
tau
)
tb0
=
tQ
(
Q
,
tau
,
t_gate
)
tb1
=
t_gate
-
tb0
N0
=
dp1dt
(
tb0
,
tau_R
,
tau_Ap
,
t_gate
)
N1
=
dp1dt
(
tb1
,
tau_R
,
tau_Ap
,
t_gate
)
D0
=
dabsQdt
(
tb0
,
tau
,
t_gate
)
D1
=
dabsQdt
(
tb1
,
tau
,
t_gate
)
D0
=
np
.
where
(
D0
<
epsilon
(),
epsilon
(),
D0
)
D1
=
np
.
where
(
D1
<
epsilon
(),
epsilon
(),
D1
)
pdf0
=
N0
/
D0
pdf1
=
N1
/
D1
pdf
=
pdf0
+
pdf1
pdf
=
np
.
where
((
Q
>
0
)
&
(
Q
<
_PH_max
),
pdf
,
0
)
return
pdf
########################################################################################################
## dpDCR1dQ(Q, tau, t_gate, t_0)
########################################################################################################
## Returns dark count p.d.f as a function of n.p.e
## Note: the distribution is normalised by factor (t_gate+t_0)/tau
########################################################################################################
@njit
def
dpDCR1dQ
(
Q
,
tau
,
t_gate
,
t_0
):
Q_min
=
np
.
exp
(
-
t_0
/
tau
)
*
(
1
-
np
.
exp
(
-
t_gate
/
tau
))
Q_max
=
(
1
-
np
.
exp
(
-
t_gate
/
tau
))
Q_th
=
np
.
where
(
np
.
abs
(
Q
)
<
epsilon
(),
epsilon
(),
Q
)
pdf_bfg
=
np
.
where
((
Q_th
>
Q_min
)
&
(
Q_th
<
Q_max
),
1
/
(
Q_th
),
0
)
pdf_dg
=
np
.
where
((
Q_th
>
0
)
&
(
Q_th
<
Q_max
),
1
/
(
1
-
Q_th
),
0
)
pdf
=
(
pdf_bfg
+
pdf_dg
)
*
(
tau
/
(
t_gate
+
t_0
))
return
pdf
########################################################################################################
## I_dp1dQ(Q, tau, t_gate, t_0)
########################################################################################################
##
## Returns dp1dQ, corrects for any nans/infs and ensures normalisation by applying Simpson's rule.
########################################################################################################
def
I_dp1dQ
(
Q
,
dx
,
tau
,
tau_R
,
tau_Ap
,
t_gate
):
I
=
dp1dQ
(
Q
,
tau
,
tau_R
,
tau_Ap
,
t_gate
)
I
=
np
.
nan_to_num
(
I
,
nan
=
0.0
,
posinf
=
0.0
,
neginf
=
0.0
)
I
=
I
/
max
(
epsilon
(),
simps
(
I
,
dx
=
dx
))
return
I
########################################################################################################
## I_dpDCR1dQ(Q, dx, tau, t_gate, t_0)
########################################################################################################
##
## Returns dpDCR1dQ, corrects for any nans/infs and ensures normalisation by applying Simpson's rule.
########################################################################################################
def
I_dpDCR1dQ
(
Q
,
dx
,
tau
,
t_gate
,
t_0
):
I
=
dpDCR1dQ
(
Q
,
tau
,
t_gate
,
t_0
)
I
=
np
.
nan_to_num
(
I
,
nan
=
0.0
,
posinf
=
0.0
,
neginf
=
0.0
)
I
=
I
/
max
(
epsilon
(),
simps
(
I
,
dx
=
dx
))
return
I
########################################################################################################
## Convolve(A, B, idx_0, length, dx, norm=True)
########################################################################################################
##
## Calculates convolution of A and B using scipy fftconvolve, selects the convolved range relative to the pedestal index due to convolution shift,
## and multiplies by dx to renormalise the distribution. Then, corrects for any nans/infs and ensures normalisation by applying Simpson's rule.
##
########################################################################################################
def
Convolve
(
A
,
B
,
idx_0
,
length
,
dx
,
norm
=
True
):
A_o_B
=
convolve
(
A
,
B
)[
idx_0
:
length
+
idx_0
]
*
dx
A_o_B
=
np
.
nan_to_num
(
A_o_B
,
nan
=
0.0
,
posinf
=
0.0
,
neginf
=
0.0
)
if
(
norm
):
A_o_B
=
A_o_B
/
max
(
epsilon
(),
simps
(
A_o_B
,
dx
=
dx
))
return
A_o_B
########################################################################################################
## DRM(Q, Q_0, G, mu, lbda, sigma_0, sigma_1, tau_Ap, p_Ap, DCR, tau, tau_R, t_gate, t_0, k_max, len_pad)
########################################################################################################
##
## Calculates full detector response model.
## Notes:
## - The model is fitted in n.p.e scale. k = (Q - Q_0)/G.
## - To rescale to the input parameter unit, the final pdf is scaled by a factor of 1/G -
## this is because dp/dQ = (dp/dk)*(dk/dQ), dk/dQ = d/dQ (Q - Q_0)/G = 1/G
##
########################################################################################################
def
DRM
(
Q
,
Q_0
,
G
,
mu
,
lbda
,
sigma_0
,
sigma_1
,
tau_Ap
,
p_Ap
,
DCR
,
tau
,
tau_R
,
t_gate
,
t_0
,
k_max
,
len_pad
):
########################################################################################################
# Primary Geiger Model
#########################################################################################################
##
## 1. Correct negative t_0 and ensures len_pad is an integer.
## 2. Calculate padded Q and indices of the original Q so that these can be selected at the end of the function.
## 3. Convert Q to n.p.e units for the main fit.
##
########################################################################################################
t_0
=
abs
(
t_0
)
len_pad
=
int
(
len_pad
)
len_Q
=
len
(
Q
)
len_Q_pad
=
len_Q
+
2
*
len_pad
Q_idx
=
np
.
arange
(
0
,
len_Q
)
Q_idx_pad
=
np
.
arange
(
-
len_pad
,
len_Q
+
len_pad
)
f_lin
=
interp1d
(
Q
,
Q_idx
,
fill_value
=
'
extrapolate
'
)
f_lin_inv
=
interp1d
(
Q_idx
,
Q
,
fill_value
=
'
extrapolate
'
)
Q_pad
=
f_lin_inv
(
Q_idx_pad
)
k_pad
=
(
Q_pad
-
Q_0
)
/
G
dx
=
abs
(
f_lin_inv
(
1
)
-
f_lin_inv
(
0
))
dx_k
=
dx
/
G
idx_k_0_pad
=
np
.
argmin
(
abs
(
k_pad
))
Q_idx_orig
=
np
.
where
(
np
.
in1d
(
Q_idx_pad
,
np
.
intersect1d
(
Q_idx_pad
,
Q_idx
)
),
True
,
False
)
k_pg
=
np
.
arange
(
0
,
max
(
k_max
,
3
)).
astype
(
int
)
########################################################################################################
# Primary Geiger Model
########################################################################################################
## 1. Calculate the probabilities:
## - Primary Geiger, GP(k;μ,λ)
## - Afterpulse, Binom(k, i; alpha)
##
## 2. Calculate the p.d.fs:
## - dp0dQs(Q; sigma_k(k; sigma_0/G, sigma_1/G) - Gaus(Q; μ=k, σ = sigma_k)
## - Note: sigma_0 and sigma_1 are in bin units. To convert to n.p.e, divide by G.
##
## - dpndQs(k; tau, tau_R, tau_Ap, t_gate) - Afterpulse distributions.
## dp2dQ = dp1dQ o dp1dQ, dp3dQ = dp1dQ o dp1dQ o dp1dQ ... etc, where o is convolution.
##
## 3. Calculate primary Geiger p.d.f:
## - For zeroth order afterpulse, return Binom(0; k, α) x GP(k;μ,λ) x Gaus(Q; k; sigma_k)
## - For nth order afterpulse, return Binom(n, k, α) x GP(k;μ,λ) x (dpndQ o Gaus(Q; k; sigma_k)) (Afterpulse p.d.f convolved with noise peak)
## - The above statement is valid because of convolution distributivity rules: f o (g+h) = f o g + f o h
## - Sum across all k to k_max;
##
## RESULT: pdf_pg - Primary Geiger Discharge p.d.f
########################################################################################################
pdf_pg
=
np
.
zeros
(
len_Q_pad
)
Ppgs
=
np
.
expand_dims
(
gpoisson
.
pmf
(
k_pg
,
mu
,
lbda
),
-
1
)
Pns
=
np
.
zeros
((
int
(
k_max
),
int
(
k_max
)))
alpha
=
Alpha
(
tau_R
,
tau_Ap
,
t_gate
,
p_Ap
)
dp0dQs
=
np
.
vstack
([
norm
.
pdf
(
k_pad
,
loc
=
_k
,
scale
=
sigmak
(
_k
,
sigma_0
/
G
,
sigma_1
/
G
))
for
_k
in
k_pg
])
dpndQs
=
[]
for
_k
in
k_pg
:
if
(
_k
==
0
):
_dpndQ
=
np
.
zeros
(
len
(
k_pad
))
Pns
[
0
,
0
]
=
binom
.
pmf
(
0
,
0
,
alpha
)
elif
(
_k
==
1
):
_dpndQ
=
I_dp1dQ
(
k_pad
,
dx_k
,
tau
,
tau_R
,
tau_Ap
,
t_gate
)
Pns
[
1
,
0
:
2
]
=
np
.
array
(
binom
.
pmf
(
np
.
arange
(
0
,
2
).
astype
(
int
),
_k
,
alpha
))
else
:
_dpndQ
=
Convolve
(
dpndQs
[
1
],
dpndQs
[
-
1
],
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
Pns
[
_k
,
0
:
_k
+
1
]
=
np
.
array
(
binom
.
pmf
(
np
.
arange
(
0
,
_k
+
1
).
astype
(
int
),
_k
,
alpha
))
dpndQs
.
append
(
_dpndQ
)
dpndQs
=
np
.
vstack
(
dpndQs
)
for
_k
in
k_pg
:
_dp0dQ
=
float
(
Pns
[
_k
,
0
])
*
dp0dQs
[
_k
,
:]
if
(
_k
>
0
):
_dpndQ_sum
=
np
.
sum
(
np
.
vstack
([
float
(
Pns
[
_k
,
_j
])
*
Convolve
(
dpndQs
[
_j
,
:],
dp0dQs
[
_k
,
:],
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
for
_j
in
range
(
1
,
_k
+
1
)
]),
axis
=
0
)
else
:
_dpndQ_sum
=
np
.
zeros
(
len_Q_pad
)
_dp0dQ
=
np
.
nan_to_num
(
_dp0dQ
,
nan
=
0.0
,
posinf
=
0.0
,
neginf
=
0.0
)
_dpndQ_sum
=
np
.
nan_to_num
(
_dpndQ_sum
,
nan
=
0.0
,
posinf
=
0.0
,
neginf
=
0.0
)
pdf_pg
+=
float
(
Ppgs
[
_k
])
*
(
_dp0dQ
+
_dpndQ_sum
)
########################################################################################################
# Dark Model
########################################################################################################
##
## 1. Calculate the probabilities:
## - μDCR = DCR x (t_0 + t_gate)
## - Primary Geiger - Poisson(k;μDCR)
## - XTalk - Borel(k;λ)
##
## 2. Calculate the p.d.fs:
## - Notation as in Chmill et al:
## - f_1 is 1st order dark distribution; f_2 = f_1 o f_1, f_3 = f_1 o f_1 o f_1 ... etc
## - h_1 is 1st order stretched XT distribution; h_1 = 1/2 x f_1(Q/2; pars), h_2 = 1/3 x f_1(Q/3; pars)
## - Convolutions of f_n and h_m shown as f_n_o_h_m.
##
## 3. Sum probabilities and pdfs as in Chmill et al.
## - Note: The 0th term is incorrect in Chmill et al. The probability should be Poisson(0; μDCR); the distribution should be
## Dirac Delta distribution at pedestal 𝛿(Q - Q_0) (i.e. no discharge.)
##
## 4. Renormalise distribution
## - Since p.d.f only goes up to 4th order, the distribution is not always correctly normalised.
## We correct for the normalisation by appling Simpson's rule. The effect of poor normalisation is only relevant
## for λ > 0.4: 5% off at this value.
##
## RESULT: pdf_dark - Dark Count p.d.f
########################################################################################################
mu_DCR
=
DCR
*
(
t_0
+
t_gate
)
Pp0
=
float
(
poisson
.
pmf
(
0
,
mu_DCR
))
Pp1
=
float
(
poisson
.
pmf
(
1
,
mu_DCR
))
Pp2
=
float
(
poisson
.
pmf
(
2
,
mu_DCR
))
Pp3
=
float
(
poisson
.
pmf
(
3
,
mu_DCR
))
Pp4
=
float
(
poisson
.
pmf
(
4
,
mu_DCR
))
Pb0
=
float
(
borel
.
pmf
(
0
,
lbda
))
Pb1
=
float
(
borel
.
pmf
(
1
,
lbda
))
Pb2
=
float
(
borel
.
pmf
(
2
,
lbda
))
Pb3
=
float
(
borel
.
pmf
(
3
,
lbda
))
f_0
=
np
.
zeros
(
len_Q_pad
)
f_0
[
idx_k_0_pad
]
=
1
/
dx_k
f_1
=
I_dpDCR1dQ
(
k_pad
,
dx_k
,
tau
,
t_gate
,
t_0
)
f_2
=
Convolve
(
f_1
,
f_1
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
f_3
=
Convolve
(
f_1
,
f_2
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
f_4
=
Convolve
(
f_1
,
f_3
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
h_1
=
I_dpDCR1dQ
(
k_pad
/
(
1
+
1
),
dx_k
,
tau
,
t_gate
,
t_0
)
/
(
1
+
1
)
h_2
=
I_dpDCR1dQ
(
k_pad
/
(
2
+
1
),
dx_k
,
tau
,
t_gate
,
t_0
)
/
(
2
+
1
)
h_3
=
I_dpDCR1dQ
(
k_pad
/
(
3
+
1
),
dx_k
,
tau
,
t_gate
,
t_0
)
/
(
3
+
1
)
f_1_o_h_1
=
Convolve
(
f_1
,
h_1
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
f_1_o_h_2
=
Convolve
(
f_1
,
h_2
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
h_1_o_h_1
=
Convolve
(
h_1
,
h_1
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
f_2_o_h_1
=
Convolve
(
f_2
,
h_1
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
dp0DCRdQ
=
Pp0
*
f_0
dp1DCRdQ
=
Pp1
*
Pb0
*
f_1
dp2DCRdQ
=
Pp1
*
Pb1
*
h_1
+
Pp2
*
(
Pb0
**
2
)
*
f_2
dp3DCRdQ
=
Pp1
*
Pb2
*
h_2
+
2
*
Pp2
*
Pb0
*
Pb1
*
f_1_o_h_1
+
Pp3
*
(
Pb0
**
3
)
*
f_3
dp4DCRdQ
=
Pp1
*
Pb3
*
h_3
+
2
*
Pp2
*
Pb0
*
Pb2
*
f_1_o_h_2
+
Pp2
*
(
Pb1
**
2
)
*
h_1_o_h_1
+
3
*
Pp3
*
(
Pb0
**
2
)
*
Pb1
*
f_2_o_h_1
+
Pp4
*
(
Pb0
**
4
)
*
f_4
pdf_dark
=
dp0DCRdQ
+
dp1DCRdQ
+
dp2DCRdQ
+
dp3DCRdQ
+
dp4DCRdQ
pdf_dark
=
pdf_dark
/
max
(
epsilon
(),
simps
(
pdf_dark
,
dx
=
dx_k
))
########################################################################################################
# Convolve Primary Geiger and Dark Models
########################################################################################################
##
## 1. Convolve and normalise pdf_pg and pdf_dark
## pdf_drm = pdf_pg o pdf_dark
##
## RESULT: pdf_drm, final detector response model p.d.f
########################################################################################################
pdf_drm
=
Convolve
(
pdf_pg
,
pdf_dark
,
idx_k_0_pad
,
len_Q_pad
,
dx_k
,
norm
=
True
)
pdf_drm
=
pdf_drm
[
Q_idx_orig
]
/
G
return
pdf_drm
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment