@@ -26,7 +26,6 @@ Fit a Gaussian Mixture Model to the given pe calibration data and return the fit
26
26
function fit_sipm_spectrum (pe_cal:: Vector{<:Real} , min_pe:: Real = 0.5 , max_pe:: Real = 3.5 ;
27
27
n_mixtures:: Int = ceil (Int, (max_pe - min_pe) * 4 ), nIter:: Int = 25 , nInit:: Int = 50 ,
28
28
method:: Symbol = :kmeans , kind= :diag , Δpe_peak_assignment:: Real = 0.3 , f_uncal:: Function = identity, uncertainty:: Bool = true )
29
-
30
29
# first filter peak positions out of amplitude vector
31
30
amps_fit = filter (in (min_pe.. max_pe), pe_cal)
32
31
@@ -106,9 +105,34 @@ function fit_sipm_spectrum(pe_cal::Vector{<:Real}, min_pe::Real=0.5, max_pe::Rea
106
105
get_pe_pos = pe -> let sel = in .(μ, (- Δpe_peak_assignment.. Δpe_peak_assignment) .+ pe)
107
106
dot (view (μ, sel), view (w, sel)) / sum (view (w, sel))
108
107
end
108
+
109
+ # get pe resolution (FWHM)
109
110
get_pe_res = pe -> let sel = in .(μ, (- Δpe_peak_assignment.. Δpe_peak_assignment) .+ pe)
110
- sqrt (dot (view (σ, sel).^ 2 , view (w, sel).^ 2 ))
111
- end
111
+ model_parameters = [
112
+ view (μ_ml, sel),
113
+ view (σ_ml, sel),
114
+ view (w_ml, sel)
115
+ ]
116
+
117
+ # Find maximum of PDF in the expected range, step size depends on the maximum variance of the single gaussians
118
+ range_steps = maximum (getfield .(view (μ, sel), :err )) / 100
119
+ x_max = 0.0
120
+ f_max = 0.0
121
+ # Search range depends on the selection of gaussians
122
+ for x_i in minimum (view (μ_ml, sel)): range_steps: maximum (view (μ_ml, sel))
123
+ if _gmm_pdf (x_i, model_parameters) > f_max
124
+ x_max = x_i
125
+ f_max = _gmm_pdf (x_i, model_parameters)
126
+ end
127
+ end
128
+ f_half_max = f_max / 2
129
+
130
+ # Find all the points where the half max is reached
131
+ roots = find_zeros (x -> f_half_max - _gmm_pdf (x, model_parameters), 0 , 5 )
132
+ return maximum (roots) - minimum (roots)
133
+ end
134
+
135
+
112
136
n_pos_mixtures = [count (in .(μ, (- Δpe_peak_assignment.. Δpe_peak_assignment) .+ pe)) for pe in pes]
113
137
114
138
pe_pos = get_pe_pos .(pes)
@@ -170,4 +194,10 @@ function _gmm_binned_loglike_func(
170
194
xlogy .(bin_counts, binned_density)
171
195
)
172
196
return f_loglike
173
- end
197
+ end
198
+
199
+ function _gmm_pdf (x:: Real , μ:: AbstractVector{<:Real} , σ:: AbstractVector{<:Real} , w:: AbstractVector{<:Real} )
200
+ return sum (@. w * exp (- 0.5 * ((x - μ) / σ)^ 2 ) / (σ * sqrt (2 π)))
201
+ end
202
+
203
+ _gmm_pdf (x:: Real , V:: Vector{<:AbstractVector{<:Real}} ) = _gmm_pdf (x, V... )
0 commit comments