TDCRPy 0.0.6__py3-none-any.whl → 0.0.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Code/TDCRPy.py +2 -2
- Code/TDCR_model_lib.py +24 -15
- Code/test.py +3 -0
- TDCRPy/Activity_TDCR.py +305 -0
- TDCRPy/EfficiencyProfils.py +96 -0
- TDCRPy/TDCRPy.py +425 -0
- TDCRPy/TDCR_model_lib.py +1790 -0
- TDCRPy/TDCRoptimize.py +99 -0
- TDCRPy/__init__.py +3 -0
- TDCRPy/decay.py +29 -0
- TDCRPy/test.py +12 -0
- TDCRPy/test1.py +87 -0
- TDCRPy-0.0.8.dist-info/METADATA +88 -0
- TDCRPy-0.0.8.dist-info/RECORD +23 -0
- TDCRPy-0.0.6.dist-info/METADATA +0 -31
- TDCRPy-0.0.6.dist-info/RECORD +0 -14
- {TDCRPy-0.0.6.dist-info → TDCRPy-0.0.8.dist-info}/LICENCE.md +0 -0
- {TDCRPy-0.0.6.dist-info → TDCRPy-0.0.8.dist-info}/WHEEL +0 -0
- {TDCRPy-0.0.6.dist-info → TDCRPy-0.0.8.dist-info}/top_level.txt +0 -0
TDCRPy/TDCRPy.py
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Mon Jan 23 16:01:49 2023
|
|
4
|
+
|
|
5
|
+
A Monte-Carlo code to calculate detection efficiency in TDCR measurements
|
|
6
|
+
|
|
7
|
+
@author: Romain Coulon, Jialin Hu
|
|
8
|
+
Bureau International des Poids et Mesures
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
## IMPORT PYTHON MODULES
|
|
12
|
+
import TDCR_model_lib as tl
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, RHO, nE, mode, mode2, Display=False):
|
|
16
|
+
"""
|
|
17
|
+
This is a Monte-Carlo TDCR model
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
L : Float (if mode2="sym") or a tuple (if mode2="asym")
|
|
22
|
+
Free parameter.
|
|
23
|
+
TD : Float
|
|
24
|
+
Measured TDCR.
|
|
25
|
+
Rad : string
|
|
26
|
+
List of radionuclides.
|
|
27
|
+
pmf_1 : string
|
|
28
|
+
list of probability of each radionuclide.
|
|
29
|
+
N : integer
|
|
30
|
+
Number of Monte-Carlo trials.
|
|
31
|
+
kB : float
|
|
32
|
+
Birks constant.
|
|
33
|
+
RHO : float
|
|
34
|
+
Density of the scintillator.
|
|
35
|
+
nE : integer
|
|
36
|
+
Number of bins for the quenching function.
|
|
37
|
+
mode : string
|
|
38
|
+
"res" to return the residual, "eff" to return efficiencies.
|
|
39
|
+
mode2 : string
|
|
40
|
+
"sym" for symetrical model, "asym" for symetrical model.
|
|
41
|
+
Display : Boolean, optional
|
|
42
|
+
"True" to display details on the decay sampling. The default is False.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
List
|
|
47
|
+
if mode=="res", the residual (float).
|
|
48
|
+
if mode=="eff", the efficiencies (list)
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Rad=Rad.replace(" ","")
|
|
54
|
+
Rad=Rad.split(",")
|
|
55
|
+
pmf_1=pmf_1.split(",")
|
|
56
|
+
pmf_1 = [float(x) for x in pmf_1]
|
|
57
|
+
|
|
58
|
+
if np.size(pmf_1) > 1:
|
|
59
|
+
if sum(pmf_1) !=1: print("warning p not equal to 1")
|
|
60
|
+
elif pmf_1[0] != 1: print("warning")
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
Read PenNuc File
|
|
64
|
+
"""
|
|
65
|
+
out_PenNuc = []
|
|
66
|
+
particle = [] # Particle(s) from the Mother -- indice 3
|
|
67
|
+
p_branch = [] # Probablity of the different decay of branch -- indice 5
|
|
68
|
+
e_branch = [] # Energy of the different decay of branch -- indice 4
|
|
69
|
+
LevelDaughter = [] # Level of the Daughter nucleus just after the particle emission -- indice 6
|
|
70
|
+
levelNumber = [] # The vector of level of the daughter to get information of all possible isomeric transitions -- indice 11
|
|
71
|
+
prob_trans = [] # Probability for each transition -- indice 10
|
|
72
|
+
prob_branch = [] # Probability for each branch -- indice 7
|
|
73
|
+
levelEnergy = [] # Energy of each level -- indice 13
|
|
74
|
+
transitionType = [] # type of each possible transitions (internal transitions or gamma emission) -- indice 8
|
|
75
|
+
e_trans = [] # Energy of the transition -- indice 9
|
|
76
|
+
next_level = [] # Next level on the daughter nucleus -- indice 12
|
|
77
|
+
Q_value = [] # Energy of the reaction -- indice 2
|
|
78
|
+
DaughterVec = [] # Daughters -- indice 0
|
|
79
|
+
Pdaughter = [] # Probabiblity related to daughters -- indice 1
|
|
80
|
+
Transition_prob_sum = []
|
|
81
|
+
|
|
82
|
+
for rad_i in Rad:
|
|
83
|
+
out_PenNuc = tl.readPenNuc2(rad_i)
|
|
84
|
+
particle.append(out_PenNuc[3]) # Particle(s) from the Mother -- indice 3
|
|
85
|
+
p_branch.append(out_PenNuc[5]) # Probablity of the different decay of branch -- indice 5
|
|
86
|
+
e_branch.append(out_PenNuc[4]) # Energy of the different decay of branch -- indice 4
|
|
87
|
+
LevelDaughter.append(out_PenNuc[6]) # Level of the Daughter nucleus just after the particle emission -- indice 6
|
|
88
|
+
levelNumber.append(out_PenNuc[11]) # The vector of level of the daughter to get information of all possible isomeric transitions -- indice 11
|
|
89
|
+
prob_trans.append(out_PenNuc[10]) # Probability for each transition -- indice 10
|
|
90
|
+
prob_branch.append(out_PenNuc[7]) # Probability for each branch -- indice 7
|
|
91
|
+
levelEnergy.append(out_PenNuc[13]) # Energy of each level -- indice 13
|
|
92
|
+
transitionType.append(out_PenNuc[8]) # type of each possible transitions (internal transitions or gamma emission) -- indice 8
|
|
93
|
+
e_trans.append(out_PenNuc[9]) # Energy of the transition -- indice 9
|
|
94
|
+
next_level.append(out_PenNuc[12]) # Next level on the daughter nucleus -- indice 12
|
|
95
|
+
Q_value.append(out_PenNuc[2]) # Energy of the reaction -- indice 2
|
|
96
|
+
DaughterVec.append(out_PenNuc[0]) # Daughters -- indice 0
|
|
97
|
+
Pdaughter.append(out_PenNuc[1]) # Probabiblity related to daughters -- indice 1
|
|
98
|
+
Transition_prob_sum.append(out_PenNuc[14])
|
|
99
|
+
|
|
100
|
+
efficiency_S = []
|
|
101
|
+
efficiency_D = []
|
|
102
|
+
efficiency_T = []
|
|
103
|
+
efficiency_AB = []
|
|
104
|
+
efficiency_BC = []
|
|
105
|
+
efficiency_AC = []
|
|
106
|
+
for i in range(N): # Main Loop - Monte Carlo trials
|
|
107
|
+
particle_vec=[]
|
|
108
|
+
energy_vec=[]
|
|
109
|
+
'''
|
|
110
|
+
===============================
|
|
111
|
+
0. SAMPLING OF THE RADIONUCLIDE
|
|
112
|
+
===============================
|
|
113
|
+
'''
|
|
114
|
+
index_rad = tl.sampling(pmf_1)
|
|
115
|
+
rad_i = Rad[index_rad]
|
|
116
|
+
if Display: print("\n Sampled radionuclide = ", rad_i, "- L = ", L, ' keV-1 - kB = ', kB, ' cm/keV')
|
|
117
|
+
|
|
118
|
+
'''
|
|
119
|
+
===========================
|
|
120
|
+
I. DESINTEGRATION NUCLEAIRE
|
|
121
|
+
===========================
|
|
122
|
+
'''
|
|
123
|
+
#=========================
|
|
124
|
+
# Sampling of the daughter
|
|
125
|
+
#=========================
|
|
126
|
+
iDaughter=tl.sampling(np.asarray(Pdaughter[index_rad])/sum(np.asarray(Pdaughter[index_rad])))
|
|
127
|
+
Daughter = DaughterVec[index_rad][iDaughter]
|
|
128
|
+
if Display: print("\t Sampled daughter:")
|
|
129
|
+
if Display: print("\t\t Daughter = ", Daughter)
|
|
130
|
+
#=============================
|
|
131
|
+
# Sampling of the decay branch
|
|
132
|
+
#=============================
|
|
133
|
+
branch_i = tl.normalise(prob_branch[index_rad][iDaughter]) # normalise la proba de branch
|
|
134
|
+
i_branch=tl.sampling(branch_i) # indice de la branche globale
|
|
135
|
+
if p_branch[index_rad][iDaughter][i_branch] != []:
|
|
136
|
+
branch_proba = tl.normalise(p_branch[index_rad][iDaughter][i_branch])
|
|
137
|
+
index_subBranch = tl.sampling(branch_proba) # indice de la branch precise
|
|
138
|
+
particle_branch = particle[index_rad][iDaughter][i_branch][index_subBranch] # sampled particle emitted by the mother
|
|
139
|
+
energy_branch = e_branch[index_rad][iDaughter][i_branch][index_subBranch] # energy of the particle emitted by the mother
|
|
140
|
+
# probability_branch = p_branch[index_rad][iDaughter][i_branch][index_subBranch] # probability of the sampled branch
|
|
141
|
+
levelOftheDaughter = LevelDaughter[index_rad][iDaughter][i_branch][index_subBranch] # Level of the daughter just after the particle emission from the mother
|
|
142
|
+
level_before_trans = LevelDaughter[index_rad][iDaughter][i_branch][index_subBranch]
|
|
143
|
+
if Display: print("\t Sampled decay branch:")
|
|
144
|
+
if Display: print("\t\t Particle = ", particle_branch)
|
|
145
|
+
if Display: print("\t\t Energy of the particle = ", energy_branch, " keV")
|
|
146
|
+
if Display: print("\t\t Level of the daughter nucleus = ", levelOftheDaughter)
|
|
147
|
+
#========
|
|
148
|
+
# Scoring
|
|
149
|
+
#========
|
|
150
|
+
e_sum = energy_branch # Update the Energy summary
|
|
151
|
+
particle_vec.append(particle_branch) # Update of the particle vector
|
|
152
|
+
energy_vec.append(energy_branch) # Update of the energy of the particle
|
|
153
|
+
else:
|
|
154
|
+
transition_prob = tl.normalise(Transition_prob_sum[index_rad][iDaughter])
|
|
155
|
+
index_transition_level = tl.sampling(transition_prob)
|
|
156
|
+
levelOftheDaughter = levelNumber[index_rad][iDaughter][index_transition_level][0]
|
|
157
|
+
if Display: print("\t Sampled decay branch:")
|
|
158
|
+
if Display: print("\t\t Particle = isomeric transition, no particle")
|
|
159
|
+
if Display: print("\t\t Level of the nucleus : ",levelOftheDaughter)
|
|
160
|
+
e_sum = 0
|
|
161
|
+
|
|
162
|
+
'''
|
|
163
|
+
==============
|
|
164
|
+
I-1 Transition
|
|
165
|
+
==============
|
|
166
|
+
'''
|
|
167
|
+
|
|
168
|
+
if Display: print("\t Subsequent isomeric transition") # finish with the mother / now with the daughter
|
|
169
|
+
while levelOftheDaughter > 0: # Go on the loop while the daughter nucleus is a its fundamental level (energy 0)
|
|
170
|
+
i_level = levelNumber[index_rad][iDaughter].index([levelOftheDaughter]) # Find the position in the daughter level vector
|
|
171
|
+
if transitionType[index_rad][iDaughter][i_level] != []:
|
|
172
|
+
#====================================================================
|
|
173
|
+
# Sampling of the transition in energy levels of the daughter nucleus
|
|
174
|
+
#====================================================================
|
|
175
|
+
probability_tran = tl.normalise(prob_trans[index_rad][iDaughter][i_level]) # normaliser la proba de transition
|
|
176
|
+
index_t = tl.sampling(probability_tran) # indice de la transition
|
|
177
|
+
if Display: print("\t\t Energy of the level = ", levelEnergy[index_rad][iDaughter][i_level], " keV")
|
|
178
|
+
if Display: print("\t\t Transition type = ", transitionType[index_rad][iDaughter][i_level][index_t])
|
|
179
|
+
if Display: print("\t\t Energy of the transition = ", e_trans[index_rad][iDaughter][i_level][index_t], "keV")
|
|
180
|
+
if Display: print("\t\t next level = ", next_level[index_rad][iDaughter][i_level][index_t])
|
|
181
|
+
#========
|
|
182
|
+
# Scoring
|
|
183
|
+
#========
|
|
184
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "GA": # if it is a gamma that has been emitted
|
|
185
|
+
particle_vec.append("gamma") # Update of the particle vector
|
|
186
|
+
energy_vec.append(e_trans[index_rad][iDaughter][i_level][index_t]) # Update the energy vector
|
|
187
|
+
else: # if not, it is a internal conversion, so an electron
|
|
188
|
+
particle_vec.append("electron") # !!!!!!!!! it is OK for our model? Does the electron leave with the kinetic enegy of the transition
|
|
189
|
+
energy_vec.append(e_trans[index_rad][iDaughter][i_level][index_t]) # Update the energy vector
|
|
190
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EK": # record that an electron is missing on the K shell of the dughter nucleus
|
|
191
|
+
particle_vec.append("Atom_K")
|
|
192
|
+
energy_vec.append(0)
|
|
193
|
+
|
|
194
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EL": # record that an electron is missing on the L1 shell of the dughter nucleus
|
|
195
|
+
particle_vec.append("Atom_L")
|
|
196
|
+
energy_vec.append(0)
|
|
197
|
+
|
|
198
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EL1": # record that an electron is missing on the L1 shell of the dughter nucleus
|
|
199
|
+
particle_vec.append("Atom_L1")
|
|
200
|
+
energy_vec.append(0)
|
|
201
|
+
|
|
202
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EL2": # record that an electron is missing on the L2 shell of the dughter nucleus
|
|
203
|
+
particle_vec.append("Atom_L2")
|
|
204
|
+
energy_vec.append(0)
|
|
205
|
+
|
|
206
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EL3": # record that an electron is missing on the L3 shell of the dughter nucleus
|
|
207
|
+
particle_vec.append("Atom_L3")
|
|
208
|
+
energy_vec.append(0)
|
|
209
|
+
|
|
210
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EM": # record that an electron is missing on the M shell of the dughter nucleus
|
|
211
|
+
particle_vec.append("Atom_M")
|
|
212
|
+
energy_vec.append(0)
|
|
213
|
+
|
|
214
|
+
if transitionType[index_rad][iDaughter][i_level][index_t] == "EN": # record that an electron is missing on the N shell of the dughter nucleus
|
|
215
|
+
particle_vec.append("Atom_N")
|
|
216
|
+
energy_vec.append(0)
|
|
217
|
+
|
|
218
|
+
e_sum += e_trans[index_rad][iDaughter][i_level][index_t] # Energy summary
|
|
219
|
+
levelOftheDaughter = next_level[index_rad][iDaughter][i_level][index_t] # set the next level
|
|
220
|
+
else:
|
|
221
|
+
i_level = levelNumber[index_rad][iDaughter].index([levelOftheDaughter])
|
|
222
|
+
print("warning:pas de données de transition:daughter,niveau,niveau d'énergie",DaughterVec[index_rad][iDaughter],levelOftheDaughter,levelEnergy[index_rad][iDaughter][i_level] )
|
|
223
|
+
levelOftheDaughter = 0 # set the next level
|
|
224
|
+
|
|
225
|
+
if Display: print("\t Summary of the nuclear decay")
|
|
226
|
+
if Display: print("\t\t particles : ", particle_vec)
|
|
227
|
+
if Display: print("\t\t energy : ", energy_vec, "keV")
|
|
228
|
+
|
|
229
|
+
'''
|
|
230
|
+
==========================
|
|
231
|
+
II. LA RELAXATION ATOMIQUE
|
|
232
|
+
==========================
|
|
233
|
+
'''
|
|
234
|
+
daughter_relax = DaughterVec[index_rad][iDaughter]
|
|
235
|
+
for i_part in range(len(particle_vec)):
|
|
236
|
+
relaxation = False
|
|
237
|
+
if "Atom_K" in particle_vec[i_part] or "Atom_L" in particle_vec[i_part] or "Atom_M" in particle_vec[i_part]:
|
|
238
|
+
relaxation = True
|
|
239
|
+
while relaxation:
|
|
240
|
+
tf,ef = tl.relaxation_atom(daughter_relax,Rad[index_rad],particle_vec[i_part])
|
|
241
|
+
if tf == "XKA":
|
|
242
|
+
particle_vec[i_part] = "Atom_L"
|
|
243
|
+
particle_vec.append(tf)
|
|
244
|
+
energy_vec.append(ef)
|
|
245
|
+
relaxation = True
|
|
246
|
+
elif tf == "XKB":
|
|
247
|
+
particle_vec[i_part] = "Atom_M"
|
|
248
|
+
particle_vec.append(tf)
|
|
249
|
+
energy_vec.append(ef)
|
|
250
|
+
relaxation = False
|
|
251
|
+
elif tf == "XL":
|
|
252
|
+
particle_vec[i_part] = "Atom_M"
|
|
253
|
+
particle_vec.append(tf)
|
|
254
|
+
energy_vec.append(ef)
|
|
255
|
+
relaxation = False
|
|
256
|
+
elif tf == "Auger K":
|
|
257
|
+
particle_vec[i_part] = "Atom_L"
|
|
258
|
+
particle_vec.append(tf)
|
|
259
|
+
energy_vec.append(ef)
|
|
260
|
+
relaxation = True
|
|
261
|
+
elif tf == "Auger L":
|
|
262
|
+
particle_vec[i_part] = "Atom_M"
|
|
263
|
+
particle_vec.append(tf)
|
|
264
|
+
energy_vec.append(ef)
|
|
265
|
+
relaxation = False
|
|
266
|
+
else:
|
|
267
|
+
if Display: print("untermined x or Auger")
|
|
268
|
+
relaxation = False
|
|
269
|
+
e_sum += ef
|
|
270
|
+
if Display: print("\t Summary of the atomic relaxation")
|
|
271
|
+
if Display: print("\t\t particles : ", particle_vec)
|
|
272
|
+
if Display: print("\t\t energy : ", energy_vec, "keV")
|
|
273
|
+
|
|
274
|
+
'''
|
|
275
|
+
==========================================================
|
|
276
|
+
III. INTERACTION RAYONNEMENT/MATIERE + SPECTRES D'EMISSION
|
|
277
|
+
==========================================================
|
|
278
|
+
'''
|
|
279
|
+
for i, p in enumerate(particle_vec):
|
|
280
|
+
if p == "beta":
|
|
281
|
+
e_b,p_b = tl.readBetaShape(rad_i,"beta-",level_before_trans) # read the data of BetaShape
|
|
282
|
+
index_beta_energy = tl.sampling(p_b) # sampling energy of beta
|
|
283
|
+
particle_vec[i] = "electron"
|
|
284
|
+
energy_vec[i] = e_b[index_beta_energy]
|
|
285
|
+
energy_vec[i] = tl.energie_dep_beta(energy_vec[i])
|
|
286
|
+
|
|
287
|
+
if p == "beta+":
|
|
288
|
+
e_b,p_b = tl.readBetaShape(rad_i,"beta+",level_before_trans)
|
|
289
|
+
index_beta_energy = tl.sampling(p_b)
|
|
290
|
+
particle_vec[i] = "positron"
|
|
291
|
+
energy_vec[i] = e_b[index_beta_energy]
|
|
292
|
+
energy_vec[i] = tl.energie_dep_beta(energy_vec[i])
|
|
293
|
+
particle_vec.append("gamma")
|
|
294
|
+
particle_vec.append("gamma")
|
|
295
|
+
energy_vec.append(511)
|
|
296
|
+
energy_vec.append(511)
|
|
297
|
+
|
|
298
|
+
if p == "gamma" or p == "XKA" or p == "XKB" or p == "XL":
|
|
299
|
+
energy_vec[i] = tl.energie_dep_gamma(energy_vec[i],v=10) # sampling energy free from photon
|
|
300
|
+
particle_vec[i] = "electron"
|
|
301
|
+
if p == "Auger K" or p == "Auger L":
|
|
302
|
+
particle_vec[i] = "electron"
|
|
303
|
+
energy_vec[i] = tl.energie_dep_beta(energy_vec[i])
|
|
304
|
+
if Display: print("\t Summary of the final charged particles")
|
|
305
|
+
if Display: print("\t\t particles : ", particle_vec)
|
|
306
|
+
if Display: print("\t\t energy : ", energy_vec, "keV")
|
|
307
|
+
|
|
308
|
+
'''
|
|
309
|
+
====================
|
|
310
|
+
IV. LA SCINTILLATION
|
|
311
|
+
Calculation of the scintillation quenching with the Birks Model
|
|
312
|
+
====================
|
|
313
|
+
'''
|
|
314
|
+
e_quenching=[]
|
|
315
|
+
for i, p in enumerate(particle_vec):
|
|
316
|
+
e_discrete = np.linspace(0,energy_vec[i],nE) # vector for the quenched energy calculation keV
|
|
317
|
+
delta_e = e_discrete[2]-e_discrete[1] #keV
|
|
318
|
+
if p == "alpha":
|
|
319
|
+
energy_vec[i] = np.cumsum(delta_e/(1+kB*tl.stoppingpowerA(e_discrete)))[-1]
|
|
320
|
+
e_quenching.append(energy_vec[i])
|
|
321
|
+
elif p == "electron" or p == "positron":
|
|
322
|
+
energy_vec[i] = tl.E_quench_e(energy_vec[i]*1e3,kB*1e3,nE)*1e-3
|
|
323
|
+
e_quenching.append(energy_vec[i])
|
|
324
|
+
else:
|
|
325
|
+
e_quenching.append(0)
|
|
326
|
+
if Display: print("\t Summary of the estimation of quenched energies")
|
|
327
|
+
|
|
328
|
+
if Display: print("\t\t energy_vec : ", energy_vec, "keV")
|
|
329
|
+
if Display: print("\t\t quenched energy : ", e_quenching, "keV")
|
|
330
|
+
|
|
331
|
+
'''
|
|
332
|
+
====================
|
|
333
|
+
V. LE MESURE TDCR
|
|
334
|
+
====================
|
|
335
|
+
'''
|
|
336
|
+
|
|
337
|
+
if mode2=="sym":
|
|
338
|
+
p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
|
|
339
|
+
p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
|
|
340
|
+
efficiency_S.append(p_single)
|
|
341
|
+
efficiency_T.append(p_single**3)
|
|
342
|
+
efficiency_D.append(3*(p_single)**2-2*efficiency_T[-1])
|
|
343
|
+
if Display: print("\t Summary of TDCR measurement")
|
|
344
|
+
if Display: print("\t\t Efficiency of single events: ", efficiency_S[-1])
|
|
345
|
+
if Display: print("\t\t Efficiency of double events: ", efficiency_D[-1])
|
|
346
|
+
if Display: print("\t\t Efficiency of triple events: ", efficiency_D[-1])
|
|
347
|
+
elif mode2=="asym":
|
|
348
|
+
pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
|
|
349
|
+
pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
|
|
350
|
+
pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
|
|
351
|
+
pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
|
|
352
|
+
pC_nosingle = np.exp(-L[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
|
|
353
|
+
pC_single = 1-pC_nosingle # probability to have at least 1 electrons in a PMT
|
|
354
|
+
|
|
355
|
+
efficiency_AB.append(pA_single*pB_single)
|
|
356
|
+
efficiency_BC.append(pB_single*pC_single)
|
|
357
|
+
efficiency_AC.append(pA_single*pC_single)
|
|
358
|
+
efficiency_T.append(pA_single*pB_single*pC_single)
|
|
359
|
+
|
|
360
|
+
efficiency_D.append(efficiency_AB[-1]+efficiency_BC[-1]+efficiency_AC[-1]-2*efficiency_T[-1])
|
|
361
|
+
efficiency_S.append(pA_single+pB_single+pC_single-efficiency_D[-1]-efficiency_T[-1])
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
'''
|
|
366
|
+
====================
|
|
367
|
+
VI. CALCULATION OF THE FINAL ESTIMATORS
|
|
368
|
+
====================
|
|
369
|
+
'''
|
|
370
|
+
if mode2=="sym":
|
|
371
|
+
mean_efficiency_T = np.mean(efficiency_T) # average
|
|
372
|
+
std_efficiency_T = np.std(efficiency_T)/np.sqrt(N) # standard deviation
|
|
373
|
+
mean_efficiency_D = np.mean(efficiency_D)
|
|
374
|
+
std_efficiency_D = np.std(efficiency_D)/np.sqrt(N)
|
|
375
|
+
mean_efficiency_S = np.mean(efficiency_S)
|
|
376
|
+
std_efficiency_S = np.std(efficiency_S)/np.sqrt(N)
|
|
377
|
+
TDCR_calcul = mean_efficiency_T/mean_efficiency_D
|
|
378
|
+
elif mode2=="asym":
|
|
379
|
+
mean_efficiency_T = np.mean(efficiency_T) # average
|
|
380
|
+
std_efficiency_T = np.std(efficiency_T)/np.sqrt(N) # standard deviation
|
|
381
|
+
mean_efficiency_D = np.mean(efficiency_D)
|
|
382
|
+
std_efficiency_D = np.std(efficiency_D)/np.sqrt(N)
|
|
383
|
+
mean_efficiency_S = np.mean(efficiency_S)
|
|
384
|
+
std_efficiency_S = np.std(efficiency_S)/np.sqrt(N)
|
|
385
|
+
mean_efficiency_AB = np.mean(efficiency_AB)
|
|
386
|
+
std_efficiency_AB = np.std(efficiency_AB)/np.sqrt(N)
|
|
387
|
+
mean_efficiency_BC = np.mean(efficiency_BC)
|
|
388
|
+
std_efficiency_BC = np.std(efficiency_BC)/np.sqrt(N)
|
|
389
|
+
mean_efficiency_AC = np.mean(efficiency_AC)
|
|
390
|
+
std_efficiency_AC = np.std(efficiency_AC)/np.sqrt(N)
|
|
391
|
+
TDCR_calcul = mean_efficiency_T/mean_efficiency_D
|
|
392
|
+
TABmodel = mean_efficiency_T/mean_efficiency_AB
|
|
393
|
+
TBCmodel = mean_efficiency_T/mean_efficiency_BC
|
|
394
|
+
TACmodel = mean_efficiency_T/mean_efficiency_AC
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
# x = np.arange(np.mean(efficiency_T),1.001,0.001)
|
|
398
|
+
# plt.figure("efficiency distribution")
|
|
399
|
+
# plt.clf()
|
|
400
|
+
# plt.hist(np.asarray(efficiency_D),bins=x,label="Efficiency of double coincidences")[0]
|
|
401
|
+
# plt.hist(np.asarray(efficiency_T),bins=x,label="Efficiency of triple coincidences")[0]
|
|
402
|
+
# plt.xlabel("Efficiency", fontsize = 14)
|
|
403
|
+
# plt.ylabel(r"Number of counts", fontsize = 14)
|
|
404
|
+
# plt.legend(fontsize = 12)
|
|
405
|
+
# plt.savefig('Effdistribution.png')
|
|
406
|
+
|
|
407
|
+
# x = np.arange(np.mean(tdcr),1.001,0.001)
|
|
408
|
+
# plt.figure("TDCR distribution")
|
|
409
|
+
# plt.clf()
|
|
410
|
+
# plt.hist(np.asarray(tdcr),bins=x,label="Calculated TDCR")[0]
|
|
411
|
+
# plt.plot(x,st.norm.pdf(x, TDCR_measure, u_TDCR_measure),label="measured TDCR")[0]
|
|
412
|
+
# plt.xlabel("Efficiency", fontsize = 14)
|
|
413
|
+
# plt.ylabel(r"Number of counts", fontsize = 14)
|
|
414
|
+
# plt.legend(fontsize = 12)
|
|
415
|
+
# plt.savefig('TDCRdistribution.png')
|
|
416
|
+
|
|
417
|
+
if mode2=="sym":
|
|
418
|
+
res=(TDCR_calcul-TD)**2
|
|
419
|
+
elif mode2=="asym":
|
|
420
|
+
res=(TAB-TABmodel)**2+(TBC-TBCmodel)**2+(TAC-TACmodel)**2
|
|
421
|
+
|
|
422
|
+
if mode == "res":
|
|
423
|
+
return res
|
|
424
|
+
if mode == "eff":
|
|
425
|
+
return mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T
|