TDCRPy 1.13.0__py3-none-any.whl → 2.0.0__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TDCRPy
3
- Version: 1.13.0
3
+ Version: 2.0.0
4
4
  Summary: TDCR model
5
5
  Home-page: https://pypi.org/project/TDCRPy/
6
6
  Author: RomainCoulon (Romain Coulon)
@@ -1,8 +1,8 @@
1
- tdcrpy/TDCRPy.py,sha256=i16smPjN2GhbMfhdnTYNXwnyM0rncCszxjK5XCASPh0,69480
1
+ tdcrpy/TDCRPy.py,sha256=MBIIarFldIoz1BOyWlB_5rKA_5NMed2QQfM-2xqJnUg,61031
2
2
  tdcrpy/TDCRPy1.py,sha256=QTBZh5B5JWnGB0BQfD-cFmwA9W080OD4sG-aj50-ejo,38106
3
- tdcrpy/TDCR_model_lib.py,sha256=GLxnYEmB-U-kIsrSwwvawKsltbMyOZESiE_DdRodxjQ,119180
3
+ tdcrpy/TDCR_model_lib.py,sha256=I8AOboq9sgCnkMpu871RTABgxvUg-OwBNzL20EARJpo,124068
4
4
  tdcrpy/TDCRoptimize.py,sha256=c2XIGveeLdVYYek4Rg6dygMvVA2xIrIkMb3L-_jUucM,6496
5
- tdcrpy/__init__.py,sha256=vQslGLsoZPIceaitnSHOqN6lUdjEyJ3YhfJ6tYdXt-s,127
5
+ tdcrpy/__init__.py,sha256=9Djir8dPNchcJVQvhl-oRHEOsoDkiZlkOhWT-eHR7wQ,95
6
6
  tdcrpy/config.toml,sha256=d_olKEgxfobBHkZ2wEj9EgKE7I8Wbpim9ZAsi5ImFxk,1470
7
7
  tdcrpy/test2.py,sha256=poLLXJyIaCeqh1VSkwgbi-udvY7lQjxz_YStKjJXGhU,501
8
8
  tdcrpy/EfficiencyCurves/Ag-108/EffD_Ag-108_[1]_1e-05.txt,sha256=OUoMuqPTw3fXLu5qaHUFN2iW0dPJ9cRyh99a6mUcEus,43
@@ -1081,8 +1081,8 @@ tdcrpy/docs/_build/html/source/modules.html,sha256=Jf-qxVBId0UgpwyvYuyjtMNG-ezPO
1081
1081
  tdcrpy/docs/_build/html/source/tdcrpy.html,sha256=-38lHMNFB22p1tWJEeN3yDqfDiCYE304vxDamO1-iRc,3779
1082
1082
  tdcrpy/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1083
1083
  tdcrpy/test/test_tdcrpy.py,sha256=JINqSEMFoNpptE4f3h6ZzTYW1rBx90KkaoQzltSg-No,4692
1084
- TDCRPy-1.13.0.dist-info/LICENCE.md,sha256=ZTpWyGU3qv_iwEpgvCijoCuCYpOPpyzJCgOk46WpUKU,1066
1085
- TDCRPy-1.13.0.dist-info/METADATA,sha256=369qvRM9JVEZlkH7YAB5j-DzZG8rmVnUVBQCp7QfVzY,15832
1086
- TDCRPy-1.13.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
1087
- TDCRPy-1.13.0.dist-info/top_level.txt,sha256=f4vzFFcKSEnonAACs0ZXuRczmroLLqtPTqXFymU_VU0,14
1088
- TDCRPy-1.13.0.dist-info/RECORD,,
1084
+ TDCRPy-2.0.0.dist-info/LICENCE.md,sha256=ZTpWyGU3qv_iwEpgvCijoCuCYpOPpyzJCgOk46WpUKU,1066
1085
+ TDCRPy-2.0.0.dist-info/METADATA,sha256=VHpxRhIMAyLRXOcwjFkhQ-E0bVBk5yIQ_YsevRQorcY,15831
1086
+ TDCRPy-2.0.0.dist-info/WHEEL,sha256=nCVcAvsfA9TDtwGwhYaRrlPhTLV9m-Ga6mdyDtuwK18,91
1087
+ TDCRPy-2.0.0.dist-info/top_level.txt,sha256=f4vzFFcKSEnonAACs0ZXuRczmroLLqtPTqXFymU_VU0,14
1088
+ TDCRPy-2.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (73.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
tdcrpy/TDCRPy.py CHANGED
@@ -17,6 +17,7 @@ import numpy as np
17
17
  from tqdm import tqdm
18
18
  import tempfile
19
19
  import os
20
+ import scipy.optimize as opt
20
21
 
21
22
  def relaxAtom(daughter_relax,particle_vec,energy_vec,rad,Display=False,uncData=False):
22
23
 
@@ -83,61 +84,32 @@ def relaxAtom(daughter_relax,particle_vec,energy_vec,rad,Display=False,uncData=F
83
84
  relaxation = False
84
85
  return particle_vec, energy_vec
85
86
 
86
- def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=False, barp=False, Smodel=True, syst = "TDCR", record = False, readRecHist = False, uncData=False):
87
+ def TDCRPy(L, Rad, pmf_1, N, kB, V, mode="eff", Display=False, barp=False, Smodel=True, record = False, readRecHist = False, uncData=False):
87
88
  """
88
- This is the main function of the TDCRPy package running the Monte-Carlo Triple-to-Double Coincidence Ratio model.
89
+ This is the main function of the TDCRPy package.
89
90
  The computation is made for a given solution containing a radionuclide (or a mixture of radionuclides), a given volume of scintillator V and a given Birks constant kB.
90
-
91
- It can operates in two modes:
92
-
93
- --> In mode="eff", it calculates the efficiency of the TDCR system as a function of a value (triplet) of free parameter(s) L, the measurement data is not used;
94
-
95
- --> In mode="res", it calculates the residual of the TDCR model parametrized by a value (or triplet) of free parameter(s) L and the measurement data TD, TAB, TBC, TAC.
96
-
97
- also, two configuration can be set:
98
91
 
99
- --> mode2="sym", where symmetry is considered between the 3 photomultiplier tubes - here L is a scalar and only the global TDCR value TD is used as measurement data.
100
-
101
- --> mode2="asym", where an asymmetry between the 3 photomultiplier tubes is possible - here L is a triplet and only the specific TDCR values TAB, TBC, TAC are used as measurement data.
102
-
103
92
  The parmeter N sets the number of Monte-Carlo trails used for the estimation. Each MC trial corresponds to a simulated radiactive decay.
104
93
  TDCRPY() used a set of fonctions from the tdcrpy.TDCR_model_lib module.
105
94
 
106
95
  Advanced settings can be configured in the config.toml file.
107
96
 
108
- --> By default Y = True so that the analytical model is applied for solution containing only pure beta emitting radionuclides. If you would like to apply the MC calculation also for these nuclides, set Y = False.
109
-
110
- --> If you would like to change the number of bins nE to discretize the linear energy space for quenching calculation, you can change nE_electron and nE_alpha parameters for respectively electrons and alpha particles.
111
-
112
- --> By default the calculation is set for Ultima-Gold cocktail mixed with a small amount of aqueous solution. You can adapt for a specific scintillator by changing the density, the mean charge number Z and the mean mass number A of the scintillator.
113
-
114
-
115
97
  Parameters
116
98
  ----------
117
- L : Float (if mode2="sym") or a tuple (if mode2="asym")
118
- Free parameter in keV-1.
119
- TD : float
120
- triple-to-double coincidence ratio. Not consider if mode2="asym". Not consider if mode2="asym".
121
- TAB : float
122
- triple-to-double coincidence ratio (coincidences between channel A and B). Not consider if mode2="sym".
123
- TBC : float
124
- triple-to-double coincidence ratio (coincidences between channel B and C). Not consider if mode2="sym".
125
- TAC : float
126
- triple-to-double coincidence ratio (coincidences between channel A and C). Not consider if mode2="sym".
99
+ L : Float or tuple
100
+ If L is float, then L is the global free parameter. If L is tuple, then L is a triplet of free parameters. unit keV-1
127
101
  Rad : string
128
102
  List of radionuclides (eg. "H-3, Co-60").
129
103
  pmf_1 : string
130
104
  list of probability of each radionuclide (eg. "0.8, 0.2").
131
105
  N : integer
132
- Number of Monte-Carlo trials. recommanded N>10000 (see JCGM 101). Not applied in the case of pure beta emitting radionuclides.
106
+ Number of Monte-Carlo trials. recommanded N>10000 (see JCGM 101). Not applied in the case of the analytical model.
133
107
  kB : float
134
108
  Birks constant in cm/keV.
135
109
  V : float
136
110
  volume of the scintillator in ml.
137
111
  mode : string
138
- "res" to return the residual, "eff" to return efficiencies.
139
- mode2 : string
140
- "sym" for symetrical model, "asym" for symetrical model.
112
+ "eff" to return efficiencies, "dis" to return list of decay events.
141
113
  Display : Boolean, optional
142
114
  "True" to display details on the decay sampling. The default is False.
143
115
  barp : Boolean, optional
@@ -149,25 +121,42 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
149
121
 
150
122
  Returns
151
123
  -------
152
- res : float
153
- Residuals of the model compared the measurement data for (a) given free parmeters L. (only in mode="res")
154
124
  mean_efficiency_S : float
155
- Estimation of the efficiency of single counting events. (only in mode="eff")
125
+ Estimation of the efficiency of single counting events.
156
126
  std_efficiency_S : float
157
- Standard uncertainty from calculation associated with the estimation of the efficiency of single counting events. (only in mode="eff")
127
+ Standard uncertainty from calculation associated with the estimation of the efficiency of single counting events.
158
128
  mean_efficiency_D : float
159
- Estimation of the efficiency of logic sum of double coincidences. (only in mode="eff")
129
+ Estimation of the efficiency of logic sum of double coincidences.
160
130
  std_efficiency_D : float
161
- Standard uncertainty from calculation associated with the estimation of the efficiency of logic sum of double coincidences. (only in mode="eff")
131
+ Standard uncertainty from calculation associated with the estimation of the efficiency of logic sum of double coincidences.
162
132
  mean_efficiency_T : float
163
- Estimation of the efficiency of triple coincidences. (only in mode="eff")
133
+ Estimation of the efficiency of triple coincidences.
164
134
  std_efficiency_T : float
165
- Standard uncertainty from calculation associated with the estimation of the efficiency of triple coincidences. (only in mode="eff")
135
+ Standard uncertainty from calculation associated with the estimation of the efficiency of triple coincidences.
136
+ mean_efficiency_AB : float
137
+ detection efficiency of coincidences between channels A and B.
138
+ std_efficiency_AB : float
139
+ standard uncertainty of detection efficiency of coincidences between channels A and B.
140
+ mean_efficiency_BC : float
141
+ detection efficiency of coincidences between channels B and C.
142
+ std_efficiency_BC : float
143
+ standard uncertainty of Ddetection efficiency of coincidences between channels B and C.
144
+ mean_efficiency_AC : float
145
+ detection efficiency of coincidences between channels A and C.
146
+ std_efficiency_AC : float
147
+ standard uncertainty of detection efficiency of coincidences between channels A and C.
166
148
  mean_efficiency_D2 : float
167
- Estimation of the efficiency of double coincidences for C/N systems. (only in mode="eff")
149
+ detection efficiency of coincidences in a C/N system.
168
150
  std_efficiency_D2 : float
169
- Standard uncertainty from calculation associated with the estimation of the efficiency of double coincidences for C/N systems. (only in mode="eff")
151
+ standard uncertainty of detection efficiency of coincidences in a C/N system.
170
152
  """
153
+
154
+ if isinstance(L, (tuple, list)):
155
+ symm = False
156
+ else:
157
+ symm = True
158
+
159
+
171
160
  if record:
172
161
  temp_dir = tempfile.gettempdir()
173
162
  recfile1 = os.path.join(temp_dir, "Temp_E0.txt")
@@ -228,17 +217,13 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
228
217
  inE = radListPureBeta.index(Rad)
229
218
  nE = nElist[inE]
230
219
  # print(f"Analytical model used for {Rad}")
231
- out=tl.modelAnalytical(L,TD,TAB,TBC,TAC,Rad,kB,V,mode,mode2,nE)
232
- if mode == "res":
233
- return out
220
+ out=tl.modelAnalytical(L,1,1,1,1,Rad,kB,V,mode,symm,nE)
234
221
  if mode == "eff":
235
222
  return out[0], 0, out[1], 0, out[2], 0
236
223
  elif (not Smodel) and (not Rad in radListPureBeta):
237
224
  # print("cannot be processed by the analytical model.")
238
225
  # print(f"Analytical model used for {Rad}")
239
- out=tl.modelAnalytical(L,TD,TAB,TBC,TAC,Rad,kB,V,mode,mode2,1000)
240
- if mode == "res":
241
- return out
226
+ out=tl.modelAnalytical(L,1,1,1,1,Rad,kB,V,mode,symm,1000)
242
227
  if mode == "eff":
243
228
  return out[0], 0, out[1], 0, out[2], 0
244
229
 
@@ -269,10 +254,13 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
269
254
  if decay != decaym:
270
255
  if decay>0:
271
256
  # print(decay-1,e_quenching,e_quenching2, evenement)
272
- efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_D2 = tl.detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extDT, measTime)
257
+ 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)
273
258
  efficiency_S.append(efficiency0_S)
274
259
  efficiency_T.append(efficiency0_T)
275
260
  efficiency_D.append(efficiency0_D)
261
+ efficiency_AB.append(efficiency0_AB)
262
+ efficiency_BC.append(efficiency0_BC)
263
+ efficiency_AC.append(efficiency0_AC)
276
264
  efficiency_D2.append(efficiency0_D2)
277
265
 
278
266
  # print(efficiency0_D, "\n")
@@ -294,15 +282,19 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
294
282
  else:
295
283
  e_quenching.append(energy)
296
284
 
297
- efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_D2 = tl.detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extDT, measTime)
285
+ 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)
298
286
  efficiency_S.append(efficiency0_S)
299
287
  efficiency_T.append(efficiency0_T)
300
288
  efficiency_D.append(efficiency0_D)
289
+ efficiency_AB.append(efficiency0_AB)
290
+ efficiency_BC.append(efficiency0_BC)
291
+ efficiency_AC.append(efficiency0_AC)
301
292
  efficiency_D2.append(efficiency0_D2)
302
293
 
303
294
  # print(efficiency_D)
304
- outEff = tl.efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_D2, N)
305
- return outEff
295
+ outEff = tl.efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_AB, efficiency_BC, efficiency_AC, efficiency_D2, N)
296
+ if mode == "eff": return outEff
297
+ if mode == "dis": return efficiency_S, efficiency_D, efficiency_T, efficiency_D2
306
298
 
307
299
 
308
300
  # temp1, temp2, temp3, temp4 = tl.read_temp_files()
@@ -957,111 +949,15 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
957
949
  ====================
958
950
  '''
959
951
  if evenement == 1: e_quenching2 = 0; t1=0
960
- efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_D2 = tl.detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extDT, measTime)
952
+ 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)
961
953
  efficiency_S.append(efficiency0_S)
962
954
  efficiency_T.append(efficiency0_T)
963
955
  efficiency_D.append(efficiency0_D)
956
+ efficiency_AB.append(efficiency0_AB)
957
+ efficiency_BC.append(efficiency0_BC)
958
+ efficiency_AC.append(efficiency0_AC)
964
959
  efficiency_D2.append(efficiency0_D2)
965
- # print(e_quenching,efficiency0_D)
966
-
967
-
968
- # if mode2=="sym":
969
- # if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
970
- # p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
971
- # p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
972
- # p_nosingle2 = np.exp(-L*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
973
- # p_single2 = 1-p_nosingle2
974
- # efficiency_S.append(1-p_nosingle**3+1-p_nosingle2**3)
975
- # efficiency_T.append(p_single**3+p_single2**3)
976
- # efficiency_D.append(3*(p_single)**2-2*p_single**3+(3*(p_single2)**2-2*p_single2**3))
977
- # efficiency_D2.append(p_single**2+p_single2**2)
978
- # if Display: print(f"\n\t COUNTING--Sym \n\t\t Free parameter = {L} keV-1 \n\t Summary of TDCR measurement (prompt)")
979
- # if Display: print("\t\t Free parameter = ", L, "keV-1")
980
- # if Display: print("\t\t Efficiency of single events = ", round(1-p_nosingle**3,5))
981
- # if Display: print("\t\t Efficiency of double events = ", round(3*(p_single)**2-2*p_single**3,5))
982
- # if Display: print("\t\t Efficiency of triple events = ", round(p_single**3,5))
983
- # if Display: print("\t Summary of TDCR measurement (delayed)")
984
- # if Display: print("\t\t Efficiency of single events = ", round(1-p_nosingle2**3,5))
985
- # if Display: print("\t\t Efficiency of double events = ", round(3*(p_single2)**2-2*p_single2**3,5))
986
- # if Display: print("\t\t Efficiency of triple events = ", round(p_single2**3,5))
987
- # if Display: print("\t Summary of TDCR measurement (prompt + delayed)")
988
- # if Display: print("\t\t Efficiency of single events = ", round(1-p_nosingle**3+1-p_nosingle2**3,5))
989
- # if Display: print("\t\t Efficiency of double events = ", round(3*(p_single)**2-2*p_single**3+(3*(p_single2)**2-2*p_single2**3),5))
990
- # if Display: print("\t\t Efficiency of triple events = ", round(p_single**3+p_single2**3,5))
991
- # else:
992
- # p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
993
- # p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
994
- # efficiency_S.append(1-p_nosingle**3)
995
- # efficiency_T.append(p_single**3)
996
- # efficiency_D.append(3*(p_single)**2-2*efficiency_T[-1])
997
- # efficiency_D2.append(p_single**2)
998
- # if Display: print(f"\n\t COUNTING--Sym \n\t\t Free parameter = {L} keV-1 \n\t Summary of TDCR measurement (prompt)")
999
- # if Display: print("\t\t Efficiency of single events = ", round(efficiency_S[-1],5))
1000
- # if Display: print("\t\t Efficiency of double events = ", round(efficiency_D[-1],5))
1001
- # if Display: print("\t\t Efficiency of triple events = ", round(efficiency_T[-1],5))
1002
-
1003
- # elif mode2=="asym":
1004
- # if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
1005
- # pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1006
- # pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
1007
- # pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1008
- # pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
1009
- # pC_nosingle = np.exp(-L[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1010
- # pC_single = 1-pC_nosingle # probability to have at least 1 electrons in a PMT
1011
-
1012
- # pA_nosingle2 = np.exp(-L[0]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
1013
- # pA_single2 = 1-pA_nosingle2 # probability to have at least 1 electrons in a PMT
1014
- # pB_nosingle2 = np.exp(-L[1]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
1015
- # pB_single2 = 1-pB_nosingle2 # probability to have at least 1 electrons in a PMT
1016
- # pC_nosingle2 = np.exp(-L[2]*np.sum(np.asarray(e_quenching2))/3) # probability to have 0 electrons in a PMT
1017
- # pC_single2 = 1-pC_nosingle2 # probability to have at least 1 electrons in a PMT
1018
-
1019
- # efficiency_A2.append(pA_single+pA_single2)
1020
- # efficiency_B2.append(pB_single+pB_single2)
1021
- # efficiency_AB.append(pA_single*pB_single+pA_single2*pB_single2)
1022
- # efficiency_BC.append(pB_single*pC_single+pB_single2*pC_single2)
1023
- # efficiency_AC.append(pA_single*pC_single+pA_single2*pC_single2)
1024
- # efficiency_T.append(pA_single*pB_single*pC_single+pA_single2*pB_single2*pC_single2)
1025
- # efficiency_D.append(pA_single*pB_single+pB_single*pC_single+pA_single*pC_single-2*pA_single*pB_single*pC_single+(pA_single2*pB_single2+pB_single2*pC_single2+pA_single2*pC_single2-2*pA_single2*pB_single2*pC_single2))
1026
- # #efficiency_S.append(pA_single+pB_single+pC_single-pA_single*pB_single+pB_single*pC_single+pA_single*pC_single-2*pA_single*pB_single*pC_single-pA_single*pB_single*pC_single+(pA_single2+pB_single2+pC_single2-pA_single2*pB_single2+pB_single2*pC_single2+pA_single2*pC_single2-2*pA_single2*pB_single2*pC_single2-pA_single2*pB_single2*pC_single2))
1027
- # efficiency_S.append(1-pA_nosingle*pB_nosingle*pC_nosingle+1-pA_nosingle2*pB_nosingle2*pC_nosingle2)
1028
- # efficiency_D2.append(pA_single*pB_single+pA_single2*pB_single2)
1029
-
1030
-
1031
-
1032
- # if Display: print(f"\n\t COUNTING--Asym \n\t\t Free parameters (A,B,C) = {L[0]},{L[1]},{L[2]} keV-1 \n\t Summary of TDCR measurement (prompt)")
1033
- # #if Display: print("\t Summary of TDCR measurement (prompt)")
1034
- # if Display: print("\t\t Efficiency of single events: ", round(pA_single+pB_single+pC_single-pA_single*pB_single+pB_single*pC_single+pA_single*pC_single-2*pA_single*pB_single*pC_single-pA_single*pB_single*pC_single,5))
1035
- # if Display: print("\t\t Efficiency of double events: ", round(pA_single*pB_single+pB_single*pC_single+pA_single*pC_single-2*pA_single*pB_single*pC_single,5))
1036
- # if Display: print("\t\t Efficiency of triple events: ", round(pA_single*pB_single*pC_single,5))
1037
- # if Display: print("\t Summary of TDCR measurement (delayed)")
1038
- # if Display: print("\t\t Efficiency of single events: ", round(pA_single2+pB_single2+pC_single2-pA_single2*pB_single2+pB_single2*pC_single2+pA_single2*pC_single2-2*pA_single2*pB_single2*pC_single2-pA_single2*pB_single2*pC_single2,5))
1039
- # if Display: print("\t\t Efficiency of double events: ", round(pA_single2*pB_single2+pB_single2*pC_single2+pA_single2*pC_single2-2*pA_single2*pB_single2*pC_single2,5))
1040
- # if Display: print("\t\t Efficiency of triple events: ", round(efficiency_S[-1],5))
1041
- # else:
1042
- # pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1043
- # pA_single = 1-pA_nosingle # probability to have at least 1 electrons in a PMT
1044
- # pB_nosingle = np.exp(-L[1]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1045
- # pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
1046
- # pC_nosingle = np.exp(-L[2]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
1047
- # pC_single = 1-pC_nosingle # probability to have at least 1 electrons in a PMT
1048
-
1049
- # efficiency_A2.append(pA_single)
1050
- # efficiency_B2.append(pB_single)
1051
- # efficiency_AB.append(pA_single*pB_single)
1052
- # efficiency_BC.append(pB_single*pC_single)
1053
- # efficiency_AC.append(pA_single*pC_single)
1054
- # efficiency_T.append(pA_single*pB_single*pC_single)
1055
- # efficiency_D.append(efficiency_AB[-1]+efficiency_BC[-1]+efficiency_AC[-1]-2*efficiency_T[-1])
1056
- # efficiency_S.append(1-pA_nosingle*pB_nosingle*pC_nosingle)
1057
- # efficiency_D2.append(pA_single*pB_single)
1058
- # if Display: print(f"\n\t COUNTING--Asym \n\t\t Free parameters (A,B,C) = {L[0]},{L[1]},{L[2]} keV-1 \n\t Summary of TDCR measurement (prompt)")
1059
- # if Display: print("\t\t Free parameter PMT A: ", L[0], "keV-1")
1060
- # if Display: print("\t\t Free parameter PMT B: ", L[1], "keV-1")
1061
- # if Display: print("\t\t Free parameter PMT C: ", L[2], "keV-1")
1062
- # if Display: print("\t\t Efficiency of single events: ", round(efficiency_S[-1],5))
1063
- # if Display: print("\t\t Efficiency of double events: ", round(efficiency_D[-1],5))
1064
- # if Display: print("\t\t Efficiency of triple events: ", round(efficiency_T[-1],5))
960
+
1065
961
 
1066
962
  """
1067
963
  ==========================================================
@@ -1070,9 +966,9 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
1070
966
  """
1071
967
  if record:
1072
968
  with open(recfile4, "a") as file:
1073
- if mode2=="sym":
969
+ if symm:
1074
970
  file.write(f"{idec} {efficiency_S[-1]} {efficiency_D[-1]} {efficiency_T[-1]}\n")
1075
- elif mode2=="asym":
971
+ else:
1076
972
  file.write(f"{idec} {efficiency_S[-1]} {efficiency_D[-1]} {efficiency_T[-1]} {efficiency_AB[-1]} {efficiency_BC[-1]} {efficiency_AC[-1]}\n")
1077
973
 
1078
974
  '''
@@ -1080,92 +976,174 @@ def TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=Fals
1080
976
  VI. CALCULATION OF THE FINAL ESTIMATORS
1081
977
  ====================
1082
978
  '''
1083
- mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_D2, std_efficiency_D2 = tl.efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_D2,N)
1084
-
1085
- # mean_efficiency_T = np.mean(efficiency_T) # average
1086
- # std_efficiency_T = np.std(efficiency_T)/np.sqrt(N) # standard deviation
1087
- # std_efficiency_T = np.sqrt(std_efficiency_T**2+1e-8) # combined with uncertainty due to quenching calculation
1088
- # mean_efficiency_D = np.mean(efficiency_D)
1089
- # std_efficiency_D = np.std(efficiency_D)/np.sqrt(N)
1090
- # std_efficiency_D = np.sqrt(std_efficiency_D**2+1e-8)
1091
- # mean_efficiency_D2 = np.mean(efficiency_D2)
1092
- # std_efficiency_D2 = np.std(efficiency_D2)/np.sqrt(N)
1093
- # std_efficiency_D2 = np.sqrt(std_efficiency_D2**2+1e-8)
1094
- # mean_efficiency_S = np.mean(efficiency_S)
1095
- # std_efficiency_S = np.std(efficiency_S)/np.sqrt(N)
1096
- # std_efficiency_S = np.sqrt(std_efficiency_S**2+1e-8)
1097
-
1098
- if mode2=="sym":
1099
- TDCR_calcul = mean_efficiency_T/mean_efficiency_D
1100
- elif mode2=="asym":
1101
- mean_efficiency_AB = np.mean(efficiency_AB)
1102
- std_efficiency_AB = np.std(efficiency_AB)/np.sqrt(N)
1103
- mean_efficiency_BC = np.mean(efficiency_BC)
1104
- std_efficiency_BC = np.std(efficiency_BC)/np.sqrt(N)
1105
- mean_efficiency_AC = np.mean(efficiency_AC)
1106
- std_efficiency_AC = np.std(efficiency_AC)/np.sqrt(N)
1107
- TDCR_calcul = mean_efficiency_T/mean_efficiency_D
1108
- TABmodel = mean_efficiency_T/mean_efficiency_AB
1109
- TBCmodel = mean_efficiency_T/mean_efficiency_BC
1110
- TACmodel = mean_efficiency_T/mean_efficiency_AC
1111
-
1112
- if mode2=="sym":
1113
- res=(TDCR_calcul-TD)**2
1114
- elif mode2=="asym":
1115
- res=(TAB-TABmodel)**2+(TBC-TBCmodel)**2+(TAC-TACmodel)**2
1116
-
1117
- if mode == "res":
1118
- return res
979
+ mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_AB, std_efficiency_AB, mean_efficiency_BC, std_efficiency_BC, mean_efficiency_AC, std_efficiency_AC, mean_efficiency_D2, std_efficiency_D2 = tl.efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_AB, efficiency_BC, efficiency_AC, efficiency_D2, N)
980
+
1119
981
  if mode == "eff":
1120
- # if N<200:
1121
- # print("Warning. too low number of MC trials - inaccurate estimation")
1122
- # if syst == "TDCR":
1123
- # return mean_efficiency_S, 1, mean_efficiency_D, 1, mean_efficiency_T, 1
1124
- # elif syst =="CN":
1125
- # return mean_efficiency_D2, 1
1126
- # else:
1127
- return mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_D2, std_efficiency_D2
982
+ return mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_AB, std_efficiency_AB, mean_efficiency_BC, std_efficiency_BC, mean_efficiency_AC, std_efficiency_AC, mean_efficiency_D2, std_efficiency_D2
1128
983
  if mode =="dis":
1129
984
  return efficiency_S, efficiency_D, efficiency_T, efficiency_D2
1130
985
 
1131
- # L = 1
1132
- # TD = 0.977667386529166
1133
- # TAB = 0.992232838598821
1134
- # TBC = 0.992343419459002
1135
- # TAC = 0.99275350064608
1136
- # Rad="H-3"
1137
- # pmf_1="1"
1138
- # N = 100
1139
- # kB =1.0e-5
1140
- # V = 10
1141
- # mode = "eff"
1142
- # mode2 = "sym"
986
+ def objectFct(L, TD, Rad, pmf_1, N, kB, V):
987
+ """
988
+ Objective function to minimize in order the estimate the detection efficiencies based on the measurements.
1143
989
 
1144
- # out = TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=False, barp=False, Smodel=False, uncData=False)
990
+ Parameters
991
+ ----------
992
+ L : float or tuple
993
+ If L is float, then L is the global free parameter. If L is tuple, then L is a triplet of free parameters. unit keV-1
994
+ TD : float or tuple
995
+ measurements. If TD is float, then TD is the measured TDCR parameter. If TD is tuple, then TD must contain the global TDCR parameter followed by specific ones (T/B, T/AB, T/BC, T/AC)
996
+ Rad : string
997
+ List of radionuclides (eg. "H-3, Co-60").
998
+ pmf_1 : string
999
+ list of probability of each radionuclide (eg. "0.8, 0.2").
1000
+ N : integer
1001
+ Number of Monte-Carlo trials. recommanded N>10000 (see JCGM 101). Not applied in the case of the analytical model.
1002
+ kB : float
1003
+ Birks constant in cm/keV.
1004
+ V : float
1005
+ volume of the scintillator in ml.
1006
+
1007
+ Returns
1008
+ -------
1009
+ res : float
1010
+ The residual value.
1011
+
1012
+ """
1013
+
1014
+ if isinstance(TD, (tuple, list)):
1015
+ symm = False
1016
+ else:
1017
+ symm = True
1018
+
1019
+ if symm:
1020
+ eff_model = TDCRPy(L, Rad, pmf_1, N, kB, V, readRecHist = True)
1021
+ TDCR_calcul = eff_model[4]/eff_model[2]
1022
+ res=(TDCR_calcul-TD)**2
1023
+ else:
1024
+ eff_model = TDCRPy(L, Rad, pmf_1, N, kB, V, readRecHist = True)
1025
+ TAB_calcul = eff_model[4]/eff_model[6]
1026
+ TBC_calcul = eff_model[4]/eff_model[8]
1027
+ TAC_calcul = eff_model[4]/eff_model[10]
1028
+ res=(TD[1]-TAB_calcul)**2+(TD[2]-TBC_calcul)**2+(TD[3]-TAC_calcul)**2
1029
+
1030
+ return res
1031
+
1032
+ def eff(TD, Rad, pmf_1, kB, V, N=10000, L=1, maxiter=20, xatol=1e-7, disp=False):
1033
+ """
1034
+ Caclulation of the efficiency of a TDCR system based on the model TDCRPy.
1035
+ This function includes optimization procedures from scipy.
1036
+
1037
+ Parameters
1038
+ ----------
1039
+ TD : float or tuple
1040
+ measurements. If TD is float, then TD is the measured TDCR parameter. If TD is tuple, then TD must contain the global TDCR parameter followed by specific ones (T/B, T/AB, T/BC, T/AC)
1041
+ Rad : string
1042
+ List of radionuclides (eg. "H-3, Co-60").
1043
+ pmf_1 : string
1044
+ list of probability of each radionuclide (eg. "0.8, 0.2").
1045
+ kB : float
1046
+ Birks constant in cm/keV.
1047
+ V : float
1048
+ volume of the scintillator in ml.
1049
+ N : interger, optional
1050
+ number of Monte-Carlo trials. The default is 10000.
1051
+ maxiter : interger, optional
1052
+ maximum number of iterations of the optimization procedures
1053
+ xatol : float
1054
+ convergence parameter of the Nelder Mead optimisation
1055
+ disp : Boolean
1056
+ to display detailed results of the procedure. Default is False.
1057
+
1058
+ Returns
1059
+ -------
1060
+ L0 : float
1061
+ global free parameter.
1062
+ L : tuple
1063
+ free parameters (relevant for the asymetric model).
1064
+ eff_S : float
1065
+ counting efficiency of single events.
1066
+ u_eff_S : float
1067
+ standard uncertainty of eff_S.
1068
+ eff_D : float
1069
+ counting efficiency of double coincidences.
1070
+ u_eff_D : float
1071
+ standard uncertainty of eff_D.
1072
+ eff_T : float
1073
+ counting efficiency of triple coincidences.
1074
+ u_eff_T : float
1075
+ standard uncertainty of eff_T.
1076
+ eff_AB : float
1077
+ counting efficiency of coincidences AB.
1078
+ u_eff_AB : float
1079
+ standard uncertainty of eff_AB.
1080
+ eff_BC : float
1081
+ counting efficiency of coincidences BC.
1082
+ u_eff_BC : float
1083
+ standard uncertainty of eff_BC.
1084
+ eff_AC : float
1085
+ counting efficiency of coincidences AC.
1086
+ u_eff_AC : float
1087
+ standard uncertainty of eff_AC.
1088
+ eff_D : float
1089
+ counting efficiency of double coincidences in C/N configuation (not relevant).
1090
+ u_eff_D : float
1091
+ standard uncertainty of eff_D in C/N configuation (not relevant).
1092
+
1093
+ """
1094
+ if isinstance(TD, (tuple, list)):
1095
+ symm = False
1096
+ else:
1097
+ symm = True
1098
+
1099
+ 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})
1100
+ 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})
1101
+ L0=r.x
1102
+ L=(L0, L0, L0)
1103
+ print(f"global free parameter = {L0} keV-1")
1104
+
1105
+ if not symm:
1106
+ r=opt.minimize(objectFct, L, args=(TD, Rad, pmf_1, N, kB, V), method='nelder-mead',options={'xatol': xatol, 'disp': disp, 'maxiter':maxiter})
1107
+ L=r.x
1108
+ print(f"free parameters = {L} keV-1")
1145
1109
 
1146
- # print(out)
1110
+ if symm: out=TDCRPy(L0, Rad, pmf_1, N, kB, V, readRecHist = True)
1111
+ else: out=TDCRPy(L, Rad, pmf_1, N, kB, V, readRecHist = True)
1112
+ eff_S = out[0]
1113
+ u_eff_S = out[1]
1114
+ eff_D = out[2]
1115
+ u_eff_D = out[3]
1116
+ eff_T = out[4]
1117
+ u_eff_T = out[5]
1118
+ eff_AB = out[6]
1119
+ u_eff_AB = out[7]
1120
+ eff_BC = out[8]
1121
+ u_eff_BC = out[9]
1122
+ eff_AC = out[10]
1123
+ u_eff_AC = out[11]
1124
+ eff_D2 = out[12]
1125
+ u_eff_D2 = out[13]
1126
+
1127
+ 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
1147
1128
 
1148
- # L = 1
1149
- # TD = 0.977667386529166
1150
- # TAB = 0.992232838598821
1151
- # TBC = 0.992343419459002
1152
- # TAC = 0.99275350064608
1129
+
1130
+ # # L = 1
1131
+ # # L = (1.1, 1.05, 1.15)
1132
+ # # TD = 0.977667386529166
1133
+ # TD = (0.977667386529166, 0.992232838598821, 0.992343419459002, 0.99275350064608)
1134
+ # # TD = (0.977667386529166, 0.995232838598821, 0.990343419459002, 0.99275350064608)
1153
1135
  # Rad="Co-60"
1154
1136
  # pmf_1="1"
1155
- # N = 5
1137
+ # N = 1000
1156
1138
  # kB =1.0e-5
1157
1139
  # V = 10
1158
1140
  # mode = "eff"
1159
- # mode2 = "sym"
1160
-
1161
- # # # out = TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display=True, barp=False,uncData=False)
1162
- # # # print("TDCR", out[4]/out[2])
1163
- # # # print("Eff D", out[2])
1164
1141
 
1165
1142
 
1166
- # # out = TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, 20, kB, V, mode, mode2, Display=True, barp=False, Smodel=True, syst = "TDCR", record = "phf1", uncData=False)
1143
+ # # out = TDCRPy(L, Rad, pmf_1, N, kB, V, Display = False, record = True, readRecHist = False)
1144
+ # # print("result", out)
1145
+ # # out = TDCRPy(L, Rad, pmf_1, N, kB, V, Display = False, record = False, readRecHist = True)
1146
+ # # print("result", out)
1167
1147
 
1168
- # out = TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display = False, record = True, readRecHist = False)
1169
- # print("result", out)
1170
- # out = TDCRPy(L, TD, TAB, TBC, TAC, Rad, pmf_1, N, kB, V, mode, mode2, Display = False, record = False, readRecHist = True)
1171
- # print("result", out)
1148
+ # out = eff(TD, Rad, pmf_1, kB, V, N=1000, L=1, maxiter=20, xatol=1e-7)
1149
+ # print(out)
tdcrpy/TDCR_model_lib.py CHANGED
@@ -2624,7 +2624,7 @@ def relaxation_atom_ph(lacune,element,v):
2624
2624
 
2625
2625
 
2626
2626
 
2627
- def modelAnalytical(L,TD,TAB,TBC,TAC,rad,kB,V,mode,mode2,ne):
2627
+ def modelAnalytical(L,TD,TAB,TBC,TAC,rad,kB,V,mode,symm,ne):
2628
2628
  """
2629
2629
  TDCR analytical model that is used for pure beta emitting radionuclides
2630
2630
 
@@ -2648,8 +2648,8 @@ def modelAnalytical(L,TD,TAB,TBC,TAC,rad,kB,V,mode,mode2,ne):
2648
2648
  volume of the scintillator in ml. run only for 10 ml
2649
2649
  mode : string
2650
2650
  "res" to return the residual, "eff" to return efficiencies.
2651
- mode2 : string
2652
- "sym" for symetrical model, "asym" for symetrical model.
2651
+ symm : boolean
2652
+ "True" for symetrical model, "False" for symetrical model.
2653
2653
  nE : integer
2654
2654
  Number of bins for the quenching function.
2655
2655
 
@@ -2675,14 +2675,13 @@ def modelAnalytical(L,TD,TAB,TBC,TAC,rad,kB,V,mode,mode2,ne):
2675
2675
  em[i] = Em_e(ei*1e3,ei*1e3,kB*1e3,ne)*1e-3
2676
2676
 
2677
2677
 
2678
- if mode2=="sym":
2678
+ if symm:
2679
2679
  eff_S = sum(p*(1-np.exp(-L*em/3)))
2680
2680
  eff_T = sum(p*(1-np.exp(-L*em/3))**3)
2681
2681
  eff_D = sum(p*(3*(1-np.exp(-L*em/3))**2-2*(1-np.exp(-L*em/3))**3))
2682
2682
  TDCR_calcul=eff_T/eff_D
2683
2683
  res=(TDCR_calcul-TD)**2
2684
-
2685
- if mode2=="asym":
2684
+ else:
2686
2685
  # eff_A = sum(p*(1-np.exp(-L[0]*em/3)))
2687
2686
  # eff_B = sum(p*(1-np.exp(-L[1]*em/3)))
2688
2687
  # eff_C = sum(p*(1-np.exp(-L[2]*em/3)))
@@ -2830,8 +2829,51 @@ def buildBetaSpectra(rad, V, N, prt=False):
2830
2829
  else: file.write(f"{b}\t{p2[i]}\n")
2831
2830
  print("file written in local")
2832
2831
 
2833
- def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extDT, measTime):
2834
- if mode2=="sym":
2832
+ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, extDT, measTime):
2833
+ """
2834
+ 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
2835
+
2836
+ Parameters
2837
+ ----------
2838
+ L : float or tuple
2839
+ If L is float, then L is the global free parameter. If L is tuple, then L is a triplet of free parameters. unit keV-1
2840
+ e_quenching : list
2841
+ List of quenched deposited energies from prompt particles in keV.
2842
+ e_quenching2 : list
2843
+ List of quenched deposited energies from delayed particles in keV.
2844
+ t1 : float
2845
+ decay time of the delayed transitions in s.
2846
+ evenement : interger
2847
+ number of pulses per decay (prompt (1), prompt + delayed (2)).
2848
+ extDT : float
2849
+ extended dead time of the system in ns.
2850
+ measTime : float
2851
+ measurement time in minutes.
2852
+
2853
+ Returns
2854
+ -------
2855
+ efficiency0_S : float
2856
+ detection probability of single event.
2857
+ efficiency0_D : float
2858
+ detection probability of double coincidences.
2859
+ efficiency0_T : float
2860
+ detection probability of triple coincidences.
2861
+ efficiency0_AB : float
2862
+ detection probability of coincidences between channels A and B.
2863
+ efficiency0_BC : float
2864
+ detection probability of coincidences between channels B and C.
2865
+ efficiency0_AC : float
2866
+ detection probability of coincidences between channels A and C.
2867
+ efficiency0_D2 : float
2868
+ detection probability of coincidences in a C/N system.
2869
+
2870
+ """
2871
+ if isinstance(L, (tuple, list)):
2872
+ symm = False
2873
+ else:
2874
+ symm = True
2875
+
2876
+ if symm:
2835
2877
  # print(evenement !=1, t1 > extDT*1e-6, t1 < measTime*60)
2836
2878
  if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
2837
2879
  # TDCR
@@ -2842,12 +2884,17 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extD
2842
2884
  efficiency0_S = 1-p_nosingle**3+1-p_nosingle2**3
2843
2885
  efficiency0_T = p_single**3+p_single2**3
2844
2886
  efficiency0_D = 3*(p_single)**2-2*p_single**3+(3*(p_single2)**2-2*p_single2**3)
2887
+ efficiency0_AB = (efficiency0_D+2*efficiency0_T)/3
2888
+ efficiency0_BC = efficiency0_AB
2889
+ efficiency0_AC = efficiency0_AB
2845
2890
 
2846
2891
  # CN
2847
2892
  p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2848
2893
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2849
2894
  p_nosingle2 = np.exp(-L*np.sum(np.asarray(e_quenching2))/2) # probability to have 0 electrons in a PMT
2850
2895
  p_single2 = 1-p_nosingle2
2896
+ efficiency0_A2 = p_single+p_single2
2897
+ efficiency0_B2 = efficiency0_A2
2851
2898
  efficiency0_D2 = p_single**2+p_single2**2
2852
2899
  else:
2853
2900
  # TDCR
@@ -2856,14 +2903,19 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extD
2856
2903
  efficiency0_S = 1-p_nosingle**3
2857
2904
  efficiency0_T = p_single**3
2858
2905
  efficiency0_D = 3*(p_single)**2-2*efficiency0_T
2906
+ efficiency0_AB = (efficiency0_D+2*efficiency0_T)/3
2907
+ efficiency0_BC = efficiency0_AB
2908
+ efficiency0_AC = efficiency0_AB
2859
2909
 
2860
2910
  # CN
2861
2911
  p_nosingle = np.exp(-L*np.sum(np.asarray(e_quenching))/2) # probability to have 0 electrons in a PMT
2862
2912
  p_single = 1-p_nosingle # probability to have at least 1 electrons in a PMT
2913
+ efficiency0_A2 = p_single
2914
+ efficiency0_B2 = efficiency0_A2
2863
2915
  efficiency0_D2 = p_single**2
2864
2916
 
2865
2917
 
2866
- elif mode2=="asym":
2918
+ else:
2867
2919
  if evenement !=1 and t1 > extDT*1e-6 and t1 < measTime*60:
2868
2920
  # TDCR
2869
2921
  pA_nosingle = np.exp(-L[0]*np.sum(np.asarray(e_quenching))/3) # probability to have 0 electrons in a PMT
@@ -2928,19 +2980,81 @@ def detectProbabilities(L, e_quenching, e_quenching2, t1, evenement, mode2, extD
2928
2980
  pB_single = 1-pB_nosingle # probability to have at least 1 electrons in a PMT
2929
2981
  efficiency0_D2 = pA_single*pB_single
2930
2982
 
2931
- return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_D2
2983
+ return efficiency0_S, efficiency0_D, efficiency0_T, efficiency0_AB, efficiency0_BC, efficiency0_AC, efficiency0_D2
2932
2984
 
2933
2985
 
2934
- def efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_D2,N):
2935
- mean_efficiency_T = np.mean(efficiency_T) # average
2936
- std_efficiency_T = np.std(efficiency_T)/np.sqrt(N) # standard deviation
2986
+ def efficienciesEstimates(efficiency_S, efficiency_D, efficiency_T, efficiency_AB, efficiency_BC, efficiency_AC, efficiency_D2, N):
2987
+ """
2988
+ Calculate detection efficiencies from list of detection probabilities per decays.
2989
+
2990
+ Parameters
2991
+ ----------
2992
+ efficiency0_S : float
2993
+ detection probability of single event.
2994
+ efficiency0_D : float
2995
+ detection probability of double coincidences.
2996
+ efficiency0_T : float
2997
+ detection probability of triple coincidences.
2998
+ efficiency0_AB : float
2999
+ detection probability of coincidences between channels A and B.
3000
+ efficiency0_BC : float
3001
+ detection probability of coincidences between channels B and C.
3002
+ efficiency0_AC : float
3003
+ detection probability of coincidences between channels A and C.
3004
+ efficiency0_D2 : float
3005
+ detection probability of coincidences in a C/N system.
3006
+ N : interger
3007
+ number of simulated decays.
3008
+
3009
+ Returns
3010
+ -------
3011
+ mean_efficiency_S : float
3012
+ detection efficiency of single event.
3013
+ std_efficiency_S : float
3014
+ standard uncertainty of detection efficiency of single event.
3015
+ mean_efficiency_D : float
3016
+ detection efficiency of double coincidences.
3017
+ std_efficiency_D : float
3018
+ standard uncertainty of detection efficiency of double coincidences.
3019
+ mean_efficiency_T : float
3020
+ detection efficiency of triple coincidences.
3021
+ std_efficiency_T : float
3022
+ standard uncertainty of detection efficiency of triple coincidences.
3023
+ mean_efficiency_AB : float
3024
+ detection efficiency of coincidences between channels A and B.
3025
+ std_efficiency_AB : float
3026
+ standard uncertainty of detection efficiency of coincidences between channels A and B.
3027
+ mean_efficiency_BC : float
3028
+ detection efficiency of coincidences between channels B and C.
3029
+ std_efficiency_BC : float
3030
+ standard uncertainty of Ddetection efficiency of coincidences between channels B and C.
3031
+ mean_efficiency_AC : float
3032
+ detection efficiency of coincidences between channels A and C.
3033
+ std_efficiency_AC : float
3034
+ standard uncertainty of detection efficiency of coincidences between channels A and C.
3035
+ mean_efficiency_D2 : float
3036
+ detection efficiency of coincidences in a C/N system.
3037
+ std_efficiency_D2 : float
3038
+ standard uncertainty of detection efficiency of coincidences in a C/N system.
3039
+
3040
+ """
3041
+ mean_efficiency_S = np.mean(efficiency_S)
3042
+ std_efficiency_S = np.std(efficiency_S)/np.sqrt(N)
2937
3043
  mean_efficiency_D = np.mean(efficiency_D)
2938
3044
  std_efficiency_D = np.std(efficiency_D)/np.sqrt(N)
3045
+ mean_efficiency_T = np.mean(efficiency_T) # average
3046
+ std_efficiency_T = np.std(efficiency_T)/np.sqrt(N) # standard deviation
3047
+ mean_efficiency_AB = np.mean(efficiency_AB)
3048
+ std_efficiency_AB = np.std(efficiency_AB)/np.sqrt(N)
3049
+ mean_efficiency_BC = np.mean(efficiency_BC)
3050
+ std_efficiency_BC = np.std(efficiency_BC)/np.sqrt(N)
3051
+ mean_efficiency_AC = np.mean(efficiency_AC)
3052
+ std_efficiency_AC = np.std(efficiency_AC)/np.sqrt(N)
3053
+
2939
3054
  mean_efficiency_D2 = np.mean(efficiency_D2)
2940
3055
  std_efficiency_D2 = np.std(efficiency_D2)/np.sqrt(N)
2941
- mean_efficiency_S = np.mean(efficiency_S)
2942
- std_efficiency_S = np.std(efficiency_S)/np.sqrt(N)
2943
- return mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_D2, std_efficiency_D2
3056
+
3057
+ return mean_efficiency_S, std_efficiency_S, mean_efficiency_D, std_efficiency_D, mean_efficiency_T, std_efficiency_T, mean_efficiency_AB, std_efficiency_AB, mean_efficiency_BC, std_efficiency_BC, mean_efficiency_AC, std_efficiency_AC, mean_efficiency_D2, std_efficiency_D2
2944
3058
 
2945
3059
 
2946
3060
 
tdcrpy/__init__.py CHANGED
@@ -1,4 +1,3 @@
1
1
  from tdcrpy import TDCRPy
2
2
  from tdcrpy import TDCR_model_lib
3
- from tdcrpy import TDCRoptimize
4
3
  from tdcrpy.test import test_tdcrpy