TDCRPy 2.4.0__py3-none-any.whl → 2.15.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.
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)
@@ -1038,7 +1039,7 @@ def objectFct(L, TD, Rad, pmf_1, N, kB, V):
1038
1039
 
1039
1040
  return res
1040
1041
 
1041
- def eff(TD, Rad, pmf_1, kB, V, N=10000, L=1, maxiter=20, xatol=1e-7, disp=False):
1042
+ def eff(TD, Rad, pmf_1, kB, V, N=10000, L=1, maxiter=20, xatol=1e-7, disp=False, Lbounds=[0.1, 10]):
1042
1043
  """
1043
1044
  Caclulation of the efficiency of a TDCR system based on the model TDCRPy.
1044
1045
  This function includes optimization procedures from scipy.
@@ -1107,8 +1108,8 @@ def eff(TD, Rad, pmf_1, kB, V, N=10000, L=1, maxiter=20, xatol=1e-7, disp=False)
1107
1108
 
1108
1109
  TDCRPy(L, Rad, pmf_1, N, kB, V, record = True)
1109
1110
 
1110
- if symm: r=opt.minimize_scalar(objectFct, args=(TD, Rad, pmf_1, N, kB, V), method='bounded', bounds = (0.1, 5), options={'disp': disp, 'maxiter':maxiter})
1111
- else: r=opt.minimize_scalar(objectFct, args=(TD[0], Rad, pmf_1, N, kB, V), method='bounded', bounds = (0.1, 5), options={'disp': disp, 'maxiter':maxiter})
1111
+ if symm: r=opt.minimize_scalar(objectFct, args=(TD, Rad, pmf_1, N, kB, V), method='bounded', bounds = (Lbounds[0], Lbounds[1]), options={'disp': disp, 'maxiter':maxiter})
1112
+ else: r=opt.minimize_scalar(objectFct, args=(TD[0], Rad, pmf_1, N, kB, V), method='bounded', bounds = (Lbounds[0], Lbounds[1]), options={'disp': disp, 'maxiter':maxiter})
1112
1113
  L0=r.x
1113
1114
  L=(L0, L0, L0)
1114
1115
  print(f"global free parameter = {L0} keV-1")
@@ -1138,7 +1139,7 @@ def eff(TD, Rad, pmf_1, kB, V, N=10000, L=1, maxiter=20, xatol=1e-7, disp=False)
1138
1139
  return L0, L, eff_S, u_eff_S, eff_D, u_eff_D, eff_T, u_eff_T, eff_AB, u_eff_AB, eff_BC, u_eff_BC, eff_AC, u_eff_AC, eff_D2, u_eff_D2
1139
1140
 
1140
1141
 
1141
- def effA(TD, Rad, pmf_1, kB, V, L=1, maxiter=20, xatol=1e-7, disp=False):
1142
+ def effA(TD, Rad, pmf_1, kB, V, L=1, maxiter=20, xatol=1e-7, disp=False, Lbounds=[0.1, 10]):
1142
1143
  """
1143
1144
  Caclulation of the efficiency of a TDCR system based on the model TDCRPy (analytical model).
1144
1145
  This function includes optimization procedures from scipy.
@@ -1203,8 +1204,8 @@ def effA(TD, Rad, pmf_1, kB, V, L=1, maxiter=20, xatol=1e-7, disp=False):
1203
1204
  else:
1204
1205
  symm = True
1205
1206
 
1206
- if symm: r=opt.minimize_scalar(tl.modelAnalytical, args=(TD, TD, TD, TD, Rad, kB, V, "res", 1e3), method='bounded', bounds = (0.1, 5), options={'disp': disp, 'maxiter':maxiter})
1207
- else: r=opt.minimize_scalar(tl.modelAnalytical, args=(TD[0], TD[1], TD[2], TD[3], Rad, kB, V, "res", 1e3), method='bounded', bounds = (0.1, 5), options={'disp': disp, 'maxiter':maxiter})
1207
+ if symm: r=opt.minimize_scalar(tl.modelAnalytical, args=(TD, TD, TD, TD, Rad, kB, V, "res", 1e3), method='bounded', bounds = (Lbounds[0], Lbounds[1]), options={'disp': disp, 'maxiter':maxiter})
1208
+ else: r=opt.minimize_scalar(tl.modelAnalytical, args=(TD[0], TD[1], TD[2], TD[3], Rad, kB, V, "res", 1e3), method='bounded', bounds = (Lbounds[0], Lbounds[1]), options={'disp': disp, 'maxiter':maxiter})
1208
1209
  L0=r.x
1209
1210
  L=(L0, L0, L0)
1210
1211
  print(f"global free parameter = {L0} keV-1")
@@ -1236,20 +1237,20 @@ def effA(TD, Rad, pmf_1, kB, V, L=1, maxiter=20, xatol=1e-7, disp=False):
1236
1237
 
1237
1238
 
1238
1239
  # mode = "eff" # ask for efficiency calculation
1239
- # Rad="Na-22" # radionuclides
1240
+ # Rad="Fe-55" # radionuclides
1240
1241
  # pmf_1="1" # relatives fractions of the radionulides
1241
1242
  # N = 1000 # number of Monte Carlo trials
1242
1243
  # kB =1.0e-5 # Birks constant in cm keV-1
1243
1244
  # V = 10 # volume of scintillator in mL
1244
- # L=np.logspace(-3,2,num=100) # free parameter in keV-1
1245
+ # L=np.logspace(-1,2,num=100) # free parameter in keV-1
1245
1246
 
1246
- # # TDCRPy(1, Rad, pmf_1, 10, kB, V, mode, Display= True, barp=False, record=True)
1247
1247
  # # Record decay histories in temporary files
1248
- # TDCRPy(L[0], Rad, pmf_1, N, kB, V, mode, barp=False, record=True)
1248
+ # TDCRPy(L[0], Rad, pmf_1, N, kB, V, mode, barp=False, record=True, fullMC=False)
1249
+ # # TDCRPy(100, Rad, pmf_1, N, kB, V, mode, barp=False, record=True, fullMC=True)
1249
1250
 
1250
1251
  # effS, u_effS, effD, u_effD, effT, u_effT, effD2, u_effD2 = [], [],[], [],[], [], [], []
1251
1252
  # for l in tqdm(L, desc="free parameters ", unit=" iterations"):
1252
- # out = TDCRPy(l, Rad, pmf_1, N, kB, V, mode, readRecHist=True)
1253
+ # out = TDCRPy(l, Rad, pmf_1, N, kB, V, mode, readRecHist=True, fullMC=False)
1253
1254
  # effS.append(out[2])
1254
1255
  # u_effS.append(out[3])
1255
1256
  # effD.append(out[2])
tdcrpy/TDCR_model_lib.py CHANGED
@@ -11,7 +11,6 @@ Bureau International des Poids et Mesures
11
11
  """
12
12
  ======= Import Python Module =======
13
13
  """
14
-
15
14
  import importlib.resources
16
15
  from importlib.resources import files
17
16
  import pkg_resources
@@ -24,6 +23,7 @@ import scipy.interpolate as interp
24
23
  import matplotlib.pyplot as plt
25
24
  from tqdm import tqdm
26
25
  import tempfile
26
+ import math
27
27
 
28
28
  """
29
29
  ======= Import ressource data =======
@@ -32,6 +32,16 @@ import tempfile
32
32
  # import advanced configuration data
33
33
  config = configparser.ConfigParser()
34
34
 
35
+ def readEffQ0():
36
+ global config, file_conf
37
+ config = configparser.ConfigParser()
38
+ with importlib.resources.as_file(files('tdcrpy').joinpath('config.toml')) as data_path:
39
+ file_conf = data_path
40
+ config.read(file_conf)
41
+
42
+ effQuantic0 = config["Inputs"].get("effQuantum")
43
+ return effQuantic0
44
+
35
45
  def readParameters(disp=False):
36
46
  global config, file_conf
37
47
  config = configparser.ConfigParser()
@@ -60,6 +70,15 @@ def readParameters(disp=False):
60
70
  diam_micelle = config["Inputs"].getfloat("diam_micelle")
61
71
  fAq = config["Inputs"].getfloat("fAq")
62
72
  micCorr = config["Inputs"].getboolean("micCorr")
73
+ # alphaDir = config["Inputs"].getfloat("alphaDir")
74
+ effQuantic0 = config["Inputs"].get("effQuantum")
75
+ effQuantic = effQuantic0.split(',')
76
+ for i, iS in enumerate(effQuantic):
77
+ iS=iS.replace(" ","")
78
+ if iS != 'None': effQuantic[i]=float(iS)
79
+ optionModel = config["Inputs"].get("optionModel")
80
+ diffP = config["Inputs"].getfloat("diffP")
81
+ PMTspace = config["Inputs"].getfloat("PMTspace")
63
82
 
64
83
  if disp:
65
84
  print(f"number of integration bins for electrons = {nE_electron}")
@@ -76,13 +95,18 @@ def readParameters(disp=False):
76
95
  print(f"activation of the micelle correction = {micCorr}")
77
96
  print(f"diameter of micelle = {diam_micelle} nm")
78
97
  print(f"acqueous fraction = {fAq}")
98
+ # print(f"alpha parameter of the hidden Dirichlet process = {alphaDir}")
99
+ print(f"quantum efficiency of the photocathodes = {effQuantic}")
100
+ print(f"Monte Carlo model of the optics = {optionModel}")
101
+ print(f"fraction of diffused scintillation photons = {diffP*100:.1f} %")
102
+ print(f"relative distance from vials border to PMT entrance = {PMTspace*100:.1f} %")
79
103
  print(f"coincidence resolving time = {tau} ns")
80
104
  print(f"extended dead time = {extDT} µs")
81
105
  print(f"measurement time = {measTime} min")
82
106
 
83
- return nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr, pH,pC,pN,pO,pP,pCl
107
+ 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
84
108
 
85
- nE_electron, nE_alpha, RHO, Z, A, depthSpline, Einterp_a, Einterp_e, diam_micelle, fAq, tau, extDT, measTime, micCorr, pH,pC,pN,pO,pP,pCl = readParameters()
109
+ 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()
86
110
 
87
111
  p_atom = np.array([pH,pC,pN,pO,pP,pCl]) # atom abondance in the scintillator
88
112
  p_atom /= sum(p_atom)
@@ -96,7 +120,7 @@ def readConfigAsstr():
96
120
  def writeConfifAsstr(data):
97
121
  path2config = str(config.read(file_conf)[0])
98
122
  with open(path2config, 'w') as file:
99
- file.write(data)
123
+ file.write(data)
100
124
 
101
125
  def modifynE_electron(x):
102
126
  data0 = readConfigAsstr()
@@ -190,7 +214,38 @@ def modifyMeasTime(x):
190
214
  def modifyMicCorr(x):
191
215
  data0 = readConfigAsstr()
192
216
  x0 = readParameters()[13]
193
- data1 = data0.replace(f"micCorr = {x0}",f"micCorr= {x}")
217
+ data1 = data0.replace(f"micCorr = {x0}",f"micCorr = {x}")
218
+ writeConfifAsstr(data1)
219
+
220
+ # def modifyAlphaDir(x):
221
+ # data0 = readConfigAsstr()
222
+ # x0 = readParameters()[14]
223
+ # data1 = data0.replace(f"alphaDir = {x0}",f"alphaDir = {x}")
224
+ # writeConfifAsstr(data1)
225
+
226
+ def modifyEffQ(x):
227
+ data0 = readConfigAsstr()
228
+ # x0 = readParameters()[14]
229
+ x0 = readEffQ0()
230
+ data1 = data0.replace(f"effQuantum = {x0}",f"effQuantum = {x}")
231
+ writeConfifAsstr(data1)
232
+
233
+ def modifyOptModel(x):
234
+ data0 = readConfigAsstr()
235
+ x0 = readParameters()[15]
236
+ data1 = data0.replace(f"optionModel = {x0}",f"optionModel = {x}")
237
+ writeConfifAsstr(data1)
238
+
239
+ def modifyDiffP(x):
240
+ data0 = readConfigAsstr()
241
+ x0 = readParameters()[16]
242
+ data1 = data0.replace(f"diffP = {x0:.1f}",f"diffP = {x:.1f}")
243
+ writeConfifAsstr(data1)
244
+
245
+ def modifyPMTspace(x):
246
+ data0 = readConfigAsstr()
247
+ x0 = readParameters()[17]
248
+ data1 = data0.replace(f"PMTspace = {x0:.1f}",f"PMTspace = {x:.1f}")
194
249
  writeConfifAsstr(data1)
195
250
 
196
251
  def read_temp_files(copy=False, path="C:"):
@@ -2851,7 +2906,7 @@ def buildBetaSpectra(rad, V, N, prt=False):
2851
2906
  else: file.write(f"{b}\t{p2[i]}\n")
2852
2907
  print("file written in local")
2853
2908
 
2854
- def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime):
2909
+ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime, effQuantic = effQuantic):
2855
2910
  """
2856
2911
  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
2857
2912
 
@@ -2892,17 +2947,20 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2892
2947
  """
2893
2948
  if isinstance(L, (tuple, list)):
2894
2949
  symm = False
2950
+ mu = effQuantic
2895
2951
  else:
2896
2952
  symm = True
2953
+ mu = np.mean(effQuantic)
2897
2954
 
2955
+
2898
2956
 
2899
2957
  if symm:
2900
- # print(evenement !=1, t1 > extDT*1e-6, t1 < measTime*60)
2958
+
2901
2959
  if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
2902
2960
  # TDCR
2903
- p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2961
+ p_nosingle = np.exp(-L*mu*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2904
2962
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2905
- p_nosingle2 = np.exp(-L*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
2963
+ p_nosingle2 = np.exp(-L*mu*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
2906
2964
  p_single2 = 1-p_nosingle2
2907
2965
  efficiency0_S = 1-p_nosingle**3+1-p_nosingle2**3
2908
2966
  efficiency0_T = p_single**3+p_single2**3
@@ -2912,16 +2970,16 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2912
2970
  efficiency0_AC = efficiency0_AB
2913
2971
 
2914
2972
  # CN
2915
- p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2973
+ p_nosingle = np.exp(-L*mu*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2916
2974
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2917
- p_nosingle2 = np.exp(-L*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
2975
+ p_nosingle2 = np.exp(-L*mu*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
2918
2976
  p_single2 = 1-p_nosingle2
2919
2977
  efficiency0_A2 = p_single+p_single2
2920
2978
  efficiency0_B2 = efficiency0_A2
2921
2979
  efficiency0_D2 = p_single**2+p_single2**2
2922
2980
  else:
2923
2981
  # TDCR
2924
- p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2982
+ p_nosingle = np.exp(-L*mu*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2925
2983
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2926
2984
  efficiency0_S = 1-p_nosingle**3
2927
2985
  efficiency0_T = p_single**3
@@ -2931,7 +2989,7 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2931
2989
  efficiency0_AC = efficiency0_AB
2932
2990
 
2933
2991
  # CN
2934
- p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2992
+ p_nosingle = np.exp(-L*mu*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2935
2993
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2936
2994
  efficiency0_A2 = p_single
2937
2995
  efficiency0_B2 = efficiency0_A2
@@ -2939,18 +2997,18 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2939
2997
  else:
2940
2998
  if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
2941
2999
  # TDCR
2942
- pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3000
+ pA_nosingle = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2943
3001
  pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
2944
- pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3002
+ pB_nosingle = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2945
3003
  pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
2946
- pC_nosingle = np.exp(-L[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3004
+ pC_nosingle = np.exp(-L[2]*mu[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2947
3005
  pC_single = 1-pC_nosingle # probability to have at least 1 electrons in a PMT
2948
3006
 
2949
- pA_nosingle2 = np.exp(-L[0]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
3007
+ pA_nosingle2 = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
2950
3008
  pA_single2 = 1-pA_nosingle2 # probability to have at least 1 electrons in a PMT
2951
- pB_nosingle2 = np.exp(-L[1]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
3009
+ pB_nosingle2 = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
2952
3010
  pB_single2 = 1-pB_nosingle2 # probability to have at least 1 electrons in a PMT
2953
- pC_nosingle2 = np.exp(-L[2]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
3011
+ pC_nosingle2 = np.exp(-L[2]*mu[2]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
2954
3012
  pC_single2 = 1-pC_nosingle2 # probability to have at least 1 electrons in a PMT
2955
3013
 
2956
3014
  efficiency0_A2 = pA_single+pA_single2
@@ -2965,24 +3023,24 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2965
3023
 
2966
3024
 
2967
3025
  # CN
2968
- pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
3026
+ pA_nosingle = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2969
3027
  pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
2970
- pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
3028
+ pB_nosingle = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2971
3029
  pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
2972
3030
 
2973
- pA_nosingle2 = np.exp(-L[0]*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
3031
+ pA_nosingle2 = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
2974
3032
  pA_single2 = 1-pA_nosingle2 # probability to have at least 1 electrons in a PMT
2975
- pB_nosingle2 = np.exp(-L[1]*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
3033
+ pB_nosingle2 = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
2976
3034
  pB_single2 = 1-pB_nosingle2 # probability to have at least 1 electrons in a PMT
2977
3035
 
2978
3036
  efficiency0_D2 = pA_single*pB_single+pA_single2*pB_single2
2979
3037
  else:
2980
3038
  # TDCR
2981
- pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3039
+ pA_nosingle = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2982
3040
  pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
2983
- pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3041
+ pB_nosingle = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2984
3042
  pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
2985
- pC_nosingle = np.exp(-L[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
3043
+ pC_nosingle = np.exp(-L[2]*mu[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
2986
3044
  pC_single = 1-pC_nosingle # probability to have at least 1 electrons in a PMT
2987
3045
 
2988
3046
  efficiency0_A2 = pA_single
@@ -2995,16 +3053,114 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, meas
2995
3053
  efficiency0_S = 1-pA_nosingle*pB_nosingle*pC_nosingle
2996
3054
 
2997
3055
  # CN
2998
- pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
3056
+ pA_nosingle = np.exp(-L[0]*mu[0]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2999
3057
  pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
3000
- pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
3058
+ pB_nosingle = np.exp(-L[1]*mu[1]*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
3001
3059
  pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
3002
3060
  efficiency0_D2 = pA_single*pB_single
3003
3061
 
3004
3062
  return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
3005
3063
 
3006
3064
 
3007
- def detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime):
3065
+ def stochasticDepTD(diffP, PMTspace):
3066
+ """
3067
+ Generate the probability
3068
+
3069
+ Parameters
3070
+ ----------
3071
+ diffP : TYPE
3072
+ DESCRIPTION.
3073
+ PMTspace : TYPE
3074
+ DESCRIPTION.
3075
+
3076
+ Returns
3077
+ -------
3078
+ TYPE
3079
+ DESCRIPTION.
3080
+
3081
+ """
3082
+ detA = np.array([[2*(1+PMTspace), 0], [-(1+PMTspace), np.sqrt(3)*(1+PMTspace)]])
3083
+ detB = np.array([[-(1+PMTspace), np.sqrt(3)*(1+PMTspace)], [-(1+PMTspace), -np.sqrt(3)*(1+PMTspace)]])
3084
+ detC = np.array([[-(1+PMTspace), -np.sqrt(3)*(1+PMTspace)], [2*(1+PMTspace), 0]])
3085
+
3086
+ def simulate_photon_groups():
3087
+ rho = 1 * np.sqrt(np.random.uniform(0, 1, 1)) # Radial distance
3088
+ theta = np.random.uniform(0, 2 * np.pi, 1) # Angular position
3089
+ x = rho * np.cos(theta)
3090
+ y = rho * np.sin(theta)
3091
+ return x, y
3092
+
3093
+ def calculate_angle(O, det):
3094
+ A=det[0]
3095
+ B=det[1]
3096
+ OA = (A[0] - O[0], A[1] - O[1]) # Vecteurs OA et OB
3097
+ OB = (B[0] - O[0], B[1] - O[1])
3098
+ dot_product = OA[0] * OB[0] + OA[1] * OB[1] # Produit scalaire OA . OB
3099
+ norm_OA = math.sqrt((OA[0]**2 + OA[1]**2)[0]) # Normes des vecteurs OA et OB
3100
+ norm_OB = math.sqrt((OB[0]**2 + OB[1]**2)[0])
3101
+ cos_angle = dot_product / (norm_OA * norm_OB) # Cosinus de l'angle
3102
+ angle_rad = math.acos(cos_angle[0]) # Angle en radians
3103
+ angle_deg = math.degrees(angle_rad) # Convertir en degrés
3104
+ return angle_deg
3105
+
3106
+ x, y = simulate_photon_groups()
3107
+
3108
+ pa=(1-diffP)*calculate_angle([x, y], detA)/360+diffP/3
3109
+ pb=(1-diffP)*calculate_angle([x, y], detB)/360+diffP/3
3110
+ pc=(1-diffP)*calculate_angle([x, y], detC)/360+diffP/3
3111
+
3112
+ return pa, pb, pc
3113
+
3114
+ # Di = []; Ti = []
3115
+ # n=1000000
3116
+ # for i in range(n):
3117
+ # A = stochasticDepTD(1, 0)
3118
+ # B = np.random.poisson(2)
3119
+ # n_phPMT = np.random.multinomial(B, A) # sample the number of photons in each PMTs (TDCR configuration)
3120
+ # nA=np.random.binomial(n_phPMT[0],0.25) # sample the conversion to photoelectrons PMT A
3121
+ # nB=np.random.binomial(n_phPMT[1],0.25) # sample the conversion to photoelectrons PMT B
3122
+ # nC=np.random.binomial(n_phPMT[2],0.25) # sample the conversion to photoelectrons PMT C
3123
+ # Di.append(sum([nA>0, nB>0, nC>0])>1)
3124
+ # Ti.append(sum([nA>0, nB>0, nC>0])>2)
3125
+ # D = sum(Di)/n
3126
+ # uD = D/np.sqrt(sum(Di))#np.sqrt(n)
3127
+ # T = sum(Ti)/n
3128
+ # uT = T/np.sqrt(sum(Ti))#/np.sqrt(n)
3129
+ # print(D, uD)
3130
+ # print(T, uT)
3131
+
3132
+ def stochasticDepCN(diffP, PMTspace):
3133
+ def simulate_photon_groups():
3134
+ rho = 1 * np.sqrt(np.random.uniform(0, 1, 1)) # Radial distance
3135
+ theta = np.random.uniform(0, 2 * np.pi, 1) # Angular position
3136
+ x = rho * np.cos(theta)
3137
+ y = rho * np.sin(theta)
3138
+ return x, y
3139
+
3140
+ def calculate_angle(O):
3141
+ OA = (-1-PMTspace - O[0], 0 - O[1]) # Vecteurs OA et OB
3142
+ OB = (1+PMTspace - O[0], 0 - O[1])
3143
+ dot_product = OA[0] * OB[0] + OA[1] * OB[1] # Produit scalaire OA . OB
3144
+ norm_OA = math.sqrt((OA[0]**2 + OA[1]**2)[0]) # Normes des vecteurs OA et OB
3145
+ norm_OB = math.sqrt((OB[0]**2 + OB[1]**2)[0])
3146
+ cos_angle = dot_product / (norm_OA * norm_OB) # Cosinus de l'angle
3147
+ angle_rad = math.acos(cos_angle[0]) # Angle en radians
3148
+ angle_deg = math.degrees(angle_rad) # Convertir en degrés
3149
+ return angle_deg
3150
+
3151
+ x, y = simulate_photon_groups()
3152
+
3153
+ if np.random.randint(0, high=2)==0:
3154
+ pa=(1-diffP)*calculate_angle([x, y])/360+diffP/2
3155
+ pb=1-pa
3156
+ else:
3157
+ pb=(1-diffP)*calculate_angle([x, y])/360+diffP/2
3158
+ pa=1-pb
3159
+
3160
+ return pa, pb
3161
+
3162
+
3163
+ def detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime, effQuantic = effQuantic, optionModel=optionModel, diffP = diffP, PMTspace = PMTspace, dispParam=False):
3008
3164
  """
3009
3165
  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
3010
3166
 
@@ -3043,123 +3199,79 @@ def detectProbabilitiesMC(L, e_quenching, e_quenching2, t1, evenement, extDT, me
3043
3199
  detection probability of coincidences in a C/N system.
3044
3200
 
3045
3201
  """
3046
- if isinstance(L, (tuple, list)):
3047
- symm = False
3048
- else:
3049
- symm = True
3202
+ mu = effQuantic
3203
+
3204
+ if type(L) == float:
3205
+ L = [L, L, L]
3050
3206
 
3051
- if symm:
3052
- if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
3053
- m = len(e_quenching)
3054
- n_ph = np.random.poisson(np.asarray((e_quenching+e_quenching2)*L))
3055
- n_S = 0; n_D = 0; n_T = 0; n_AB = 0; n_BC = 0; n_AC = 0; n_D2 = 0; n_A2 = 0; n_B2 = 0;
3056
- for j in n_ph:
3057
- n_phPMT = np.random.multinomial(j, [1/3, 1/3, 1/3])
3058
- if sum(n_phPMT>1)>0: n_S +=1
3059
- if sum(n_phPMT>1)>1: n_D +=1
3060
- if sum(n_phPMT>1)>2: n_T +=1
3061
- if n_phPMT[0]>1 and n_phPMT[1]>1: n_AB +=1
3062
- if n_phPMT[1]>1 and n_phPMT[2]>1: n_BC +=1
3063
- if n_phPMT[0]>1 and n_phPMT[2]>1: n_AC +=1
3064
- efficiency0_S = n_S/m
3065
- efficiency0_T = n_T/m
3066
- efficiency0_D = n_D/m
3067
- efficiency0_AB = n_AB/m
3068
- efficiency0_BC = n_BC/m
3069
- efficiency0_AC = n_AC/m
3070
- for j in n_ph:
3071
- n_phPMT = np.random.multinomial(j, [1/2, 1/2])
3072
- if sum(n_phPMT>1)>1: n_D2 +=1
3073
- if n_phPMT[0]>1: n_A2 +=1
3074
- if n_phPMT[1]>1: n_B2 +=1
3075
- # efficiency0_A2 = n_A2/m
3076
- # efficiency0_B2 = n_B2/m
3077
- efficiency0_D2 = n_D2/m
3078
- else: # symm and no deleayed event sum
3079
- m = len(e_quenching)
3080
- n_ph = np.random.poisson(np.asarray(e_quenching*L))
3081
- n_S = 0; n_D = 0; n_T = 0; n_AB = 0; n_BC = 0; n_AC = 0; n_D2 = 0; n_A2 = 0; n_B2 = 0;
3082
- for j in n_ph:
3083
- n_phPMT = np.random.multinomial(j, [1/3, 1/3, 1/3])
3084
- if sum(n_phPMT>1)>0: n_S +=1
3085
- if sum(n_phPMT>1)>1: n_D +=1
3086
- if sum(n_phPMT>1)>2: n_T +=1
3087
- if n_phPMT[0]>1 and n_phPMT[1]>1: n_AB +=1
3088
- if n_phPMT[1]>1 and n_phPMT[2]>1: n_BC +=1
3089
- if n_phPMT[0]>1 and n_phPMT[2]>1: n_AC +=1
3090
- efficiency0_S = n_S/m
3091
- efficiency0_T = n_T/m
3092
- efficiency0_D = n_D/m
3093
- efficiency0_AB = n_AB/m
3094
- efficiency0_BC = n_BC/m
3095
- efficiency0_AC = n_AC/m
3096
- for j in n_ph:
3097
- n_phPMT = np.random.multinomial(j, [1/2, 1/2])
3098
- if sum(n_phPMT>1)>1: n_D2 +=1
3099
- if n_phPMT[0]>1: n_A2 +=1
3100
- if n_phPMT[1]>1: n_B2 +=1
3101
- # efficiency0_A2 = n_A2/m
3102
- # efficiency0_B2 = n_B2/m
3103
- efficiency0_D2 = n_D2/m
3104
- else: # asym
3105
- if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60: # sum of delayed event
3106
- m = len(e_quenching)
3107
- Lm = np.mean(L)
3108
- n_ph = np.random.poisson(np.asarray(e_quenching+e_quenching2)*Lm)
3109
- n_S = 0; n_D = 0; n_T = 0; n_AB = 0; n_BC = 0; n_AC = 0; n_D2 = 0; n_A2 = 0; n_B2 = 0;
3110
- for j in n_ph:
3111
- n_phPMT = np.random.multinomial(j, [L[0]/(3*Lm), L[1]/(3*Lm), L[2]/(3*Lm)])
3112
- if sum(n_phPMT>1)>0: n_S +=1
3113
- if sum(n_phPMT>1)>1: n_D +=1
3114
- if sum(n_phPMT>1)>2: n_T +=1
3115
- if n_phPMT[0]>1 and n_phPMT[1]>1: n_AB +=1
3116
- if n_phPMT[1]>1 and n_phPMT[2]>1: n_BC +=1
3117
- if n_phPMT[0]>1 and n_phPMT[2]>1: n_AC +=1
3118
- efficiency0_S = n_S/m
3119
- efficiency0_T = n_T/m
3120
- efficiency0_D = n_D/m
3121
- efficiency0_AB = n_AB/m
3122
- efficiency0_BC = n_BC/m
3123
- efficiency0_AC = n_AC/m
3124
- for j in n_ph:
3125
- n_phPMT = np.random.multinomial(j, [L[0]/(2*Lm), L[1]/(2*Lm)])
3126
- if sum(n_phPMT>1)>1: n_D2 +=1
3127
- if n_phPMT[0]>1: n_A2 +=1
3128
- if n_phPMT[1]>1: n_B2 +=1
3129
- # efficiency0_A2 = n_A2/m
3130
- # efficiency0_B2 = n_B2/m
3131
- efficiency0_D2 = n_D2/m
3132
- else: # asym and no sum of delayed events
3133
- m = len(e_quenching)
3134
- Lm = np.mean(L)
3135
- n_ph = np.random.poisson(np.asarray((e_quenching+e_quenching2)*Lm))
3136
- n_S = 0; n_D = 0; n_T = 0; n_AB = 0; n_BC = 0; n_AC = 0; n_D2 = 0; n_A2 = 0; n_B2 = 0;
3137
- for j in n_ph:
3138
- n_phPMT = np.random.multinomial(j, [L[0]/(3*Lm), L[1]/(3*Lm), L[2]/(3*Lm)])
3139
- if sum(n_phPMT>1)>0: n_S +=1
3140
- if sum(n_phPMT>1)>1: n_D +=1
3141
- if sum(n_phPMT>1)>2: n_T +=1
3142
- if n_phPMT[0]>1 and n_phPMT[1]>1: n_AB +=1
3143
- if n_phPMT[1]>1 and n_phPMT[2]>1: n_BC +=1
3144
- if n_phPMT[0]>1 and n_phPMT[2]>1: n_AC +=1
3145
- efficiency0_S = n_S/m
3146
- efficiency0_T = n_T/m
3147
- efficiency0_D = n_D/m
3148
- efficiency0_AB = n_AB/m
3149
- efficiency0_BC = n_BC/m
3150
- efficiency0_AC = n_AC/m
3151
- for j in n_ph:
3152
- n_phPMT = np.random.multinomial(j, [L[0]/(2*Lm), L[1]/(2*Lm)])
3153
- if sum(n_phPMT>1)>1: n_D2 +=1
3154
- if n_phPMT[0]>1: n_A2 +=1
3155
- if n_phPMT[1]>1: n_B2 +=1
3156
- # efficiency0_A2 = n_A2/m
3157
- # efficiency0_B2 = n_B2/m
3158
- efficiency0_D2 = n_D2/m
3159
- return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
3160
-
3161
-
3162
-
3207
+ if dispParam: print(f"EffQ = {mu} - model = {optionModel} - diffP = {diffP} - PMTspace = {PMTspace}")
3208
+
3209
+ def stochasOpticModel(e_q, L, mu):
3210
+ n_e=np.zeros(3); n_eCN=np.zeros(2) # initilize the number of photoelectrons
3211
+
3212
+ n_ph = np.random.poisson(sum(np.asarray(e_q))*np.mean(L)) # sample the number of scintillation photons
3213
+
3214
+ pTD = stochasticDepTD(diffP, PMTspace) # probabilities for photons to move towards the different PMTs (TDCR configuration)
3215
+ n_phPMT = np.random.multinomial(n_ph, pTD) # sample the number of photons in each PMTs (TDCR configuration)
3216
+ n_e[0]=np.random.binomial(n_phPMT[0],mu[0]) # sample the conversion to photoelectrons PMT A
3217
+ n_e[1]=np.random.binomial(n_phPMT[1],mu[1]) # sample the conversion to photoelectrons PMT B
3218
+ n_e[2]=np.random.binomial(n_phPMT[2],mu[2]) # sample the conversion to photoelectrons PMT C
3219
+
3220
+ pCN = stochasticDepCN(diffP, PMTspace) # probabilities for photons to move towards the different PMTs (C/N configuration)
3221
+ n_phPMTCN = np.random.multinomial(n_ph, pCN) # sample the number of photons in each PMTs (C/N configuration)
3222
+ n_eCN[0]=np.random.binomial(n_phPMTCN[0],mu[0]) # sample the conversion to photoelectrons PMT A
3223
+ n_eCN[1]=np.random.binomial(n_phPMTCN[1],mu[1]) # sample the conversion to photoelectrons PMT B
3224
+
3225
+ return n_e, n_eCN
3226
+
3227
+ def Pmodel(e_q, pTD_ideal, pCN_ideal, L, mu):
3228
+ n_e=np.zeros(3); n_eCN=np.zeros(2) # initilize the number of photoelectrons
3229
+
3230
+ 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
3231
+ 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
3232
+ 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
3233
+ 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
3234
+ 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
3235
+
3236
+ return n_e, n_eCN
3237
+
3238
+
3239
+ efficiency0_S = 0; efficiency0_T = 0; efficiency0_D = 0
3240
+ efficiency0_AB = 0; efficiency0_BC = 0; efficiency0_AC = 0
3241
+ efficiency0_D2 = 0;
3242
+ # n_e = np.zeros(3); n_eCN = np.zeros(2); n_e2 = np.zeros(3); n_e2CN = np.zeros(2)
3243
+ if optionModel == "stochastic-dependence":
3244
+ n_e, n_eCN = stochasOpticModel(e_quenching, L, mu)
3245
+ elif optionModel == "poisson":
3246
+ n_e, n_eCN = Pmodel(e_quenching, [1/3, 1/3, 1/3], [1/2, 1/2], L, mu)
3247
+ else:
3248
+ print("unknown model")
3249
+
3250
+ if sum(n_e>0)>0: efficiency0_S =1
3251
+ if sum(n_e>0)>1: efficiency0_D =1
3252
+ if sum(n_e>0)>2: efficiency0_T =1
3253
+ if n_e[0]>0 and n_e[1]>0: efficiency0_AB =1
3254
+ if n_e[1]>0 and n_e[2]>0: efficiency0_BC =1
3255
+ if n_e[0]>0 and n_e[2]>0: efficiency0_AC =1
3256
+ if sum(n_eCN>1)>1: efficiency0_D2 =1
3257
+
3258
+ if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
3259
+ if optionModel == "stochastic-dependence":
3260
+ n_e2, n_e2CN = stochasOpticModel(e_quenching2, L, mu)
3261
+ elif optionModel == "poisson":
3262
+ n_e2, n_e2CN = Pmodel(e_quenching2, [1/3, 1/3, 1/3], [1/2, 1/2], L, mu)
3263
+ else:
3264
+ print("unknown model")
3265
+
3266
+ if sum(n_e2>0)>0: efficiency0_S +=1
3267
+ if sum(n_e2>0)>1: efficiency0_D +=1
3268
+ if sum(n_e2>0)>2: efficiency0_T +=1
3269
+ if n_e2[0]>0 and n_e2[1]>0: efficiency0_AB +=1
3270
+ if n_e2[1]>0 and n_e2[2]>0: efficiency0_BC +=1
3271
+ if n_e2[0]>0 and n_e2[2]>0: efficiency0_AC +=1
3272
+ if sum(n_e2CN>1)>1: efficiency0_D2 +=1
3273
+
3274
+ return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
3163
3275
 
3164
3276
 
3165
3277
  def efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_AB, efficiency_BC, efficiency_AC, efficiency_D2, N):
@@ -3271,6 +3383,9 @@ def readRecQuenchedEnergies():
3271
3383
  e_quenching.append(energy)
3272
3384
  return Epromt, Edelayed
3273
3385
 
3386
+
3387
+
3388
+
3274
3389
  # N = 1e7
3275
3390
  # buildBetaSpectra('H-3', 16, N, prt=True); print('H-3 - done')
3276
3391
  # buildBetaSpectra('C-14', 16, N, prt=True); print('C-14 - done')
tdcrpy/config.toml CHANGED
@@ -31,6 +31,16 @@ diam_micelle = 2
31
31
  # acqueous fraction of the scintillator
32
32
  fAq = 0.1
33
33
 
34
+ ## OPTICAL PROPERTIES
35
+ # Quantum efficiency
36
+ effQuantum = 0.25, 0.25, 0.25
37
+ # Optical MC model
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
43
+
34
44
  ## PROPERTIES OF THE COUNTER
35
45
  # Coincidence resolving time (ns)
36
46
  tau = 50
Binary file
Binary file
Binary file
@@ -0,0 +1,62 @@
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
+ import importlib
23
+ import tdcrpy
24
+ tdcrpy.TDCR_model_lib.modifyEffQ("0.1, 0.1, 0.1")
25
+ # tdcrpy.TDCR_model_lib.modifyOptModel("stochastic-dependence")
26
+ tdcrpy.TDCR_model_lib.modifyOptModel("poisson")
27
+ L = [1.0, 1.0, 1.0]
28
+ e_q = [100]
29
+ diffP = 1
30
+ importlib.reload(tdcrpy.TDCR_model_lib)
31
+
32
+ Q = tdcrpy.TDCR_model_lib.readEffQ0()
33
+ Q = Q.split(",")
34
+ Q = [float(i) for i in Q]
35
+ QL = [float(Qi)*L[i] for i, Qi in enumerate(Q)]
36
+
37
+ e_q2 = [0]; t1 = 0; evenement = 1; extDT = 50; measTime = 60000
38
+
39
+ S,D,T,_,_,_,_ = tdcrpy.TDCR_model_lib.detectProbabilities(QL, e_q, e_q2, t1, evenement, extDT, measTime)
40
+ SmcI=[];DmcI=[];TmcI=[]
41
+ nIter=100000
42
+ for i in range(nIter):
43
+ Smc,Dmc,Tmc,_,_,_,_ = tdcrpy.TDCR_model_lib.detectProbabilitiesMC(L, e_q, e_q2, t1, evenement, extDT, measTime, dispParam=True)
44
+ SmcI.append(Smc); DmcI.append(Dmc); TmcI.append(Tmc)
45
+
46
+ print('\n')
47
+ tdcrpy.TDCR_model_lib.readParameters(disp=True)
48
+
49
+ print("\nEffQ = ", Q, "\tEffQ*L = ", QL, "\n")
50
+
51
+ print("\nEFF, EFFmc, +/-")
52
+ print("single eff = ",round(S,4),round(np.mean(SmcI),4),round(np.std(SmcI)/np.sqrt(nIter),4))
53
+ print("double eff = ",round(D,4),round(np.mean(DmcI),4),round(np.std(DmcI)/np.sqrt(nIter),4))
54
+ print("triple eff = ",round(T,4),round(np.mean(TmcI),4),round(np.std(TmcI)/np.sqrt(nIter),4))
55
+ print('\nDEVIATION < 2 sigma')
56
+ print("single eff = ",abs(round(S,4)-round(np.mean(SmcI),4))<2*round(np.std(SmcI)/np.sqrt(nIter),4))
57
+ print("double eff = ",abs(round(D,4)-round(np.mean(DmcI),4))<2*round(np.std(DmcI)/np.sqrt(nIter),4))
58
+ print("triple eff = ",abs(round(T,4)-round(np.mean(TmcI),4))<2*round(np.std(TmcI)/np.sqrt(nIter),4))
59
+ print('\nPRECISION')
60
+ print("single eff = ",round(100*np.std(SmcI)/(np.sqrt(nIter)*round(np.mean(SmcI),4)),4)," %")
61
+ print("double eff = ",round(100*np.std(DmcI)/(np.sqrt(nIter)*round(np.mean(DmcI),4)),4)," %")
62
+ print("triple eff = ",round(100*np.std(TmcI)/(np.sqrt(nIter)*round(np.mean(TmcI),4)),4)," %")
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TDCRPy
3
- Version: 2.4.0
3
+ Version: 2.15.8
4
4
  Summary: TDCR model
5
5
  Home-page: https://pypi.org/project/TDCRPy/
6
6
  Author: RomainCoulon (Romain Coulon)
7
7
  Author-email: <romain.coulon@bipm.org>
8
8
  Project-URL: Documentation, https://github.com/RomainCoulon/TDCRPy/
9
9
  Keywords: Python,TDCR,Monte-Carlo,radionuclide,scintillation,counting
10
- Classifier: Development Status :: 4 - Beta
10
+ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Intended Audience :: Science/Research
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Natural Language :: English
@@ -49,7 +49,8 @@ The code is developped and maintained by the BIPM (MIT license).
49
49
 
50
50
  Technical details can be found in
51
51
 
52
- http://dx.doi.org/10.13140/RG.2.2.15682.80321
52
+ * http://dx.doi.org/10.13140/RG.2.2.15682.80321
53
+ * https://doi.org/10.1016/j.apradiso.2024.111518
53
54
 
54
55
  ## 1.1 Installation
55
56
 
@@ -1,10 +1,11 @@
1
- tdcrpy/TDCRPy.py,sha256=of9b8U2-Zl1pHj4YqoWLJ6Ibjpb8xFgdE7_-9gO-hEg,67823
1
+ tdcrpy/TDCRPy.py,sha256=3puNWaySzWsCg08OYzI89rWRy5f2CV2aa5HuC0tVCFM,67965
2
2
  tdcrpy/TDCRPy1.py,sha256=QTBZh5B5JWnGB0BQfD-cFmwA9W080OD4sG-aj50-ejo,38106
3
- tdcrpy/TDCR_model_lib.py,sha256=yGvth6Fu1a6tWRu6Uajnpv604qyUMCviBXeifQ6-4Xg,133469
3
+ tdcrpy/TDCR_model_lib.py,sha256=aaQfweMgml6_yzvEAMmVC0zXcYd2WBxqY-os-nzmktA,138157
4
4
  tdcrpy/TDCRoptimize.py,sha256=c2XIGveeLdVYYek4Rg6dygMvVA2xIrIkMb3L-_jUucM,6496
5
5
  tdcrpy/__init__.py,sha256=9Djir8dPNchcJVQvhl-oRHEOsoDkiZlkOhWT-eHR7wQ,95
6
- tdcrpy/config.toml,sha256=d_olKEgxfobBHkZ2wEj9EgKE7I8Wbpim9ZAsi5ImFxk,1470
6
+ tdcrpy/config.toml,sha256=UvIV6oUFjkk96c0Z053l14vekVc0eZ2-C0xy8MTs2zQ,1725
7
7
  tdcrpy/test2.py,sha256=poLLXJyIaCeqh1VSkwgbi-udvY7lQjxz_YStKjJXGhU,501
8
+ tdcrpy/test_randomGen.py,sha256=CWN8jWJ3VAu6WhkRIR9BHv-e4V4hGx5jSfWBqGE0TT4,2195
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
@@ -62,9 +63,9 @@ tdcrpy/Quenching/TandataUG.txt,sha256=AkUGz2dAZ6g3bQIIacR5f92aa8gmiklgRbN4Dyz-12
62
63
  tdcrpy/Quenching/alpha_toulene.txt,sha256=rJB9xCLM3GLg91EKfhu8sGwro281ySq6R0G5mXMt3f8,1553
63
64
  tdcrpy/Quenching/inputVecteurAlpha.txt,sha256=ee4emplX51vhomC7cGNP_eE5eqS9By5PaSSaa4hh1eg,178652
64
65
  tdcrpy/Quenching/inputVecteurElectron.txt,sha256=5NBRBaiB7op1SJ6v952w9gFKqh0x83pn8zYcoUpy33Y,181498
65
- tdcrpy/decayData/All-nuclides_BetaShape.zip,sha256=4aTyDeOLFWAWjfkmr7Fk5xHtsva3RTAUq-8_ii6fLf0,7881260
66
- tdcrpy/decayData/All-nuclides_Ensdf.zip,sha256=GL-X_IG6x4ykGrWYaMiZrjfMXOvYPM07G-Cp8WCPOu8,437902
67
- tdcrpy/decayData/All-nuclides_PenNuc.zip,sha256=DmhS2CYegWhL8qggc_MO6FgyiXE5qX73dOoH-SSQXoo,388954
66
+ tdcrpy/decayData/All-nuclides_BetaShape.zip,sha256=k-UOym1MPPzGrOwal2mrlcXi3NSR1vAqzO15qTsW25c,8000329
67
+ tdcrpy/decayData/All-nuclides_Ensdf.zip,sha256=J7m6Uq9UqEvBgazuu31NPDO-43xMh3Ktq6w6yMEWBF0,453398
68
+ tdcrpy/decayData/All-nuclides_PenNuc.zip,sha256=o2DftXAJW6-zpBpi_ozHZiDIzl3XcEcAjFJZWAeHbI8,410519
68
69
  tdcrpy/decayData/atom-ENDF-VII0.zip,sha256=oP4Z7qWweWF4j12QAIfvLFLlqeY1RomXwXD2iFgQCqo,1624444
69
70
  tdcrpy/decayData/photo-ENDF.zip,sha256=eOiVUt6OKGl0a3pErfaibZzF_yoSzswdUCTbnGNlu7g,249674
70
71
  tdcrpy/docs/_build/html/genindex.html,sha256=FopjoEyhTbeh7qOem-A7er-6yCIfdhv1BIzs9dJocCc,2522
@@ -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.4.0.dist-info/licenses/LICENCE.md,sha256=ZTpWyGU3qv_iwEpgvCijoCuCYpOPpyzJCgOk46WpUKU,1066
78
- tdcrpy-2.4.0.dist-info/METADATA,sha256=gjwfho2j7db0Q52y3Lg79Y9q1r2sg82zl9vS31004m8,45298
79
- tdcrpy-2.4.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
80
- tdcrpy-2.4.0.dist-info/top_level.txt,sha256=f4vzFFcKSEnonAACs0ZXuRczmroLLqtPTqXFymU_VU0,14
81
- tdcrpy-2.4.0.dist-info/RECORD,,
78
+ tdcrpy-2.15.8.dist-info/licenses/LICENCE.md,sha256=ZTpWyGU3qv_iwEpgvCijoCuCYpOPpyzJCgOk46WpUKU,1066
79
+ tdcrpy-2.15.8.dist-info/METADATA,sha256=G68HRdhNUqMMynusKChlR44rsKGNXoD7qFWHo-qisY8,45363
80
+ tdcrpy-2.15.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
81
+ tdcrpy-2.15.8.dist-info/top_level.txt,sha256=f4vzFFcKSEnonAACs0ZXuRczmroLLqtPTqXFymU_VU0,14
82
+ tdcrpy-2.15.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5