TDCRPy 2.9.0__py3-none-any.whl → 2.12.13__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.
Potentially problematic release.
This version of TDCRPy might be problematic. Click here for more details.
- tdcrpy/TDCRPy.py +1 -0
- tdcrpy/TDCR_model_lib.py +208 -143
- tdcrpy/config.toml +6 -4
- tdcrpy/test_randomGen.py +66 -0
- {tdcrpy-2.9.0.dist-info → tdcrpy-2.12.13.dist-info}/METADATA +1 -1
- {tdcrpy-2.9.0.dist-info → tdcrpy-2.12.13.dist-info}/RECORD +9 -8
- {tdcrpy-2.9.0.dist-info → tdcrpy-2.12.13.dist-info}/WHEEL +1 -1
- {tdcrpy-2.9.0.dist-info → tdcrpy-2.12.13.dist-info}/licenses/LICENCE.md +0 -0
- {tdcrpy-2.9.0.dist-info → tdcrpy-2.12.13.dist-info}/top_level.txt +0 -0
tdcrpy/TDCRPy.py
CHANGED
|
@@ -289,6 +289,7 @@ def TDCRPy(L, Rad, pmf_1, N, kB, V, mode="eff", Display=False, barp=False, Smode
|
|
|
289
289
|
efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2 = tl.detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime)
|
|
290
290
|
else:
|
|
291
291
|
efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2 = tl.detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime)
|
|
292
|
+
|
|
292
293
|
efficiency_S.append(efficiency0_S)
|
|
293
294
|
efficiency_T.append(efficiency0_T)
|
|
294
295
|
efficiency_D.append(efficiency0_D)
|
tdcrpy/TDCR_model_lib.py
CHANGED
|
@@ -24,6 +24,7 @@ import scipy.interpolate as interp
|
|
|
24
24
|
import matplotlib.pyplot as plt
|
|
25
25
|
from tqdm import tqdm
|
|
26
26
|
import tempfile
|
|
27
|
+
import math
|
|
27
28
|
|
|
28
29
|
"""
|
|
29
30
|
======= Import ressource data =======
|
|
@@ -32,6 +33,16 @@ import tempfile
|
|
|
32
33
|
# import advanced configuration data
|
|
33
34
|
config = configparser.ConfigParser()
|
|
34
35
|
|
|
36
|
+
def readEffQ0():
|
|
37
|
+
global config, file_conf
|
|
38
|
+
config = configparser.ConfigParser()
|
|
39
|
+
with importlib.resources.as_file(files('tdcrpy').joinpath('config.toml')) as data_path:
|
|
40
|
+
file_conf = data_path
|
|
41
|
+
config.read(file_conf)
|
|
42
|
+
|
|
43
|
+
effQuantic0 = config["Inputs"].get("effQuantum")
|
|
44
|
+
return effQuantic0
|
|
45
|
+
|
|
35
46
|
def readParameters(disp=False):
|
|
36
47
|
global config, file_conf
|
|
37
48
|
config = configparser.ConfigParser()
|
|
@@ -60,9 +71,15 @@ def readParameters(disp=False):
|
|
|
60
71
|
diam_micelle = config["Inputs"].getfloat("diam_micelle")
|
|
61
72
|
fAq = config["Inputs"].getfloat("fAq")
|
|
62
73
|
micCorr = config["Inputs"].getboolean("micCorr")
|
|
63
|
-
alphaDir = config["Inputs"].getfloat("alphaDir")
|
|
64
|
-
|
|
74
|
+
# alphaDir = config["Inputs"].getfloat("alphaDir")
|
|
75
|
+
effQuantic0 = config["Inputs"].get("effQuantum")
|
|
76
|
+
effQuantic = effQuantic0.split(',')
|
|
77
|
+
for i, iS in enumerate(effQuantic):
|
|
78
|
+
iS=iS.replace(" ","")
|
|
79
|
+
if iS != 'None': effQuantic[i]=float(iS)
|
|
65
80
|
optionModel = config["Inputs"].get("optionModel")
|
|
81
|
+
diffP = config["Inputs"].getfloat("diffP")
|
|
82
|
+
PMTspace = config["Inputs"].getfloat("PMTspace")
|
|
66
83
|
|
|
67
84
|
if disp:
|
|
68
85
|
print(f"number of integration bins for electrons = {nE_electron}")
|
|
@@ -79,16 +96,18 @@ def readParameters(disp=False):
|
|
|
79
96
|
print(f"activation of the micelle correction = {micCorr}")
|
|
80
97
|
print(f"diameter of micelle = {diam_micelle} nm")
|
|
81
98
|
print(f"acqueous fraction = {fAq}")
|
|
82
|
-
print(f"alpha parameter of the hidden Dirichlet process = {alphaDir}")
|
|
99
|
+
# print(f"alpha parameter of the hidden Dirichlet process = {alphaDir}")
|
|
83
100
|
print(f"quantum efficiency of the photocathodes = {effQuantic}")
|
|
84
101
|
print(f"Monte Carlo model of the optics = {optionModel}")
|
|
102
|
+
print(f"fraction of diffused scintillation photons = {diffP*100:.1f} %")
|
|
103
|
+
print(f"relative distance from vials border to PMT entrance = {PMTspace*100:.1f} %")
|
|
85
104
|
print(f"coincidence resolving time = {tau} ns")
|
|
86
105
|
print(f"extended dead time = {extDT} µs")
|
|
87
106
|
print(f"measurement time = {measTime} min")
|
|
88
107
|
|
|
89
|
-
return nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr,
|
|
108
|
+
return nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr, effQuantic, optionModel, diffP, PMTspace, pH,pC,pN,pO,pP,pCl
|
|
90
109
|
|
|
91
|
-
nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr,
|
|
110
|
+
nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr, effQuantic, optionModel, diffP, PMTspace, pH,pC,pN,pO,pP,pCl = readParameters()
|
|
92
111
|
|
|
93
112
|
p_atom = np.array([pH,pC,pN,pO,pP,pCl]) # atom abondance in the scintillator
|
|
94
113
|
p_atom /= sum(p_atom)
|
|
@@ -199,24 +218,37 @@ def modifyMicCorr(x):
|
|
|
199
218
|
data1 = data0.replace(f"micCorr = {x0}",f"micCorr= {x}")
|
|
200
219
|
writeConfifAsstr(data1)
|
|
201
220
|
|
|
202
|
-
def modifyAlphaDir(x):
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
221
|
+
# def modifyAlphaDir(x):
|
|
222
|
+
# data0 = readConfigAsstr()
|
|
223
|
+
# x0 = readParameters()[14]
|
|
224
|
+
# data1 = data0.replace(f"alphaDir = {x0}",f"alphaDir = {x}")
|
|
225
|
+
# writeConfifAsstr(data1)
|
|
207
226
|
|
|
208
227
|
def modifyEffQ(x):
|
|
209
228
|
data0 = readConfigAsstr()
|
|
210
|
-
x0 = readParameters()[
|
|
229
|
+
# x0 = readParameters()[14]
|
|
230
|
+
x0 = readEffQ0()
|
|
211
231
|
data1 = data0.replace(f"effQuantum = {x0}",f"effQuantum = {x}")
|
|
212
232
|
writeConfifAsstr(data1)
|
|
213
233
|
|
|
214
234
|
def modifyOptModel(x):
|
|
215
235
|
data0 = readConfigAsstr()
|
|
216
|
-
x0 = readParameters()[
|
|
236
|
+
x0 = readParameters()[15]
|
|
217
237
|
data1 = data0.replace(f"optionModel = {x0}",f"optionModel = {x}")
|
|
218
238
|
writeConfifAsstr(data1)
|
|
219
239
|
|
|
240
|
+
def modifyDiffP(x):
|
|
241
|
+
data0 = readConfigAsstr()
|
|
242
|
+
x0 = readParameters()[16]
|
|
243
|
+
data1 = data0.replace(f"diffP = {x0:.1f}",f"diffP = {x:.1f}")
|
|
244
|
+
writeConfifAsstr(data1)
|
|
245
|
+
|
|
246
|
+
def modifyPMTspace(x):
|
|
247
|
+
data0 = readConfigAsstr()
|
|
248
|
+
x0 = readParameters()[17]
|
|
249
|
+
data1 = data0.replace(f"PMTspace = {x0:.1f}",f"PMTspace = {x:.1f}")
|
|
250
|
+
writeConfifAsstr(data1)
|
|
251
|
+
|
|
220
252
|
def read_temp_files(copy=False, path="C:"):
|
|
221
253
|
|
|
222
254
|
temp_dir = tempfile.gettempdir()
|
|
@@ -2921,7 +2953,7 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
|
|
|
2921
2953
|
|
|
2922
2954
|
|
|
2923
2955
|
if symm:
|
|
2924
|
-
|
|
2956
|
+
|
|
2925
2957
|
if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
|
|
2926
2958
|
# TDCR
|
|
2927
2959
|
p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
|
|
@@ -3028,7 +3060,105 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
|
|
|
3028
3060
|
return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
|
|
3029
3061
|
|
|
3030
3062
|
|
|
3031
|
-
def
|
|
3063
|
+
def stochasticDepTD(diffP, PMTspace):
|
|
3064
|
+
"""
|
|
3065
|
+
Generate the probability
|
|
3066
|
+
|
|
3067
|
+
Parameters
|
|
3068
|
+
----------
|
|
3069
|
+
diffP : TYPE
|
|
3070
|
+
DESCRIPTION.
|
|
3071
|
+
PMTspace : TYPE
|
|
3072
|
+
DESCRIPTION.
|
|
3073
|
+
|
|
3074
|
+
Returns
|
|
3075
|
+
-------
|
|
3076
|
+
TYPE
|
|
3077
|
+
DESCRIPTION.
|
|
3078
|
+
|
|
3079
|
+
"""
|
|
3080
|
+
detA = np.array([[2*(1+PMTspace), 0], [-(1+PMTspace), np.sqrt(3)*(1+PMTspace)]])
|
|
3081
|
+
detB = np.array([[-(1+PMTspace), np.sqrt(3)*(1+PMTspace)], [-(1+PMTspace), -np.sqrt(3)*(1+PMTspace)]])
|
|
3082
|
+
detC = np.array([[-(1+PMTspace), -np.sqrt(3)*(1+PMTspace)], [2*(1+PMTspace), 0]])
|
|
3083
|
+
|
|
3084
|
+
def simulate_photon_groups():
|
|
3085
|
+
rho = 1 * np.sqrt(np.random.uniform(0, 1, 1)) # Radial distance
|
|
3086
|
+
theta = np.random.uniform(0, 2 * np.pi, 1) # Angular position
|
|
3087
|
+
x = rho * np.cos(theta)
|
|
3088
|
+
y = rho * np.sin(theta)
|
|
3089
|
+
return x, y
|
|
3090
|
+
|
|
3091
|
+
def calculate_angle(O, det):
|
|
3092
|
+
A=det[0]
|
|
3093
|
+
B=det[1]
|
|
3094
|
+
OA = (A[0] - O[0], A[1] - O[1]) # Vecteurs OA et OB
|
|
3095
|
+
OB = (B[0] - O[0], B[1] - O[1])
|
|
3096
|
+
dot_product = OA[0] * OB[0] + OA[1] * OB[1] # Produit scalaire OA . OB
|
|
3097
|
+
norm_OA = math.sqrt((OA[0]**2 + OA[1]**2)[0]) # Normes des vecteurs OA et OB
|
|
3098
|
+
norm_OB = math.sqrt((OB[0]**2 + OB[1]**2)[0])
|
|
3099
|
+
cos_angle = dot_product / (norm_OA * norm_OB) # Cosinus de l'angle
|
|
3100
|
+
angle_rad = math.acos(cos_angle[0]) # Angle en radians
|
|
3101
|
+
angle_deg = math.degrees(angle_rad) # Convertir en degrés
|
|
3102
|
+
return angle_deg
|
|
3103
|
+
|
|
3104
|
+
x, y = simulate_photon_groups()
|
|
3105
|
+
|
|
3106
|
+
pa=(1-diffP)*calculate_angle([x, y], detA)/360+diffP/3
|
|
3107
|
+
pb=(1-diffP)*calculate_angle([x, y], detB)/360+diffP/3
|
|
3108
|
+
pc=(1-diffP)*calculate_angle([x, y], detC)/360+diffP/3
|
|
3109
|
+
|
|
3110
|
+
return pa, pb, pc
|
|
3111
|
+
|
|
3112
|
+
# Di = []; Ti = []
|
|
3113
|
+
# n=1000000
|
|
3114
|
+
# for i in range(n):
|
|
3115
|
+
# A = stochasticDepTD(1, 0)
|
|
3116
|
+
# B = np.random.poisson(2)
|
|
3117
|
+
# n_phPMT = np.random.multinomial(B, A) # sample the number of photons in each PMTs (TDCR configuration)
|
|
3118
|
+
# nA=np.random.binomial(n_phPMT[0],0.25) # sample the conversion to photoelectrons PMT A
|
|
3119
|
+
# nB=np.random.binomial(n_phPMT[1],0.25) # sample the conversion to photoelectrons PMT B
|
|
3120
|
+
# nC=np.random.binomial(n_phPMT[2],0.25) # sample the conversion to photoelectrons PMT C
|
|
3121
|
+
# Di.append(sum([nA>0, nB>0, nC>0])>1)
|
|
3122
|
+
# Ti.append(sum([nA>0, nB>0, nC>0])>2)
|
|
3123
|
+
# D = sum(Di)/n
|
|
3124
|
+
# uD = D/np.sqrt(sum(Di))#np.sqrt(n)
|
|
3125
|
+
# T = sum(Ti)/n
|
|
3126
|
+
# uT = T/np.sqrt(sum(Ti))#/np.sqrt(n)
|
|
3127
|
+
# print(D, uD)
|
|
3128
|
+
# print(T, uT)
|
|
3129
|
+
|
|
3130
|
+
def stochasticDepCN(diffP, PMTspace):
|
|
3131
|
+
def simulate_photon_groups():
|
|
3132
|
+
rho = 1 * np.sqrt(np.random.uniform(0, 1, 1)) # Radial distance
|
|
3133
|
+
theta = np.random.uniform(0, 2 * np.pi, 1) # Angular position
|
|
3134
|
+
x = rho * np.cos(theta)
|
|
3135
|
+
y = rho * np.sin(theta)
|
|
3136
|
+
return x, y
|
|
3137
|
+
|
|
3138
|
+
def calculate_angle(O):
|
|
3139
|
+
OA = (-1-PMTspace - O[0], 0 - O[1]) # Vecteurs OA et OB
|
|
3140
|
+
OB = (1+PMTspace - O[0], 0 - O[1])
|
|
3141
|
+
dot_product = OA[0] * OB[0] + OA[1] * OB[1] # Produit scalaire OA . OB
|
|
3142
|
+
norm_OA = math.sqrt((OA[0]**2 + OA[1]**2)[0]) # Normes des vecteurs OA et OB
|
|
3143
|
+
norm_OB = math.sqrt((OB[0]**2 + OB[1]**2)[0])
|
|
3144
|
+
cos_angle = dot_product / (norm_OA * norm_OB) # Cosinus de l'angle
|
|
3145
|
+
angle_rad = math.acos(cos_angle[0]) # Angle en radians
|
|
3146
|
+
angle_deg = math.degrees(angle_rad) # Convertir en degrés
|
|
3147
|
+
return angle_deg
|
|
3148
|
+
|
|
3149
|
+
x, y = simulate_photon_groups()
|
|
3150
|
+
|
|
3151
|
+
if np.random.randint(0, high=2)==0:
|
|
3152
|
+
pa=(1-diffP)*calculate_angle([x, y])/360+diffP/2
|
|
3153
|
+
pb=1-pa
|
|
3154
|
+
else:
|
|
3155
|
+
pb=(1-diffP)*calculate_angle([x, y])/360+diffP/2
|
|
3156
|
+
pa=1-pb
|
|
3157
|
+
|
|
3158
|
+
return pa, pb
|
|
3159
|
+
|
|
3160
|
+
|
|
3161
|
+
def detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime, effQuantic = effQuantic, optionModel=optionModel, diffP = diffP, PMTspace = PMTspace, dispParam=False):
|
|
3032
3162
|
"""
|
|
3033
3163
|
Calculate detection probabilities for LS counting systems - see Broda, R., Cassette, P., Kossert, K., 2007. Radionuclide metrology using liquid scintillation counting. Metrologia 44. https://doi.org/10.1088/0026-1394/44/4/S06
|
|
3034
3164
|
|
|
@@ -3067,149 +3197,81 @@ def detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, me
|
|
|
3067
3197
|
detection probability of coincidences in a C/N system.
|
|
3068
3198
|
|
|
3069
3199
|
"""
|
|
3070
|
-
if isinstance(L, (tuple, list)):
|
|
3071
|
-
symm = False
|
|
3072
|
-
else:
|
|
3073
|
-
symm = True
|
|
3074
|
-
|
|
3075
3200
|
mu = effQuantic
|
|
3201
|
+
|
|
3202
|
+
if type(L) == float:
|
|
3203
|
+
L = [L, L, L]
|
|
3076
3204
|
|
|
3077
|
-
if
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3205
|
+
if dispParam: print(f"EffQ = {mu} - model = {optionModel} - diffP = {diffP} - PMTspace = {PMTspace}")
|
|
3206
|
+
|
|
3207
|
+
def stochasOpticModel(e_q, L, mu):
|
|
3208
|
+
n_e=np.zeros(3); n_eCN=np.zeros(2) # initilize the number of photoelectrons
|
|
3209
|
+
|
|
3210
|
+
n_ph = np.random.poisson(sum(np.asarray(e_q))*np.mean(L)/np.mean(mu)) # sample the number of scintillation photons
|
|
3211
|
+
|
|
3212
|
+
pTD = stochasticDepTD(diffP, PMTspace) # probabilities for photons to move towards the different PMTs (TDCR configuration)
|
|
3213
|
+
n_phPMT = np.random.multinomial(n_ph, pTD) # sample the number of photons in each PMTs (TDCR configuration)
|
|
3214
|
+
n_e[0]=np.random.binomial(n_phPMT[0],mu[0]) # sample the conversion to photoelectrons PMT A
|
|
3215
|
+
n_e[1]=np.random.binomial(n_phPMT[1],mu[1]) # sample the conversion to photoelectrons PMT B
|
|
3216
|
+
n_e[2]=np.random.binomial(n_phPMT[2],mu[2]) # sample the conversion to photoelectrons PMT C
|
|
3217
|
+
|
|
3218
|
+
pCN = stochasticDepCN(diffP, PMTspace) # probabilities for photons to move towards the different PMTs (C/N configuration)
|
|
3219
|
+
n_phPMTCN = np.random.multinomial(n_ph, pCN) # sample the number of photons in each PMTs (C/N configuration)
|
|
3220
|
+
n_eCN[0]=np.random.binomial(n_phPMTCN[0],mu[0]) # sample the conversion to photoelectrons PMT A
|
|
3221
|
+
n_eCN[1]=np.random.binomial(n_phPMTCN[1],mu[1]) # sample the conversion to photoelectrons PMT B
|
|
3222
|
+
|
|
3223
|
+
return n_e, n_eCN
|
|
3224
|
+
|
|
3225
|
+
def Pmodel(e_q, pTD_ideal, pCN_ideal, L, mu):
|
|
3226
|
+
n_e=np.zeros(3); n_eCN=np.zeros(2) # initilize the number of photoelectrons
|
|
3227
|
+
|
|
3228
|
+
n_e[0] = np.random.poisson(sum(np.asarray(e_q))*L[0]*mu[0]*pTD_ideal[0]) # sample the conversion to photoelectrons PMT A
|
|
3229
|
+
n_e[1] = np.random.poisson(sum(np.asarray(e_q))*L[1]*mu[1]*pTD_ideal[1]) # sample the conversion to photoelectrons PMT B
|
|
3230
|
+
n_e[2] = np.random.poisson(sum(np.asarray(e_q))*L[2]*mu[2]*pTD_ideal[2]) # sample the conversion to photoelectrons PMT C
|
|
3231
|
+
n_eCN[0] = np.random.poisson(sum(np.asarray(e_q))*L[0]*mu[0]*pCN_ideal[0]) # sample the conversion to photoelectrons PMT A
|
|
3232
|
+
n_eCN[1] = np.random.poisson(sum(np.asarray(e_q))*L[1]*mu[1]*pCN_ideal[1]) # sample the conversion to photoelectrons PMT B
|
|
3233
|
+
|
|
3234
|
+
return n_e, n_eCN
|
|
3235
|
+
|
|
3083
3236
|
|
|
3084
3237
|
efficiency0_S = 0; efficiency0_T = 0; efficiency0_D = 0
|
|
3085
3238
|
efficiency0_AB = 0; efficiency0_BC = 0; efficiency0_AC = 0
|
|
3086
3239
|
efficiency0_D2 = 0;
|
|
3087
|
-
n_e = np.zeros(3); n_eCN = np.zeros(2); n_e2 = np.zeros(3); n_e2CN = np.zeros(2)
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
n_e[0]=np.random.binomial(n_phPMT[0],mu)
|
|
3095
|
-
n_e[1]=np.random.binomial(n_phPMT[1],mu)
|
|
3096
|
-
n_e[2]=np.random.binomial(n_phPMT[2],mu)
|
|
3097
|
-
# C/N
|
|
3098
|
-
n_phPMTCN = np.random.multinomial(n_ph, dirichCN)
|
|
3099
|
-
n_eCN[0]=np.random.binomial(n_phPMTCN[0],mu)
|
|
3100
|
-
n_eCN[1]=np.random.binomial(n_phPMTCN[1],mu)
|
|
3101
|
-
elif optionModel == "poisson":
|
|
3102
|
-
n_e[0] = np.random.poisson(sum(np.asarray(e_quenching))*L*mu*dirichTD[0])
|
|
3103
|
-
n_e[1] = np.random.poisson(sum(np.asarray(e_quenching))*L*mu*dirichTD[1])
|
|
3104
|
-
n_e[2] = np.random.poisson(sum(np.asarray(e_quenching))*L*mu*dirichTD[2])
|
|
3105
|
-
n_eCN[0] = np.random.poisson(sum(np.asarray(e_quenching))*L*mu*dirichCN[0])
|
|
3106
|
-
n_eCN[1] = np.random.poisson(sum(np.asarray(e_quenching))*L*mu*dirichCN[1])
|
|
3107
|
-
else:
|
|
3108
|
-
print("unknown model")
|
|
3109
|
-
|
|
3110
|
-
if sum(n_e>1)>0: efficiency0_S =1
|
|
3111
|
-
if sum(n_e>1)>1: efficiency0_D =1
|
|
3112
|
-
if sum(n_e>1)>2: efficiency0_T =1
|
|
3113
|
-
if n_e[0]>1 and n_e[1]>1: efficiency0_AB =1
|
|
3114
|
-
if n_e[1]>1 and n_e[2]>1: efficiency0_BC =1
|
|
3115
|
-
if n_e[0]>1 and n_e[2]>1: efficiency0_AC =1
|
|
3116
|
-
if sum(n_eCN>1)>1: efficiency0_D2 =1
|
|
3117
|
-
|
|
3118
|
-
if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
|
|
3119
|
-
if optionModel == "poisson-multinomial-binomial":
|
|
3120
|
-
n_ph2 = np.random.poisson(sum(np.asarray(e_quenching2))*L/mu)
|
|
3121
|
-
# TDCR
|
|
3122
|
-
n_phPMT2 = np.random.multinomial(n_ph2, dirichTD)
|
|
3123
|
-
n_e2[0]=np.random.binomial(n_phPMT2[0],mu)
|
|
3124
|
-
n_e2[1]=np.random.binomial(n_phPMT2[1],mu)
|
|
3125
|
-
n_e2[2]=np.random.binomial(n_phPMT2[2],mu)
|
|
3126
|
-
# C/N
|
|
3127
|
-
n_phPMT2CN = np.random.multinomial(n_ph2, dirichCN)
|
|
3128
|
-
n_e2CN[0]=np.random.binomial(n_phPMT2CN[0],mu)
|
|
3129
|
-
n_e2CN[1]=np.random.binomial(n_phPMT2CN[1],mu)
|
|
3130
|
-
elif optionModel == "poisson":
|
|
3131
|
-
n_e2[0] = np.random.poisson(sum(np.asarray(e_quenching2))*L*mu*dirichTD[0])
|
|
3132
|
-
n_e2[1] = np.random.poisson(sum(np.asarray(e_quenching2))*L*mu*dirichTD[1])
|
|
3133
|
-
n_e2[2] = np.random.poisson(sum(np.asarray(e_quenching2))*L*mu*dirichTD[2])
|
|
3134
|
-
n_e2CN[0] = np.random.poisson(sum(np.asarray(e_quenching2))*L*mu*dirichCN[0])
|
|
3135
|
-
n_e2CN[1] = np.random.poisson(sum(np.asarray(e_quenching2))*L*mu*dirichCN[1])
|
|
3136
|
-
else:
|
|
3137
|
-
print("unknown model")
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
if sum(n_e2>1)>0: efficiency0_S +=1
|
|
3141
|
-
if sum(n_e2>1)>1: efficiency0_D +=1
|
|
3142
|
-
if sum(n_e2>1)>2: efficiency0_T +=1
|
|
3143
|
-
if n_e2[0]>1 and n_e2[1]>1: efficiency0_AB +=1
|
|
3144
|
-
if n_e2[1]>1 and n_e2[2]>1: efficiency0_BC +=1
|
|
3145
|
-
if n_e2[0]>1 and n_e2[2]>1: efficiency0_AC +=1
|
|
3146
|
-
if sum(n_e2CN>1)>1: efficiency0_D2 +=1
|
|
3240
|
+
# n_e = np.zeros(3); n_eCN = np.zeros(2); n_e2 = np.zeros(3); n_e2CN = np.zeros(2)
|
|
3241
|
+
if optionModel == "stochastic-dependence":
|
|
3242
|
+
n_e, n_eCN = stochasOpticModel(e_quenching, L, mu)
|
|
3243
|
+
elif optionModel == "poisson":
|
|
3244
|
+
n_e, n_eCN = Pmodel(e_quenching, [1/3, 1/3, 1/3], [1/2, 1/2], L, mu)
|
|
3245
|
+
else:
|
|
3246
|
+
print("unknown model")
|
|
3147
3247
|
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
n_eCN[0]=np.random.binomial(n_phPMTCN[0],mu)
|
|
3160
|
-
n_eCN[1]=np.random.binomial(n_phPMTCN[1],mu)
|
|
3248
|
+
if sum(n_e>0)>0: efficiency0_S =1
|
|
3249
|
+
if sum(n_e>0)>1: efficiency0_D =1
|
|
3250
|
+
if sum(n_e>0)>2: efficiency0_T =1
|
|
3251
|
+
if n_e[0]>0 and n_e[1]>0: efficiency0_AB =1
|
|
3252
|
+
if n_e[1]>0 and n_e[2]>0: efficiency0_BC =1
|
|
3253
|
+
if n_e[0]>0 and n_e[2]>0: efficiency0_AC =1
|
|
3254
|
+
if sum(n_eCN>1)>1: efficiency0_D2 =1
|
|
3255
|
+
|
|
3256
|
+
if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
|
|
3257
|
+
if optionModel == "stochastic-dependence":
|
|
3258
|
+
n_e2, n_e2CN = stochasOpticModel(e_quenching2, L, mu)
|
|
3161
3259
|
elif optionModel == "poisson":
|
|
3162
|
-
|
|
3163
|
-
n_e[1] = np.random.poisson(sum(np.asarray(e_quenching))*L[1]*mu*dirichTD[1])
|
|
3164
|
-
n_e[2] = np.random.poisson(sum(np.asarray(e_quenching))*L[2]*mu*dirichTD[2])
|
|
3165
|
-
n_eCN[0] = np.random.poisson(sum(np.asarray(e_quenching))*L[0]*mu*dirichCN[0])
|
|
3166
|
-
n_eCN[1] = np.random.poisson(sum(np.asarray(e_quenching))*L[1]*mu*dirichCN[1])
|
|
3260
|
+
n_e2, n_e2CN = Pmodel(e_quenching2, [1/3, 1/3, 1/3], [1/2, 1/2], L, mu)
|
|
3167
3261
|
else:
|
|
3168
3262
|
print("unknown model")
|
|
3169
|
-
|
|
3170
|
-
if sum(n_e>1)>0: efficiency0_S =1
|
|
3171
|
-
if sum(n_e>1)>1: efficiency0_D =1
|
|
3172
|
-
if sum(n_e>1)>2: efficiency0_T =1
|
|
3173
|
-
if n_e[0]>1 and n_e[1]>1: efficiency0_AB =1
|
|
3174
|
-
if n_e[1]>1 and n_e[2]>1: efficiency0_BC =1
|
|
3175
|
-
if n_e[0]>1 and n_e[2]>1: efficiency0_AC =1
|
|
3176
|
-
if sum(n_eCN>1)>1: efficiency0_D2 =1
|
|
3177
|
-
|
|
3178
|
-
if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
|
|
3179
|
-
if optionModel == "poisson-multinomial-binomial":
|
|
3180
|
-
n_ph2 = np.random.poisson(sum(np.asarray(e_quenching2))*Lm/mu)
|
|
3181
|
-
# TDCR
|
|
3182
|
-
n_phPMT2 = np.random.multinomial(n_ph2, [L[0]*dirichCN[0]/Lm, L[1]*dirichCN[1]/Lm, L[2]*dirichCN[2]/Lm])
|
|
3183
|
-
n_e2[0]=np.random.binomial(n_phPMT2[0],mu)
|
|
3184
|
-
n_e2[1]=np.random.binomial(n_phPMT2[1],mu)
|
|
3185
|
-
n_e2[2]=np.random.binomial(n_phPMT2[2],mu)
|
|
3186
|
-
# C/N
|
|
3187
|
-
n_phPMT2CN = np.random.multinomial(n_ph2, [L[0]/(2*Lm), L[1]/(2*Lm)])
|
|
3188
|
-
n_e2CN[0]=np.random.binomial(n_phPMT2CN[0],mu)
|
|
3189
|
-
n_e2CN[1]=np.random.binomial(n_phPMT2CN[1],mu)
|
|
3190
|
-
elif optionModel == "poisson":
|
|
3191
|
-
n_e2[0] = np.random.poisson(sum(np.asarray(e_quenching2))*L[0]*mu*dirichTD[0])
|
|
3192
|
-
n_e2[1] = np.random.poisson(sum(np.asarray(e_quenching2))*L[1]*mu*dirichTD[1])
|
|
3193
|
-
n_e2[2] = np.random.poisson(sum(np.asarray(e_quenching2))*L[2]*mu*dirichTD[2])
|
|
3194
|
-
n_e2CN[0] = np.random.poisson(sum(np.asarray(e_quenching2))*L[0]*mu*dirichCN[0])
|
|
3195
|
-
n_e2CN[1] = np.random.poisson(sum(np.asarray(e_quenching2))*L[1]*mu*dirichCN[1])
|
|
3196
|
-
else:
|
|
3197
|
-
print("unknown model")
|
|
3198
|
-
|
|
3199
|
-
if sum(n_e2>1)>0: efficiency0_S +=1
|
|
3200
|
-
if sum(n_e2>1)>1: efficiency0_D +=1
|
|
3201
|
-
if sum(n_e2>1)>2: efficiency0_T +=1
|
|
3202
|
-
if n_e2[0]>1 and n_e2[1]>1: efficiency0_AB +=1
|
|
3203
|
-
if n_e2[1]>1 and n_e2[2]>1: efficiency0_BC +=1
|
|
3204
|
-
if n_e2[0]>1 and n_e2[2]>1: efficiency0_AC +=1
|
|
3205
|
-
if sum(n_e2CN>1)>1: efficiency0_D2 +=1
|
|
3206
3263
|
|
|
3264
|
+
if sum(n_e2>0)>0: efficiency0_S +=1
|
|
3265
|
+
if sum(n_e2>0)>1: efficiency0_D +=1
|
|
3266
|
+
if sum(n_e2>0)>2: efficiency0_T +=1
|
|
3267
|
+
if n_e2[0]>0 and n_e2[1]>0: efficiency0_AB +=1
|
|
3268
|
+
if n_e2[1]>0 and n_e2[2]>0: efficiency0_BC +=1
|
|
3269
|
+
if n_e2[0]>0 and n_e2[2]>0: efficiency0_AC +=1
|
|
3270
|
+
if sum(n_e2CN>1)>1: efficiency0_D2 +=1
|
|
3271
|
+
|
|
3207
3272
|
return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
|
|
3208
3273
|
|
|
3209
3274
|
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
3275
|
def efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_AB, efficiency_BC, efficiency_AC, efficiency_D2, N):
|
|
3214
3276
|
"""
|
|
3215
3277
|
Calculate detection efficiencies from list of detection probabilities per decays.
|
|
@@ -3319,6 +3381,9 @@ def readRecQuenchedEnergies():
|
|
|
3319
3381
|
e_quenching.append(energy)
|
|
3320
3382
|
return Epromt, Edelayed
|
|
3321
3383
|
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
|
|
3322
3387
|
# N = 1e7
|
|
3323
3388
|
# buildBetaSpectra('H-3', 16, N, prt=True); print('H-3 - done')
|
|
3324
3389
|
# buildBetaSpectra('C-14', 16, N, prt=True); print('C-14 - done')
|
tdcrpy/config.toml
CHANGED
|
@@ -32,12 +32,14 @@ diam_micelle = 2
|
|
|
32
32
|
fAq = 0.1
|
|
33
33
|
|
|
34
34
|
## OPTICAL PROPERTIES
|
|
35
|
-
# Dirichlet parameter
|
|
36
|
-
alphaDir = 100000
|
|
37
35
|
# Quantum efficiency
|
|
38
|
-
effQuantum = 0.25
|
|
36
|
+
effQuantum = 0.25, 0.25, 0.25
|
|
39
37
|
# Optical MC model
|
|
40
|
-
optionModel =
|
|
38
|
+
optionModel = stochastic-dependence
|
|
39
|
+
# fraction of diffused scintillation photons
|
|
40
|
+
diffP = 1.0
|
|
41
|
+
# relative distance from vials border to PMT entrance
|
|
42
|
+
PMTspace = 0.1
|
|
41
43
|
|
|
42
44
|
## PROPERTIES OF THE COUNTER
|
|
43
45
|
# Coincidence resolving time (ns)
|
tdcrpy/test_randomGen.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Wed May 14 16:17:16 2025
|
|
4
|
+
|
|
5
|
+
@author: romain.coulon
|
|
6
|
+
"""
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
# m = 0.1
|
|
10
|
+
# N = 1000000
|
|
11
|
+
|
|
12
|
+
# ps0 = 1-np.exp(-m)
|
|
13
|
+
|
|
14
|
+
# psi=np.random.poisson(m,N)
|
|
15
|
+
# ps1 = sum(psi>0)/N
|
|
16
|
+
# ups1 = np.sqrt(sum(psi>0))/N
|
|
17
|
+
|
|
18
|
+
# print(ps0,ps1,ups1)
|
|
19
|
+
# print(ps0-ps1,ups1)
|
|
20
|
+
# print(abs(ps0-ps1)<2*ups1)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
import tdcrpy
|
|
24
|
+
tdcrpy.TDCR_model_lib.modifyEffQ("0.2, 0.2, 0.2")
|
|
25
|
+
# tdcrpy.TDCR_model_lib.modifyOptModel("stochastic-dependence")
|
|
26
|
+
tdcrpy.TDCR_model_lib.modifyOptModel("poisson")
|
|
27
|
+
L = [9.0, 9.0, 9.0]
|
|
28
|
+
e_q = [0.5]
|
|
29
|
+
tdcrpy.TDCR_model_lib.readParameters(disp=True)
|
|
30
|
+
|
|
31
|
+
import tdcrpy
|
|
32
|
+
diffP = 1
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Q = tdcrpy.TDCR_model_lib.readEffQ0()
|
|
36
|
+
Q = Q.split(",")
|
|
37
|
+
Q = [float(i) for i in Q]
|
|
38
|
+
QL = [float(Qi)*L[i] for i, Qi in enumerate(Q)]
|
|
39
|
+
print("EffQ = ", Q)
|
|
40
|
+
print("EffQ*L = ", QL)
|
|
41
|
+
|
|
42
|
+
e_q2 = [0]; t1 = 0; evenement = 1; extDT = 50; measTime = 60000
|
|
43
|
+
|
|
44
|
+
# S,D,T,_,_,_,_ = detectProbabilities(QL, e_q, e_q2, t1, evenement, extDT, measTime)
|
|
45
|
+
S,D,T,_,_,_,_ = tdcrpy.TDCR_model_lib.detectProbabilities(QL, e_q, e_q2, t1, evenement, extDT, measTime)
|
|
46
|
+
SmcI=[];DmcI=[];TmcI=[]
|
|
47
|
+
nIter=100000
|
|
48
|
+
for i in range(nIter):
|
|
49
|
+
Smc,Dmc,Tmc,_,_,_,_ = tdcrpy.TDCR_model_lib.detectProbabilitiesMC(L, e_q, e_q2, t1, evenement, extDT, measTime,
|
|
50
|
+
PMTspace=0, diffP=diffP, effQuantic = Q)
|
|
51
|
+
# Smc,Dmc,Tmc,_,_,_,_ = detectProbabilitiesMC(L, e_q, e_q2, t1, evenement, extDT, measTime,
|
|
52
|
+
# PMTspace=0,diffP=diffP)
|
|
53
|
+
SmcI.append(Smc); DmcI.append(Dmc); TmcI.append(Tmc)
|
|
54
|
+
|
|
55
|
+
print("\nEFF, EFFmc, +/-")
|
|
56
|
+
print("single eff = ",round(S,4),round(np.mean(SmcI),4),round(np.std(SmcI)/np.sqrt(nIter),4))
|
|
57
|
+
print("double eff = ",round(D,4),round(np.mean(DmcI),4),round(np.std(DmcI)/np.sqrt(nIter),4))
|
|
58
|
+
print("triple eff = ",round(T,4),round(np.mean(TmcI),4),round(np.std(TmcI)/np.sqrt(nIter),4))
|
|
59
|
+
print('\nDEVIATION < 2 sigma')
|
|
60
|
+
print("single eff = ",abs(round(S,4)-round(np.mean(SmcI),4))<2*round(np.std(SmcI)/np.sqrt(nIter),4))
|
|
61
|
+
print("double eff = ",abs(round(D,4)-round(np.mean(DmcI),4))<2*round(np.std(DmcI)/np.sqrt(nIter),4))
|
|
62
|
+
print("triple eff = ",abs(round(T,4)-round(np.mean(TmcI),4))<2*round(np.std(TmcI)/np.sqrt(nIter),4))
|
|
63
|
+
print('\nPRECISION')
|
|
64
|
+
print("single eff = ",round(100*np.std(SmcI)/(np.sqrt(nIter)*round(np.mean(SmcI),4)),4)," %")
|
|
65
|
+
print("double eff = ",round(100*np.std(DmcI)/(np.sqrt(nIter)*round(np.mean(DmcI),4)),4)," %")
|
|
66
|
+
print("triple eff = ",round(100*np.std(TmcI)/(np.sqrt(nIter)*round(np.mean(TmcI),4)),4)," %")
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
tdcrpy/TDCRPy.py,sha256=
|
|
1
|
+
tdcrpy/TDCRPy.py,sha256=vr3adVMfSRW6bNXZXJnvjwhhuql39nCAHEFFi_1S2Mo,67863
|
|
2
2
|
tdcrpy/TDCRPy1.py,sha256=QTBZh5B5JWnGB0BQfD-cFmwA9W080OD4sG-aj50-ejo,38106
|
|
3
|
-
tdcrpy/TDCR_model_lib.py,sha256=
|
|
3
|
+
tdcrpy/TDCR_model_lib.py,sha256=pjoPKHMRmFlJJiw06bYf5WLm70vPWsKvuR5-RI2e-m4,137978
|
|
4
4
|
tdcrpy/TDCRoptimize.py,sha256=c2XIGveeLdVYYek4Rg6dygMvVA2xIrIkMb3L-_jUucM,6496
|
|
5
5
|
tdcrpy/__init__.py,sha256=9Djir8dPNchcJVQvhl-oRHEOsoDkiZlkOhWT-eHR7wQ,95
|
|
6
|
-
tdcrpy/config.toml,sha256=
|
|
6
|
+
tdcrpy/config.toml,sha256=UvIV6oUFjkk96c0Z053l14vekVc0eZ2-C0xy8MTs2zQ,1725
|
|
7
7
|
tdcrpy/test2.py,sha256=poLLXJyIaCeqh1VSkwgbi-udvY7lQjxz_YStKjJXGhU,501
|
|
8
|
+
tdcrpy/test_randomGen.py,sha256=dhKjtjguGWd9OWl0ZcrfXHiDJUi_XJ1IY3t9qvPowf8,2457
|
|
8
9
|
tdcrpy/MCNP-MATRIX/Spectra_for_analytical_model/dep_spectrum_C-14.txt,sha256=Eh3KaNbfYHakk_uStLu8K1aFciO6_i_rS2yKxGGppDE,8416
|
|
9
10
|
tdcrpy/MCNP-MATRIX/Spectra_for_analytical_model/dep_spectrum_Ca-45.txt,sha256=TymodcK4ttoO1duZuW3RGOwHFwPPzw2ESPc_H_QQN8k,8830
|
|
10
11
|
tdcrpy/MCNP-MATRIX/Spectra_for_analytical_model/dep_spectrum_Co-60.txt,sha256=kxD5E7tk_Gc1Ylg8qCG1r3oB21m7wUT4zBWsmbseiMU,40203
|
|
@@ -74,8 +75,8 @@ tdcrpy/docs/_build/html/source/modules.html,sha256=Jf-qxVBId0UgpwyvYuyjtMNG-ezPO
|
|
|
74
75
|
tdcrpy/docs/_build/html/source/tdcrpy.html,sha256=-38lHMNFB22p1tWJEeN3yDqfDiCYE304vxDamO1-iRc,3779
|
|
75
76
|
tdcrpy/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
77
|
tdcrpy/test/test_tdcrpy.py,sha256=JINqSEMFoNpptE4f3h6ZzTYW1rBx90KkaoQzltSg-No,4692
|
|
77
|
-
tdcrpy-2.
|
|
78
|
-
tdcrpy-2.
|
|
79
|
-
tdcrpy-2.
|
|
80
|
-
tdcrpy-2.
|
|
81
|
-
tdcrpy-2.
|
|
78
|
+
tdcrpy-2.12.13.dist-info/licenses/LICENCE.md,sha256=ZTpWyGU3qv_iwEpgvCijoCuCYpOPpyzJCgOk46WpUKU,1066
|
|
79
|
+
tdcrpy-2.12.13.dist-info/METADATA,sha256=NQQG95cOfBPp_1BMGGR6PZyt2WQy1qGtX-hJrcPF-kU,45300
|
|
80
|
+
tdcrpy-2.12.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
81
|
+
tdcrpy-2.12.13.dist-info/top_level.txt,sha256=f4vzFFcKSEnonAACs0ZXuRczmroLLqtPTqXFymU_VU0,14
|
|
82
|
+
tdcrpy-2.12.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|