TDCRPy 2.0.5__py3-none-any.whl → 2.0.7__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-2.0.7.dist-info/METADATA +1630 -0
- {TDCRPy-2.0.5.dist-info → TDCRPy-2.0.7.dist-info}/RECORD +5 -5
- {TDCRPy-2.0.5.dist-info → TDCRPy-2.0.7.dist-info}/WHEEL +1 -1
- TDCRPy-2.0.5.dist-info/METADATA +0 -84
- {TDCRPy-2.0.5.dist-info → TDCRPy-2.0.7.dist-info}/LICENCE.md +0 -0
- {TDCRPy-2.0.5.dist-info → TDCRPy-2.0.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1630 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: TDCRPy
|
|
3
|
+
Version: 2.0.7
|
|
4
|
+
Summary: TDCR model
|
|
5
|
+
Home-page: https://pypi.org/project/TDCRPy/
|
|
6
|
+
Author: RomainCoulon (Romain Coulon)
|
|
7
|
+
Author-email: <romain.coulon@bipm.org>
|
|
8
|
+
Project-URL: Documentation, https://github.com/RomainCoulon/TDCRPy/
|
|
9
|
+
Keywords: Python,TDCR,Monte-Carlo,radionuclide,scintillation,counting
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Natural Language :: French
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Operating System :: Unix
|
|
17
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENCE.md
|
|
23
|
+
Requires-Dist: numpy
|
|
24
|
+
Requires-Dist: tqdm
|
|
25
|
+
Requires-Dist: setuptools
|
|
26
|
+
Requires-Dist: scipy
|
|
27
|
+
Requires-Dist: configparser
|
|
28
|
+
Requires-Dist: importlib.resources
|
|
29
|
+
Requires-Dist: matplotlib
|
|
30
|
+
|
|
31
|
+
# 1. About TDCRPy
|
|
32
|
+
|
|
33
|
+
`TDCRPy` is a Python code to estimate detection efficiencies of liquid scintillation counters (TDCR or CIEMAT/NIST).
|
|
34
|
+
The calculation is based on a photo-physical stochastic model allowing to adress complexe decay schemes and radionuclide mixtures.
|
|
35
|
+
|
|
36
|
+
The code is developped and maintained by the BIPM (MIT license).
|
|
37
|
+
|
|
38
|
+
Technical details can be found in
|
|
39
|
+
|
|
40
|
+
http://dx.doi.org/10.13140/RG.2.2.15682.80321
|
|
41
|
+
|
|
42
|
+
## 1.1 Installation
|
|
43
|
+
|
|
44
|
+
`TDCRPy` requires that the following packages are installed in your `Python` environement.
|
|
45
|
+
|
|
46
|
+
```shell
|
|
47
|
+
pip install importlib.resources configparser numpy tqdm setuptools scipy
|
|
48
|
+
```
|
|
49
|
+
or in `conda` environement:
|
|
50
|
+
|
|
51
|
+
```shell
|
|
52
|
+
conda install importlib.resources configparser numpy tqdm setuptools scipy
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then, `TDCRPy` can be installed.
|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
pip install TDCRPy
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
To obtain the last version.
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
pip install TDCRPy --upgrade
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The module can be imported in your Python code such as.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import tdcrpy
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 1.2 Test
|
|
74
|
+
|
|
75
|
+
To run the unit tests of the package:
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
python -m unittest tdcrpy.test.test_tdcrpy
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
or (using the coverage package)
|
|
82
|
+
|
|
83
|
+
```shell
|
|
84
|
+
coverage run -m unittest tdcrpy.test.test_tdcrpy
|
|
85
|
+
coverage report -m
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
# 2. Quick start with the TDCRPy code
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
import tdcrpy
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 2.1 Symmetric PMTs
|
|
95
|
+
|
|
96
|
+
### 2.1.1 Estimation of detection efficiencies given the free parameter
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
mode = "eff" # ask for efficiency calculation
|
|
101
|
+
L = 1.2 # free parameter in keV-1
|
|
102
|
+
Rad="Co-60" # radionuclide
|
|
103
|
+
pmf_1="1" # relative fraction of the radionulide
|
|
104
|
+
N = 1000 # number of Monte Carlo trials
|
|
105
|
+
kB =1.0e-5 # Birks constant in cm keV-1
|
|
106
|
+
V = 10 # volume of scintillator in mL
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
result = tdcrpy.TDCRPy.TDCRPy(L, Rad, pmf_1, N, kB, V, mode)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
print(f"efficiency S = {round(result[0],4)} +/- {round(result[1],4)}")
|
|
117
|
+
print(f"efficiency D = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
118
|
+
print(f"efficiency T = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
119
|
+
print(f"efficiency D (C/N system) = {round(result[12],4)} +/- {round(result[13],4)}")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
efficiency S = 0.9859 +/- 0.0031
|
|
123
|
+
efficiency D = 0.9738 +/- 0.0043
|
|
124
|
+
efficiency T = 0.9527 +/- 0.0057
|
|
125
|
+
efficiency D (C/N system) = 0.9702 +/- 0.0045
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
### 2.1.2 Estimation of detection efficiencies given the measured TDCR parameter
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
TD = 0.977667386529166 # TDCR parameter
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
result = tdcrpy.TDCRPy.eff(TD, Rad, pmf_1, kB, V)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
global free parameter = 1.1991314352332345 keV-1
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
print(f"free parameter = {round(result[0],4)} keV-1")
|
|
146
|
+
print(f"efficiency S = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
147
|
+
print(f"efficiency D = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
148
|
+
print(f"efficiency T = {round(result[6],4)} +/- {round(result[7],4)}")
|
|
149
|
+
print(f"efficiency D (C/N system) = {round(result[14],4)} +/- {round(result[15],4)}")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
free parameter = 1.1991 keV-1
|
|
153
|
+
efficiency S = 0.9858 +/- 0.001
|
|
154
|
+
efficiency D = 0.973 +/- 0.0014
|
|
155
|
+
efficiency T = 0.9512 +/- 0.0018
|
|
156
|
+
efficiency D (C/N system) = 0.9692 +/- 0.0014
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
## 2.2 Asymmetric PMTs
|
|
160
|
+
|
|
161
|
+
### 2.2.1 Estimation of detection efficiencies given the free parameters
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
mode = "eff" # ask for efficiency calculation
|
|
166
|
+
L = (1.1, 1.3, 1.2) # free parameter in keV-1
|
|
167
|
+
Rad="Co-60" # radionuclide
|
|
168
|
+
pmf_1="1" # relative fraction of the radionulide
|
|
169
|
+
N = 1000 # number of Monte Carlo trials
|
|
170
|
+
kB =1.0e-5 # Birks constant in cm keV-1
|
|
171
|
+
V = 10 # volume of scintillator in mL
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
result = tdcrpy.TDCRPy.TDCRPy(L, Rad, pmf_1, N, kB, V)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
print(f"efficiency S = {round(result[0],4)} +/- {round(result[1],4)}")
|
|
182
|
+
print(f"efficiency D = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
183
|
+
print(f"efficiency T = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
184
|
+
print(f"efficiency AB = {round(result[6],4)} +/- {round(result[7],4)}")
|
|
185
|
+
print(f"efficiency BC = {round(result[8],4)} +/- {round(result[9],4)}")
|
|
186
|
+
print(f"efficiency AC = {round(result[10],4)} +/- {round(result[11],4)}")
|
|
187
|
+
print(f"efficiency D (C/N system) = {round(result[12],4)} +/- {round(result[13],4)}")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
efficiency S = 0.9904 +/- 0.0024
|
|
191
|
+
efficiency D = 0.9803 +/- 0.0037
|
|
192
|
+
efficiency T = 0.9625 +/- 0.005
|
|
193
|
+
efficiency AB = 0.9684 +/- 0.0045
|
|
194
|
+
efficiency BC = 0.9696 +/- 0.0044
|
|
195
|
+
efficiency AC = 0.9674 +/- 0.0046
|
|
196
|
+
efficiency D (C/N system) = 0.9772 +/- 0.0039
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
### 2.2.2 Estimation of detection efficiencies given the measured TDCR parameters
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
TD = [0.977667386529166, 0.992232838598821, 0.992343419459002, 0.99275350064608]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
result = tdcrpy.TDCRPy.eff(TD, Rad, pmf_1, kB, V)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
global free parameter = 1.2369501044018718 keV-1
|
|
212
|
+
free parameters = [1.2369501 1.2369501 1.2369501] keV-1
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
print(f"Global free parameter = {round(result[0],4)} keV-1")
|
|
218
|
+
print(f"free parameter of PMT A = {round(result[1][0],4)} keV-1")
|
|
219
|
+
print(f"free parameter of PMT B = {round(result[1][1],4)} keV-1")
|
|
220
|
+
print(f"free parameter of PMT C = {round(result[1][2],4)} keV-1")
|
|
221
|
+
print(f"efficiency S = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
222
|
+
print(f"efficiency D = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
223
|
+
print(f"efficiency T = {round(result[6],4)} +/- {round(result[7],4)}")
|
|
224
|
+
print(f"efficiency AB = {round(result[8],4)} +/- {round(result[9],4)}")
|
|
225
|
+
print(f"efficiency BC = {round(result[10],4)} +/- {round(result[11],4)}")
|
|
226
|
+
print(f"efficiency AC = {round(result[12],4)} +/- {round(result[13],4)}")
|
|
227
|
+
print(f"efficiency D (C/N system) = {round(result[14],4)} +/- {round(result[15],4)}")
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Global free parameter = 1.237 keV-1
|
|
231
|
+
free parameter of PMT A = 1.237 keV-1
|
|
232
|
+
free parameter of PMT B = 1.237 keV-1
|
|
233
|
+
free parameter of PMT C = 1.237 keV-1
|
|
234
|
+
efficiency S = 0.9872 +/- 0.0009
|
|
235
|
+
efficiency D = 0.9751 +/- 0.0013
|
|
236
|
+
efficiency T = 0.9533 +/- 0.0018
|
|
237
|
+
efficiency AB = 0.9606 +/- 0.0016
|
|
238
|
+
efficiency BC = 0.9606 +/- 0.0016
|
|
239
|
+
efficiency AC = 0.9606 +/- 0.0016
|
|
240
|
+
efficiency D (C/N system) = 0.9714 +/- 0.0014
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
## 2.3 Radionuclide mixture
|
|
244
|
+
|
|
245
|
+
### 2.3.1 Estimation of detection efficiencies given the free parameter
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
mode = "eff" # ask for efficiency calculation
|
|
250
|
+
mode2 = "sym" # specify that symmetric PMTs is considered
|
|
251
|
+
L = 1.2 # free parameter in keV-1
|
|
252
|
+
Rad="Co-60, H-3" # radionuclides
|
|
253
|
+
pmf_1="0.8, 0.2" # relatives fractions of the radionulides
|
|
254
|
+
N = 1000 # number of Monte Carlo trials
|
|
255
|
+
kB =1.0e-5 # Birks constant in cm keV-1
|
|
256
|
+
V = 10 # volume of scintillator in mL
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
result = tdcrpy.TDCRPy.TDCRPy(L, Rad, pmf_1, N, kB, V)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
print(f"efficiency S = {round(result[0],4)} +/- {round(result[1],4)}")
|
|
267
|
+
print(f"efficiency D = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
268
|
+
print(f"efficiency T = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
269
|
+
print(f"efficiency D (C/N system) = {round(result[12],4)} +/- {round(result[13],4)}")
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
efficiency S = 0.9622 +/- 0.0045
|
|
273
|
+
efficiency D = 0.9163 +/- 0.007
|
|
274
|
+
efficiency T = 0.8482 +/- 0.0096
|
|
275
|
+
efficiency D (C/N system) = 0.9037 +/- 0.0074
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
### 2.3.2 Estimation of detection efficiencies given the measured TDCR parameter
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
TD = 0.977667386529166 # TDCR parameter
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
result = tdcrpy.TDCRPy.eff(TD, Rad, pmf_1, kB, V)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
global free parameter = 4.999573818598962 keV-1
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
print(f"free parameter = {round(result[0],4)} keV-1")
|
|
296
|
+
print(f"efficiency S = {round(result[2],4)} +/- {round(result[3],4)}")
|
|
297
|
+
print(f"efficiency D = {round(result[4],4)} +/- {round(result[5],4)}")
|
|
298
|
+
print(f"efficiency T = {round(result[6],4)} +/- {round(result[7],4)}")
|
|
299
|
+
print(f"efficiency D (C/N system) = {round(result[14],4)} +/- {round(result[15],4)}")
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
free parameter = 4.9996 keV-1
|
|
303
|
+
efficiency S = 0.9835 +/- 0.001
|
|
304
|
+
efficiency D = 0.9677 +/- 0.0015
|
|
305
|
+
efficiency T = 0.9397 +/- 0.002
|
|
306
|
+
efficiency D (C/N system) = 0.9629 +/- 0.0016
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
# 3. Advanced settings
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
import tdcrpy as td
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## 3.1 Read the parameters
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
print("\nparameters in a list: ", td.TDCR_model_lib.readParameters(disp=True))
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
number of integration bins for electrons = 1000
|
|
328
|
+
number of integration bins for alpha = 1000
|
|
329
|
+
density = 0.96 g/cm3
|
|
330
|
+
Z = 5.2
|
|
331
|
+
A = 11.04
|
|
332
|
+
depth of spline interp. = 5
|
|
333
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
334
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
335
|
+
activation of the micelle correction = False
|
|
336
|
+
diameter of micelle = 2.0 nm
|
|
337
|
+
acqueous fraction = 0.1
|
|
338
|
+
coincidence resolving time = 50 ns
|
|
339
|
+
extended dead time = 10 µs
|
|
340
|
+
measurement time = 20 min
|
|
341
|
+
|
|
342
|
+
parameters in a list: (1000, 1000, 0.96, 5.2, 11.04, 5, 100.0, 1.5, 2.0, 0.1, 50, 10, 20, False)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
## 3.2 Change energy binning the quenching function of electrons
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
td.TDCR_model_lib.modifynE_electron(100)
|
|
350
|
+
print("New configuration:")
|
|
351
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
352
|
+
# back to the default value
|
|
353
|
+
td.TDCR_model_lib.modifynE_electron(1000)
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
New configuration:
|
|
357
|
+
number of integration bins for electrons = 100
|
|
358
|
+
number of integration bins for alpha = 1000
|
|
359
|
+
density = 0.96 g/cm3
|
|
360
|
+
Z = 5.2
|
|
361
|
+
A = 11.04
|
|
362
|
+
depth of spline interp. = 5
|
|
363
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
364
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
365
|
+
activation of the micelle correction = False
|
|
366
|
+
diameter of micelle = 2.0 nm
|
|
367
|
+
acqueous fraction = 0.1
|
|
368
|
+
coincidence resolving time = 50 ns
|
|
369
|
+
extended dead time = 10 µs
|
|
370
|
+
measurement time = 20 min
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
## 3.3 Change energy binning the quenching function of alpha particles
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
td.TDCR_model_lib.modifynE_alpha(100)
|
|
378
|
+
print("New configuration:")
|
|
379
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
380
|
+
# back to the default value
|
|
381
|
+
td.TDCR_model_lib.modifynE_alpha(1000)
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
New configuration:
|
|
385
|
+
number of integration bins for electrons = 1000
|
|
386
|
+
number of integration bins for alpha = 100
|
|
387
|
+
density = 0.96 g/cm3
|
|
388
|
+
Z = 5.2
|
|
389
|
+
A = 11.04
|
|
390
|
+
depth of spline interp. = 5
|
|
391
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
392
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
393
|
+
activation of the micelle correction = False
|
|
394
|
+
diameter of micelle = 2.0 nm
|
|
395
|
+
acqueous fraction = 0.1
|
|
396
|
+
coincidence resolving time = 50 ns
|
|
397
|
+
extended dead time = 10 µs
|
|
398
|
+
measurement time = 20 min
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
## 3.4 Change the density (in g/cm3) of the LS source
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
```python
|
|
405
|
+
td.TDCR_model_lib.modifyDensity(1.02)
|
|
406
|
+
print("New configuration:")
|
|
407
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
408
|
+
# back to the default value
|
|
409
|
+
td.TDCR_model_lib.modifyDensity(0.96)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
New configuration:
|
|
413
|
+
number of integration bins for electrons = 1000
|
|
414
|
+
number of integration bins for alpha = 1000
|
|
415
|
+
density = 1.02 g/cm3
|
|
416
|
+
Z = 5.2
|
|
417
|
+
A = 11.04
|
|
418
|
+
depth of spline interp. = 5
|
|
419
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
420
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
421
|
+
activation of the micelle correction = False
|
|
422
|
+
diameter of micelle = 2.0 nm
|
|
423
|
+
acqueous fraction = 0.1
|
|
424
|
+
coincidence resolving time = 50 ns
|
|
425
|
+
extended dead time = 10 µs
|
|
426
|
+
measurement time = 20 min
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
## 3.5 Change the mean charge number of the LS source
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
td.TDCR_model_lib.modifyZ(5.7)
|
|
434
|
+
print("New configuration:")
|
|
435
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
436
|
+
# back to the default value
|
|
437
|
+
td.TDCR_model_lib.modifyZ(5.2)
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
New configuration:
|
|
441
|
+
number of integration bins for electrons = 1000
|
|
442
|
+
number of integration bins for alpha = 1000
|
|
443
|
+
density = 0.96 g/cm3
|
|
444
|
+
Z = 5.7
|
|
445
|
+
A = 11.04
|
|
446
|
+
depth of spline interp. = 5
|
|
447
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
448
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
449
|
+
activation of the micelle correction = False
|
|
450
|
+
diameter of micelle = 2.0 nm
|
|
451
|
+
acqueous fraction = 0.1
|
|
452
|
+
coincidence resolving time = 50 ns
|
|
453
|
+
extended dead time = 10 µs
|
|
454
|
+
measurement time = 20 min
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
## 3.6 Change the mean atomic mass number of the LS source
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
```python
|
|
461
|
+
td.TDCR_model_lib.modifyA(12.04)
|
|
462
|
+
print("New configuration:")
|
|
463
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
464
|
+
# back to the default value
|
|
465
|
+
td.TDCR_model_lib.modifyA(11.04)
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
New configuration:
|
|
469
|
+
number of integration bins for electrons = 1000
|
|
470
|
+
number of integration bins for alpha = 1000
|
|
471
|
+
density = 0.96 g/cm3
|
|
472
|
+
Z = 5.2
|
|
473
|
+
A = 12.04
|
|
474
|
+
depth of spline interp. = 5
|
|
475
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
476
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
477
|
+
activation of the micelle correction = False
|
|
478
|
+
diameter of micelle = 2.0 nm
|
|
479
|
+
acqueous fraction = 0.1
|
|
480
|
+
coincidence resolving time = 50 ns
|
|
481
|
+
extended dead time = 10 µs
|
|
482
|
+
measurement time = 20 min
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
## 3.7 Change the depht paramerter of the spline interpolation of the quenching function
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
```python
|
|
489
|
+
td.TDCR_model_lib.modifyDepthSpline(7)
|
|
490
|
+
print("New configuration:")
|
|
491
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
492
|
+
# back to the default value
|
|
493
|
+
td.TDCR_model_lib.modifyDepthSpline(5)
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
New configuration:
|
|
497
|
+
number of integration bins for electrons = 1000
|
|
498
|
+
number of integration bins for alpha = 1000
|
|
499
|
+
density = 0.96 g/cm3
|
|
500
|
+
Z = 5.2
|
|
501
|
+
A = 11.04
|
|
502
|
+
depth of spline interp. = 7
|
|
503
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
504
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
505
|
+
activation of the micelle correction = False
|
|
506
|
+
diameter of micelle = 2.0 nm
|
|
507
|
+
acqueous fraction = 0.1
|
|
508
|
+
coincidence resolving time = 50 ns
|
|
509
|
+
extended dead time = 10 µs
|
|
510
|
+
measurement time = 20 min
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
## 3.8 Change the energy threshold (in keV) above which the interpolation is applied (for alpha particles)
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
```python
|
|
517
|
+
td.TDCR_model_lib.modifyEinterp_a(200)
|
|
518
|
+
print("New configuration:")
|
|
519
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
520
|
+
# back to the default value
|
|
521
|
+
td.TDCR_model_lib.modifyEinterp_a(100)
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
New configuration:
|
|
525
|
+
number of integration bins for electrons = 1000
|
|
526
|
+
number of integration bins for alpha = 1000
|
|
527
|
+
density = 0.96 g/cm3
|
|
528
|
+
Z = 5.2
|
|
529
|
+
A = 11.04
|
|
530
|
+
depth of spline interp. = 5
|
|
531
|
+
energy above which interp. in implemented (for alpha) = 200.0 keV
|
|
532
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
533
|
+
activation of the micelle correction = False
|
|
534
|
+
diameter of micelle = 2.0 nm
|
|
535
|
+
acqueous fraction = 0.1
|
|
536
|
+
coincidence resolving time = 50 ns
|
|
537
|
+
extended dead time = 10 µs
|
|
538
|
+
measurement time = 20 min
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
## 3.9 Change the energy threshold (in keV) above which the interpolation is applied (for electrons)
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
```python
|
|
545
|
+
td.TDCR_model_lib.modifyEinterp_e(2.0)
|
|
546
|
+
print("New configuration:")
|
|
547
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
548
|
+
# back to the default value
|
|
549
|
+
td.TDCR_model_lib.modifyEinterp_e(1.5)
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
New configuration:
|
|
553
|
+
number of integration bins for electrons = 1000
|
|
554
|
+
number of integration bins for alpha = 1000
|
|
555
|
+
density = 0.96 g/cm3
|
|
556
|
+
Z = 5.2
|
|
557
|
+
A = 11.04
|
|
558
|
+
depth of spline interp. = 5
|
|
559
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
560
|
+
energy above which interp. in implemented (for electron) = 2.0 keV
|
|
561
|
+
activation of the micelle correction = False
|
|
562
|
+
diameter of micelle = 2.0 nm
|
|
563
|
+
acqueous fraction = 0.1
|
|
564
|
+
coincidence resolving time = 50 ns
|
|
565
|
+
extended dead time = 10 µs
|
|
566
|
+
measurement time = 20 min
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
## 3.10 Activate/desactivate the micelles correction
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
```python
|
|
573
|
+
td.TDCR_model_lib.modifyMicCorr(False)
|
|
574
|
+
print("New configuration:")
|
|
575
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
576
|
+
# back to the default value
|
|
577
|
+
td.TDCR_model_lib.modifyMicCorr(True)
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
New configuration:
|
|
581
|
+
number of integration bins for electrons = 1000
|
|
582
|
+
number of integration bins for alpha = 1000
|
|
583
|
+
density = 0.96 g/cm3
|
|
584
|
+
Z = 5.2
|
|
585
|
+
A = 11.04
|
|
586
|
+
depth of spline interp. = 5
|
|
587
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
588
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
589
|
+
activation of the micelle correction = False
|
|
590
|
+
diameter of micelle = 2.0 nm
|
|
591
|
+
acqueous fraction = 0.1
|
|
592
|
+
coincidence resolving time = 50 ns
|
|
593
|
+
extended dead time = 10 µs
|
|
594
|
+
measurement time = 20 min
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
## 3.11 Change the diameter of reverse micelles (in nm)
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
```python
|
|
601
|
+
td.TDCR_model_lib.modifyDiam_micelle(4.0)
|
|
602
|
+
print("New configuration:")
|
|
603
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
604
|
+
# back to the default value
|
|
605
|
+
td.TDCR_model_lib.modifyDiam_micelle(2.0)
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
New configuration:
|
|
609
|
+
number of integration bins for electrons = 1000
|
|
610
|
+
number of integration bins for alpha = 1000
|
|
611
|
+
density = 0.96 g/cm3
|
|
612
|
+
Z = 5.2
|
|
613
|
+
A = 11.04
|
|
614
|
+
depth of spline interp. = 5
|
|
615
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
616
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
617
|
+
activation of the micelle correction = False
|
|
618
|
+
diameter of micelle = 4.0 nm
|
|
619
|
+
acqueous fraction = 0.1
|
|
620
|
+
coincidence resolving time = 50 ns
|
|
621
|
+
extended dead time = 10 µs
|
|
622
|
+
measurement time = 20 min
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
## 3.12 Change the acqueous fraction of the LS source
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
```python
|
|
629
|
+
td.TDCR_model_lib.modifyfAq(0.2)
|
|
630
|
+
print("New configuration:")
|
|
631
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
632
|
+
# back to the default value
|
|
633
|
+
td.TDCR_model_lib.modifyfAq(0.1)
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
New configuration:
|
|
637
|
+
number of integration bins for electrons = 1000
|
|
638
|
+
number of integration bins for alpha = 1000
|
|
639
|
+
density = 0.96 g/cm3
|
|
640
|
+
Z = 5.2
|
|
641
|
+
A = 11.04
|
|
642
|
+
depth of spline interp. = 5
|
|
643
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
644
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
645
|
+
activation of the micelle correction = False
|
|
646
|
+
diameter of micelle = 2.0 nm
|
|
647
|
+
acqueous fraction = 0.2
|
|
648
|
+
coincidence resolving time = 50 ns
|
|
649
|
+
extended dead time = 10 µs
|
|
650
|
+
measurement time = 20 min
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
## 3.13 Change the coincidence resolving time of the TDCR counter (in ns)
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
```python
|
|
657
|
+
td.TDCR_model_lib.modifyTau(100)
|
|
658
|
+
print("New configuration:")
|
|
659
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
660
|
+
# back to the default value
|
|
661
|
+
td.TDCR_model_lib.modifyTau(50)
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
New configuration:
|
|
665
|
+
number of integration bins for electrons = 1000
|
|
666
|
+
number of integration bins for alpha = 1000
|
|
667
|
+
density = 0.96 g/cm3
|
|
668
|
+
Z = 5.2
|
|
669
|
+
A = 11.04
|
|
670
|
+
depth of spline interp. = 5
|
|
671
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
672
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
673
|
+
activation of the micelle correction = False
|
|
674
|
+
diameter of micelle = 2.0 nm
|
|
675
|
+
acqueous fraction = 0.1
|
|
676
|
+
coincidence resolving time = 100 ns
|
|
677
|
+
extended dead time = 10 µs
|
|
678
|
+
measurement time = 20 min
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
## 3.14 Change the extended dead time of the TDCR counter (in µs)¶
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
```python
|
|
685
|
+
td.TDCR_model_lib.modifyDeadTime(100)
|
|
686
|
+
print("New configuration:")
|
|
687
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
688
|
+
# back to the default value
|
|
689
|
+
td.TDCR_model_lib.modifyDeadTime(10)
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
New configuration:
|
|
693
|
+
number of integration bins for electrons = 1000
|
|
694
|
+
number of integration bins for alpha = 1000
|
|
695
|
+
density = 0.96 g/cm3
|
|
696
|
+
Z = 5.2
|
|
697
|
+
A = 11.04
|
|
698
|
+
depth of spline interp. = 5
|
|
699
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
700
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
701
|
+
activation of the micelle correction = False
|
|
702
|
+
diameter of micelle = 2.0 nm
|
|
703
|
+
acqueous fraction = 0.1
|
|
704
|
+
coincidence resolving time = 50 ns
|
|
705
|
+
extended dead time = 100 µs
|
|
706
|
+
measurement time = 20 min
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
## 3.15 Change the measurement time (in min)¶
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
```python
|
|
713
|
+
td.TDCR_model_lib.modifyMeasTime(60)
|
|
714
|
+
print("New configuration:")
|
|
715
|
+
td.TDCR_model_lib.readParameters(disp=True)
|
|
716
|
+
# back to the default value
|
|
717
|
+
td.TDCR_model_lib.modifyMeasTime(20)
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
New configuration:
|
|
721
|
+
number of integration bins for electrons = 1000
|
|
722
|
+
number of integration bins for alpha = 1000
|
|
723
|
+
density = 0.96 g/cm3
|
|
724
|
+
Z = 5.2
|
|
725
|
+
A = 11.04
|
|
726
|
+
depth of spline interp. = 5
|
|
727
|
+
energy above which interp. in implemented (for alpha) = 100.0 keV
|
|
728
|
+
energy above which interp. in implemented (for electron) = 1.5 keV
|
|
729
|
+
activation of the micelle correction = False
|
|
730
|
+
diameter of micelle = 2.0 nm
|
|
731
|
+
acqueous fraction = 0.1
|
|
732
|
+
coincidence resolving time = 50 ns
|
|
733
|
+
extended dead time = 10 µs
|
|
734
|
+
measurement time = 60 min
|
|
735
|
+
|
|
736
|
+
# 4. Read Beta spectrum
|
|
737
|
+
|
|
738
|
+
```python
|
|
739
|
+
import tdcrpy as td
|
|
740
|
+
import matplotlib.pyplot as plt
|
|
741
|
+
import numpy as np
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
```python
|
|
746
|
+
radionuclide = "Sr-89"
|
|
747
|
+
mode = "beta-" # 'beta-' or 'beta+'
|
|
748
|
+
level = 'tot' # 0,1,2,3 .... or 'tot'
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
## 4.1 Get information about the BetaShape version
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
```python
|
|
755
|
+
print(td.TDCR_model_lib.readBetaShapeInfo(radionuclide,mode,level))
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
-Beta Spectrum of the main transition from BetaShape 2.4
|
|
759
|
+
(05/2024), DDEP 2004 evaluation and Q-value from AME2020-
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
## 4.2 Read the energy spectrum tabulated from BetaShape
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
```python
|
|
766
|
+
energy, probability = td.TDCR_model_lib.readBetaShape(radionuclide,mode,level)
|
|
767
|
+
|
|
768
|
+
plt.figure("Energy spectrum")
|
|
769
|
+
plt.clf()
|
|
770
|
+
plt.plot(energy[:-1], probability)
|
|
771
|
+
plt.xlabel(r'$E$ /keV', fontsize=14)
|
|
772
|
+
plt.ylabel(r'$p(E)$ /(keV$^{-1}$)', fontsize=14)
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
Text(0, 0.5, '$p(E)$ /(keV$^{-1}$)')
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+

|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
## 4.3 Read the deposited energy spectrum
|
|
789
|
+
|
|
790
|
+
This spectrum is built by TDCRPy (function `buildBetaSpectra`) to be used for the analytical TDCR model
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
```python
|
|
794
|
+
energy2, probability2 = td.TDCR_model_lib.readBetaSpectra(radionuclide)
|
|
795
|
+
|
|
796
|
+
plt.figure("Deposied energy spectrum")
|
|
797
|
+
plt.clf()
|
|
798
|
+
plt.plot(energy[:-1], probability,'-b', label="emitted energy spectrum")
|
|
799
|
+
plt.plot(energy2, probability2,'-r', label="deposited energy spectrum")
|
|
800
|
+
plt.legend(fontsize=14)
|
|
801
|
+
plt.xlabel(r'$E$ /keV', fontsize=14)
|
|
802
|
+
plt.ylabel(r'$p(E)$ /(keV$^{-1}$)', fontsize=14)
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
Text(0, 0.5, '$p(E)$ /(keV$^{-1}$)')
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+

|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
```python
|
|
820
|
+
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
# 5. Stopping power
|
|
824
|
+
|
|
825
|
+
```python
|
|
826
|
+
import tdcrpy as td
|
|
827
|
+
import matplotlib.pyplot as plt
|
|
828
|
+
import numpy as np
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
## 5.1 Stopping power at a given energy
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
```python
|
|
835
|
+
density = 0.96 # in g/cm3
|
|
836
|
+
energy = 100 # keV
|
|
837
|
+
result_alpha = td.TDCR_model_lib.stoppingpowerA(energy,rho=density)
|
|
838
|
+
result_electron = td.TDCR_model_lib.stoppingpower(energy*1e3,rho=density)
|
|
839
|
+
print(f"dE/dx = {result_alpha:.7g} keV/cm for alpha particles" )
|
|
840
|
+
print(f"dE/dx = {result_electron*1e3:.4g} keV/cm for electrons" )
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
dE/dx = 1461120 keV/cm for alpha particles
|
|
844
|
+
dE/dx = 3419 keV/cm for electrons
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
## 5.2 Plot stopping power curves
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
```python
|
|
851
|
+
energy_vec = np.logspace(-2,4,1000) # in keV
|
|
852
|
+
w_a, w_e = [], []
|
|
853
|
+
for e in energy_vec:
|
|
854
|
+
w_a.append(td.TDCR_model_lib.stoppingpowerA(e,rho=density))
|
|
855
|
+
w_e.append(1e3*td.TDCR_model_lib.stoppingpower(e*1e3,rho=density))
|
|
856
|
+
plt.figure("Stopping power")
|
|
857
|
+
plt.clf()
|
|
858
|
+
plt.plot(energy_vec,w_a,"-k",label="alpha particles")
|
|
859
|
+
plt.plot(energy_vec,w_e,"-r",label="electrons")
|
|
860
|
+
plt.xscale('log')
|
|
861
|
+
plt.xlabel(r'$E$ /keV', fontsize=14)
|
|
862
|
+
plt.ylabel(r'd$E$/d$x$ /(keV/cm)', fontsize=14)
|
|
863
|
+
plt.legend()
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
<matplotlib.legend.Legend at 0x25d905a4c90>
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+

|
|
876
|
+
|
|
877
|
+
# 6. Scintillation quenching model
|
|
878
|
+
|
|
879
|
+
```python
|
|
880
|
+
import tdcrpy as td
|
|
881
|
+
import matplotlib.pyplot as plt
|
|
882
|
+
import numpy as np
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
## 6.1 Calculate the quenched energy from the Birks model
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
```python
|
|
889
|
+
kB = 0.01 # Birks constant in cm/MeV
|
|
890
|
+
ei = 1000 # initial energy in keV
|
|
891
|
+
ed = 1000 # deposited energy in keV
|
|
892
|
+
nE = 10000 # number of points of the energy linear space
|
|
893
|
+
eq_e=td.TDCR_model_lib.E_quench_e(ei*1e3,ed*1e3,kB,nE)*1e-3
|
|
894
|
+
print(f"For electrons => Initial energy = {ei} keV, deposited energy = {ed} keV, quenched energy = {eq_e:.5g} keV")
|
|
895
|
+
eq_a=td.TDCR_model_lib.E_quench_a(ei,kB*1e-3,nE)
|
|
896
|
+
print(f"For alpha particles => Initial energy = {ei} keV, quenched energy = {eq_a:.5g} keV")
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
For electrons => Initial energy = 1000 keV, deposited energy = 1000 keV, quenched energy = 975.24 keV
|
|
900
|
+
For alpha particles => Initial energy = 1000 keV, quenched energy = 48.934 keV
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
## 6.2 Correction of the micelle effect
|
|
904
|
+
|
|
905
|
+
The deposited energy ratios were evaluation by GEANT4-DNA [1].
|
|
906
|
+
|
|
907
|
+
[1] Nedjadi, Y., Laedermann, J.-P., Bochud, F., Bailat, C., 2017. On the reverse micelle effect in liquid scintillation counting. Applied Radiation and Isotopes 125, 94–107. https://doi.org/10.1016/j.apradiso.2017.04.020
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
```python
|
|
911
|
+
energy_vec = np.logspace(-2,4,100) # in keV
|
|
912
|
+
fAq=0.1
|
|
913
|
+
s05, s1, s2, s3, s4, s5, s6, s7, s8, s10 = [], [], [], [], [], [], [], [], [], []
|
|
914
|
+
for e in energy_vec:
|
|
915
|
+
s05.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=0.5))
|
|
916
|
+
s1.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=1.0))
|
|
917
|
+
s2.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=2.0))
|
|
918
|
+
s3.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=3.0))
|
|
919
|
+
s4.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=4.0))
|
|
920
|
+
s5.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=5.0))
|
|
921
|
+
s6.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=6.0))
|
|
922
|
+
s7.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=7.0))
|
|
923
|
+
s8.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=8.0))
|
|
924
|
+
s10.append(td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=10.0))
|
|
925
|
+
|
|
926
|
+
plt.figure("Deposited energy ratio")
|
|
927
|
+
plt.clf()
|
|
928
|
+
plt.plot(energy_vec,s05,label="$\Phi$=0.5 nm")
|
|
929
|
+
plt.plot(energy_vec,s1,label="$\Phi$=1.0 nm")
|
|
930
|
+
plt.plot(energy_vec,s2,label="$\Phi$=2.0 nm")
|
|
931
|
+
plt.plot(energy_vec,s3,label="$\Phi$=3.0 nm")
|
|
932
|
+
plt.plot(energy_vec,s4,label="$\Phi$=4.0 nm")
|
|
933
|
+
plt.plot(energy_vec,s5,label="$\Phi$=5.0 nm")
|
|
934
|
+
plt.plot(energy_vec,s6,label="$\Phi$=6.0 nm")
|
|
935
|
+
plt.plot(energy_vec,s7,label="$\Phi$=7.0 nm")
|
|
936
|
+
plt.plot(energy_vec,s8,label="$\Phi$=8.0 nm")
|
|
937
|
+
plt.plot(energy_vec,s10,label="$\Phi$=10.0 nm")
|
|
938
|
+
plt.xscale('log')
|
|
939
|
+
plt.xlabel(r'$E$ /keV', fontsize=14)
|
|
940
|
+
plt.ylabel(r'$S(E)/E$', fontsize=14)
|
|
941
|
+
plt.legend()
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
<matplotlib.legend.Legend at 0x2dab792de10>
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+

|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
## 6.3 Scintillation quenching function from the Birks model (with micelle effect)
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
```python
|
|
961
|
+
energy_vec = np.logspace(-2,4,100) # in keV
|
|
962
|
+
fAq = 0.1 # acqueous fraction
|
|
963
|
+
diam_micelle = 4.0 # diameter of micelles (in nm)
|
|
964
|
+
|
|
965
|
+
eq_a, eq_e, eq_e_m = [], [], []
|
|
966
|
+
for e in energy_vec:
|
|
967
|
+
eq_e.append(td.TDCR_model_lib.E_quench_e(e*1e3,e*1e3,kB,nE)*1e-3)
|
|
968
|
+
eq_e_m.append(td.TDCR_model_lib.E_quench_e(e*1e3,e*1e3,kB,nE)*1e-3*td.TDCR_model_lib.micelleLoss(e,fAq=fAq,diam_micelle=diam_micelle))
|
|
969
|
+
eq_a.append(td.TDCR_model_lib.E_quench_a(e,kB*1e-3,nE))
|
|
970
|
+
|
|
971
|
+
plt.figure("Quenched Energy")
|
|
972
|
+
plt.clf()
|
|
973
|
+
plt.plot(energy_vec,eq_a/energy_vec,"-k",label="alpha particles")
|
|
974
|
+
plt.plot(energy_vec,eq_e/energy_vec,"-r",label="electrons")
|
|
975
|
+
plt.plot(energy_vec,eq_e_m/energy_vec,"--r",label="electrons (micelle effect)")
|
|
976
|
+
plt.xscale('log')
|
|
977
|
+
plt.xlabel(r'$E$ /keV', fontsize=14)
|
|
978
|
+
plt.ylabel(r'$Q_t(E)/E$', fontsize=14)
|
|
979
|
+
plt.legend()
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
<matplotlib.legend.Legend at 0x2dab779f910>
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+

|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
```python
|
|
997
|
+
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
```python
|
|
1001
|
+
# 7. Interaction of ionizing particles
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
```python
|
|
1005
|
+
# pip install opencv-python
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
```python
|
|
1010
|
+
import tdcrpy as td
|
|
1011
|
+
import matplotlib.pyplot as plt
|
|
1012
|
+
import numpy as np
|
|
1013
|
+
import cv2
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
## 7.1 Distributions for electrons from 0 keV to 200 keV
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
```python
|
|
1020
|
+
A = td.TDCR_model_lib.Matrice10_e_1
|
|
1021
|
+
C = np.flipud(A[0:])
|
|
1022
|
+
C = np.clip(C, a_min=7e-6, a_max=1e-1)
|
|
1023
|
+
C = np.log(C)
|
|
1024
|
+
C = cv2.GaussianBlur(C, (3, 5), 10)
|
|
1025
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1026
|
+
x = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1027
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1028
|
+
|
|
1029
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1030
|
+
plt.colorbar()
|
|
1031
|
+
plt.xticks(x)
|
|
1032
|
+
plt.yticks(y)
|
|
1033
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1034
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1035
|
+
plt.savefig("electrons_0-200.png")
|
|
1036
|
+
plt.show()
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+

|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
## 7.2 Distributions for electrons from 200 keV to 2 MeV
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
```python
|
|
1049
|
+
A = td.TDCR_model_lib.Matrice10_e_2
|
|
1050
|
+
C = np.flipud(A[0:])
|
|
1051
|
+
C = np.clip(C, a_min=1e-5, a_max=1e-0)
|
|
1052
|
+
C = np.log(C)
|
|
1053
|
+
C = cv2.GaussianBlur(C, (3, 3), 20)
|
|
1054
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1055
|
+
x = np.arange(A[0,0], A[0,-1], A[0,-1]/10)
|
|
1056
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1057
|
+
|
|
1058
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1059
|
+
plt.colorbar()
|
|
1060
|
+
plt.xticks(x, rotation=20)
|
|
1061
|
+
plt.yticks(y)
|
|
1062
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1063
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1064
|
+
plt.tight_layout()
|
|
1065
|
+
plt.savefig("electrons_200-2000.png")
|
|
1066
|
+
plt.show()
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+

|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
## 7.3 Distributions for electrons from 2 MeV to 8 MeV
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
```python
|
|
1079
|
+
A = td.TDCR_model_lib.Matrice10_e_3
|
|
1080
|
+
C = np.flipud(A[0:])
|
|
1081
|
+
C = np.clip(C, a_min=1e-5, a_max=1e-0)
|
|
1082
|
+
C = np.log(C)
|
|
1083
|
+
C = cv2.GaussianBlur(C, (3, 3), 20)
|
|
1084
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1085
|
+
x = np.arange(A[0,0], A[0,-1], A[0,-1]/10)
|
|
1086
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1087
|
+
|
|
1088
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1089
|
+
plt.colorbar()
|
|
1090
|
+
plt.xticks(x, rotation=20)
|
|
1091
|
+
plt.yticks(y)
|
|
1092
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1093
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1094
|
+
plt.tight_layout()
|
|
1095
|
+
plt.savefig("electrons_2000-10000.png")
|
|
1096
|
+
plt.show()
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+

|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
## 7.4 Distributions for photons from 0 keV to 200 keV
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
```python
|
|
1109
|
+
A = td.TDCR_model_lib.Matrice10_p_1
|
|
1110
|
+
C = np.flipud(A[0:])
|
|
1111
|
+
C = np.clip(C, a_min=1e-7, a_max=1e0)
|
|
1112
|
+
C = np.log(C)
|
|
1113
|
+
C = cv2.GaussianBlur(C, (3, 3), 20)
|
|
1114
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1115
|
+
x = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1116
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1117
|
+
|
|
1118
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1119
|
+
plt.colorbar()
|
|
1120
|
+
plt.xticks(x)
|
|
1121
|
+
plt.yticks(y)
|
|
1122
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1123
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1124
|
+
plt.savefig("photons_0-200.png")
|
|
1125
|
+
plt.show()
|
|
1126
|
+
|
|
1127
|
+
x_1 = 1
|
|
1128
|
+
|
|
1129
|
+
# Find the column index for the given x_1
|
|
1130
|
+
col_idx = np.searchsorted(A[0, :], x_1)
|
|
1131
|
+
|
|
1132
|
+
# Extract the corresponding y values from the column
|
|
1133
|
+
y_1 = C[:, col_idx]
|
|
1134
|
+
x_plot = 0.2*np.arange(0, len(y_1), 1)
|
|
1135
|
+
|
|
1136
|
+
print("escape probability = ",np.exp(y_1[-2])/sum(np.exp(y_1)))
|
|
1137
|
+
# Plot the extracted values
|
|
1138
|
+
plt.plot(x_plot,np.flipud(y_1))
|
|
1139
|
+
plt.xlabel(r"$E_1$ /keV", fontsize=14)
|
|
1140
|
+
plt.ylabel(r"log($P(E_1|E_0)$)", fontsize=14)
|
|
1141
|
+
plt.title(f"Distribution for $x_1 = {x_1}$ keV")
|
|
1142
|
+
plt.grid(True)
|
|
1143
|
+
plt.xlim([0,x_1*1.5])
|
|
1144
|
+
plt.savefig(f"distribution_x_{x_1}.png")
|
|
1145
|
+
plt.show()
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+

|
|
1151
|
+
|
|
1152
|
+
escape probability = 0.5623307322837948
|
|
1153
|
+
|
|
1154
|
+

|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
## 7.5 Distributions for photons from 200 keV to 2 MeV
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
```python
|
|
1162
|
+
A = td.TDCR_model_lib.Matrice10_p_2
|
|
1163
|
+
C = np.flipud(A[0:])
|
|
1164
|
+
C = np.clip(C, a_min=1e-7, a_max=1e0)
|
|
1165
|
+
C = np.log(C)
|
|
1166
|
+
C = cv2.GaussianBlur(C, (3, 3), 20)
|
|
1167
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1168
|
+
x = np.arange(A[0,0], A[0,-1], A[0,-1]/10)
|
|
1169
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1170
|
+
|
|
1171
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1172
|
+
plt.colorbar()
|
|
1173
|
+
plt.xticks(x, rotation=20)
|
|
1174
|
+
plt.yticks(y)
|
|
1175
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1176
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1177
|
+
plt.tight_layout()
|
|
1178
|
+
plt.savefig("photons_200-2000.png")
|
|
1179
|
+
plt.show()
|
|
1180
|
+
|
|
1181
|
+
x_1 = 2000
|
|
1182
|
+
|
|
1183
|
+
# Find the column index for the given x_1
|
|
1184
|
+
col_idx = np.searchsorted(A[0, :], x_1)
|
|
1185
|
+
|
|
1186
|
+
# Extract the corresponding y values from the column
|
|
1187
|
+
y_1 = np.log(A[:, col_idx])
|
|
1188
|
+
x_plot = 2*np.arange(0, len(y_1), 1)
|
|
1189
|
+
|
|
1190
|
+
print("escape probability = ",np.exp(y_1[0]))
|
|
1191
|
+
# Plot the extracted values
|
|
1192
|
+
plt.plot(x_plot,y_1)
|
|
1193
|
+
plt.xlabel(r"$E_1$ /keV", fontsize=14)
|
|
1194
|
+
plt.ylabel(r"log($P(E_1|E_0)$)", fontsize=14)
|
|
1195
|
+
plt.title(f"Distribution for $x_1 = {x_1}$ keV")
|
|
1196
|
+
plt.grid(True)
|
|
1197
|
+
plt.xlim([0,x_1*1.5])
|
|
1198
|
+
plt.savefig(f"distribution_x_{x_1}.png")
|
|
1199
|
+
plt.show()
|
|
1200
|
+
```
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+

|
|
1205
|
+
|
|
1206
|
+
escape probability = 1999.9999999999998
|
|
1207
|
+
|
|
1208
|
+

|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
## 7.6 Distributions for photons from 2 MeV to 10 MeV
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
```python
|
|
1216
|
+
A = td.TDCR_model_lib.Matrice10_p_3
|
|
1217
|
+
C = np.flipud(A[1:])
|
|
1218
|
+
C = np.clip(C, a_min=1e-6, a_max=1e-2)
|
|
1219
|
+
C = np.log(C)
|
|
1220
|
+
C = cv2.GaussianBlur(C, (5, 5), 20)
|
|
1221
|
+
extent = [A[0,0], A[0,-1], 0, A[0,-1]]
|
|
1222
|
+
x = np.arange(A[0,0], A[0,-1], A[0,-1]/10)
|
|
1223
|
+
y = np.arange(0, A[0,-1], A[0,-1]/10)
|
|
1224
|
+
|
|
1225
|
+
plt.imshow(C, extent=extent, cmap='Greys', interpolation='nearest')
|
|
1226
|
+
plt.colorbar()
|
|
1227
|
+
plt.xticks(x, rotation=20)
|
|
1228
|
+
plt.yticks(y)
|
|
1229
|
+
plt.xlabel(r"$E_0$ /keV", fontsize=14)
|
|
1230
|
+
plt.ylabel(r"$E_1$ /keV", fontsize=14)
|
|
1231
|
+
plt.tight_layout()
|
|
1232
|
+
plt.savefig("photons_2000-10000.png")
|
|
1233
|
+
plt.show()
|
|
1234
|
+
|
|
1235
|
+
x_1 = 5000
|
|
1236
|
+
|
|
1237
|
+
# Find the column index for the given x_1
|
|
1238
|
+
col_idx = np.searchsorted(A[0, :], x_1)
|
|
1239
|
+
|
|
1240
|
+
# Extract the corresponding y values from the column
|
|
1241
|
+
y_1 = C[:, col_idx]
|
|
1242
|
+
x_plot = 10*np.arange(0, len(y_1), 1)
|
|
1243
|
+
|
|
1244
|
+
print("escape probability = ",np.exp(y_1[-1])/sum(np.exp(y_1)))
|
|
1245
|
+
# Plot the extracted values
|
|
1246
|
+
plt.plot(x_plot,np.flipud(y_1))
|
|
1247
|
+
plt.xlabel(r"$E_1$ /keV", fontsize=14)
|
|
1248
|
+
plt.ylabel(r"log($P(E_1|E_0)$)", fontsize=14)
|
|
1249
|
+
plt.title(f"Distribution for $x_1 = {x_1}$ keV")
|
|
1250
|
+
plt.grid(True)
|
|
1251
|
+
plt.xlim([0,x_1*1.5])
|
|
1252
|
+
plt.savefig(f"distribution_x_{x_1}.png")
|
|
1253
|
+
plt.show()
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+

|
|
1259
|
+
|
|
1260
|
+
escape probability = 0.03360101175407434
|
|
1261
|
+
|
|
1262
|
+

|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
## 7.7 Sample a deposited energy given an initial energy
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
```python
|
|
1270
|
+
ei = 100 # initial energy in keV
|
|
1271
|
+
v = 10 # volume of the scintillator in mL
|
|
1272
|
+
ed_g=td.TDCR_model_lib.energie_dep_gamma2(ei,v)
|
|
1273
|
+
ed_e=td.TDCR_model_lib.energie_dep_beta2(ei,v)
|
|
1274
|
+
print(f"The gamma ray of initial energy = {ei} keV, has deposited = {ed_g} keV in the scintillant.")
|
|
1275
|
+
print(f"The electron of initial energy = {ei} keV, has deposited = {ed_e} keV in the scintillant.")
|
|
1276
|
+
```
|
|
1277
|
+
|
|
1278
|
+
The gamma ray of initial energy = 100 keV, has deposited = 0 keV in the scintillant.
|
|
1279
|
+
The electron of initial energy = 100 keV, has deposited = 100 keV in the scintillant.
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
## 7.8 Deposited energy of photons as a function of the sintillant volume
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
```python
|
|
1286
|
+
V=np.arange(8,21,0.1)
|
|
1287
|
+
N=100000
|
|
1288
|
+
E=15 # initial energy in keV
|
|
1289
|
+
e_vec, ue_vec = [], []
|
|
1290
|
+
for v in V:
|
|
1291
|
+
x=[]
|
|
1292
|
+
for i in range(N):
|
|
1293
|
+
out=td.TDCR_model_lib.energie_dep_gamma2(15,v)
|
|
1294
|
+
x.append(out)
|
|
1295
|
+
e_vec.append(np.mean(x))
|
|
1296
|
+
ue_vec.append(np.std(x)/np.sqrt(N))
|
|
1297
|
+
|
|
1298
|
+
```
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
```python
|
|
1302
|
+
plt.figure(r"Ed vs volume")
|
|
1303
|
+
plt.clf()
|
|
1304
|
+
plt.errorbar(V, e_vec, yerr=ue_vec, fmt="-k", label=rf'$E_0$ = {E} keV')
|
|
1305
|
+
plt.legend()
|
|
1306
|
+
plt.xlabel(r"$V$ /mL", fontsize=14)
|
|
1307
|
+
plt.ylabel(r"$\bar{y}$ /(keV)", fontsize=14)
|
|
1308
|
+
```
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+

|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
```python
|
|
1315
|
+
|
|
1316
|
+
```
|
|
1317
|
+
|
|
1318
|
+
# 8. Efficiency curves
|
|
1319
|
+
|
|
1320
|
+
```python
|
|
1321
|
+
import tdcrpy as td
|
|
1322
|
+
import numpy as np
|
|
1323
|
+
from tqdm import tqdm
|
|
1324
|
+
import matplotlib.pyplot as plt
|
|
1325
|
+
```
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
```python
|
|
1329
|
+
mode = "eff" # ask for efficiency calculation
|
|
1330
|
+
Rad="Co-60" # radionuclides
|
|
1331
|
+
pmf_1="1" # relatives fractions of the radionulides
|
|
1332
|
+
N = 1000 # number of Monte Carlo trials
|
|
1333
|
+
kB =1.0e-5 # Birks constant in cm keV-1
|
|
1334
|
+
V = 10 # volume of scintillator in mL
|
|
1335
|
+
L=np.logspace(-3,2,num=100) # free parameter in keV-1
|
|
1336
|
+
|
|
1337
|
+
# 8.1 Record decay histories in temporary files
|
|
1338
|
+
td.TDCRPy.TDCRPy(L[0], Rad, pmf_1, N, kB, V, mode, barp=True, record=True)
|
|
1339
|
+
|
|
1340
|
+
effS, u_effS, effD, u_effD, effT, u_effT, effD2, u_effD2 = [], [],[], [],[], [], [], []
|
|
1341
|
+
for l in tqdm(L, desc="free parameters ", unit=" iterations"):
|
|
1342
|
+
out = td.TDCRPy.TDCRPy(l, Rad, pmf_1, N, kB, V, mode, readRecHist=True)
|
|
1343
|
+
effS.append(out[2])
|
|
1344
|
+
u_effS.append(out[3])
|
|
1345
|
+
effD.append(out[2])
|
|
1346
|
+
u_effD.append(out[3])
|
|
1347
|
+
effT.append(out[4])
|
|
1348
|
+
u_effT.append(out[5])
|
|
1349
|
+
effD2.append(out[12])
|
|
1350
|
+
u_effD2.append(out[13])
|
|
1351
|
+
```
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
______ ______ ______ _______ ________
|
|
1355
|
+
|__ __|| ___ \| ___|| ___ | | ____ |
|
|
1356
|
+
| | | | | || | | | | | | |___| |___ ___
|
|
1357
|
+
| | | | | || | | |__| | | _____|\ \ | |
|
|
1358
|
+
| | | |__| || |____| __ \ | | \ \ | |
|
|
1359
|
+
|_| |_____/ |_____||_| \__\|_| \ \_| |
|
|
1360
|
+
+++++++++++++++++++++++++++++++++++++++++/ /
|
|
1361
|
+
________________________________________/ /
|
|
1362
|
+
|______________________________________________/
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
version 2.0.2
|
|
1366
|
+
BIPM 2023 - license MIT
|
|
1367
|
+
distribution: https://pypi.org/project/TDCRPy
|
|
1368
|
+
developement: https://github.com/RomainCoulon/TDCRPy
|
|
1369
|
+
|
|
1370
|
+
start calculation...
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
Processing: 100%|█████████████████████████████████████████████████████████████| 1000/1000 [00:24<00:00, 40.79 decays/s]
|
|
1374
|
+
free parameters : 100%|█████████████████████████████████████████████████████| 100/100 [00:02<00:00, 35.96 iterations/s]
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
```python
|
|
1379
|
+
effS=np.asarray(effS)
|
|
1380
|
+
effT=np.asarray(effT)
|
|
1381
|
+
effD=np.asarray(effD)
|
|
1382
|
+
effD2=np.asarray(effD2)
|
|
1383
|
+
u_effS=np.asarray(u_effS)
|
|
1384
|
+
u_effT=np.asarray(u_effT)
|
|
1385
|
+
u_effD=np.asarray(u_effD)
|
|
1386
|
+
u_effD2=np.asarray(u_effD2)
|
|
1387
|
+
|
|
1388
|
+
tdcr=effT/effD
|
|
1389
|
+
u_tdcr=np.sqrt(u_effD**2*effT**2/effD**4+u_effT**2/effD**2)
|
|
1390
|
+
|
|
1391
|
+
plt.figure("efficiency vs free parameter")
|
|
1392
|
+
plt.clf()
|
|
1393
|
+
plt.errorbar(L,effD,yerr=u_effD,fmt="-k",label="double coincidences")
|
|
1394
|
+
plt.errorbar(L,effT,yerr=u_effT,fmt="-r",label="triple coincidences")
|
|
1395
|
+
plt.errorbar(L,effD2,yerr=u_effD2,fmt="-g",label="double coincidences (CIEMAT/NIST)")
|
|
1396
|
+
plt.xscale('log')
|
|
1397
|
+
plt.xlabel(r'$L$ /keV$^{-1}$', fontsize=14)
|
|
1398
|
+
plt.ylabel(r'$\epsilon$', fontsize=14)
|
|
1399
|
+
plt.legend()
|
|
1400
|
+
|
|
1401
|
+
plt.figure("efficiency vs TDCR")
|
|
1402
|
+
plt.clf()
|
|
1403
|
+
plt.errorbar(tdcr,effD,xerr=u_tdcr,yerr=u_effD,fmt="-k")
|
|
1404
|
+
#plt.xscale('log')
|
|
1405
|
+
plt.xlabel(r'$R_T/R_D$', fontsize=14)
|
|
1406
|
+
plt.ylabel(r'$\epsilon_{D}$', fontsize=14)
|
|
1407
|
+
```
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+

|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+

|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
# 9. Efficiency with radionuclide mixtures
|
|
1417
|
+
|
|
1418
|
+
```python
|
|
1419
|
+
import tdcrpy as td
|
|
1420
|
+
import matplotlib.pyplot as plt
|
|
1421
|
+
import numpy as np
|
|
1422
|
+
from tqdm import tqdm
|
|
1423
|
+
```
|
|
1424
|
+
|
|
1425
|
+
## 9.1 Fixed parameters
|
|
1426
|
+
|
|
1427
|
+
```python
|
|
1428
|
+
mode = "eff" # ask for efficiency calculation
|
|
1429
|
+
Rad = "Fe-55, Ni-63" # list of radionuclides
|
|
1430
|
+
pmf_1="1" # relatives fractions of the radionulides
|
|
1431
|
+
N = 1000 # number of Monte Carlo trials
|
|
1432
|
+
kB =1.0e-5 # Birks constant in cm keV-1
|
|
1433
|
+
V = 10 # volume of scintillator in mL
|
|
1434
|
+
L=1 # free parameter in keV-1
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
## 9.2 Mixture parameters
|
|
1438
|
+
|
|
1439
|
+
```python
|
|
1440
|
+
C = np.arange(0,1,0.05) # relative fraction of the second nuclide
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1443
|
+
## 9.3 Efficiency calculation
|
|
1444
|
+
|
|
1445
|
+
```python
|
|
1446
|
+
effS, ueffS, effD, ueffD, effT, ueffT, effD2, ueffD2 = [], [], [], [], [], [], [], []
|
|
1447
|
+
for i in tqdm(C, desc="Processing items"):
|
|
1448
|
+
pmf_1 = f"{1-i}, {i}"
|
|
1449
|
+
result = td.TDCRPy.TDCRPy(L, Rad, pmf_1, N, kB, V, mode)
|
|
1450
|
+
effS.append(result[0]); ueffS.append(result[1])
|
|
1451
|
+
effD.append(result[2]); ueffD.append(result[3])
|
|
1452
|
+
effT.append(result[4]); ueffT.append(result[5])
|
|
1453
|
+
effD2.append(result[12]); ueffD2.append(result[13])
|
|
1454
|
+
effD = np.asarray(effD); ueffD = np.asarray(ueffD)
|
|
1455
|
+
effD2 = np.asarray(effD2); ueffD2 = np.asarray(ueffD2)
|
|
1456
|
+
effT = np.asarray(effT); ueffT = np.asarray(ueffT)
|
|
1457
|
+
TDCR = effT/effD
|
|
1458
|
+
```
|
|
1459
|
+
|
|
1460
|
+
Processing items: 100%|████████████████████████████████████████████████████████████████| 20/20 [03:52<00:00, 11.63s/it]
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
## 9.4 Plot the efficiency curves
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
```python
|
|
1467
|
+
plt.figure("Stopping power")
|
|
1468
|
+
plt.clf()
|
|
1469
|
+
plt.errorbar(C,effD,yerr=2*ueffD,fmt="-k",label=r"$\epsilon_D$")
|
|
1470
|
+
plt.errorbar(C,TDCR,yerr=2*ueffD,fmt="-r",label=r"$\epsilon_T/\epsilon_D$")
|
|
1471
|
+
plt.errorbar(C,effD2,yerr=2*ueffD2,fmt="-g",label=r"$\epsilon_{D2}$ (CIEMAT/NIST)")
|
|
1472
|
+
#plt.xscale('log')
|
|
1473
|
+
plt.xlabel(f'relative fraction of {Rad.split(",")[1]}', fontsize=14)
|
|
1474
|
+
plt.ylabel(r' ', fontsize=14)
|
|
1475
|
+
plt.legend()
|
|
1476
|
+
plt.savefig("stopping_power_plot.png")
|
|
1477
|
+
```
|
|
1478
|
+
|
|
1479
|
+

|
|
1480
|
+
|
|
1481
|
+
# 10. Dynamic efficiency estimation
|
|
1482
|
+
|
|
1483
|
+
This notebook presents how to link the `TDCRPy` package with the `radioactivedecay` package [1] to simulate dynamic TDCR measurements.
|
|
1484
|
+
|
|
1485
|
+
[1] Alex Malins & Thom Lemoine, radioactivedecay: A Python package for radioactive decay calculations. Journal of Open Source Software, 7 (71), 3318 (2022). https://doi.org/10.21105/joss.03318.
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
```python
|
|
1489
|
+
# pip install radioactivedecay
|
|
1490
|
+
```
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
```python
|
|
1494
|
+
import radioactivedecay as rd
|
|
1495
|
+
import tdcrpy as td
|
|
1496
|
+
import numpy as np
|
|
1497
|
+
import matplotlib.pyplot as plt
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
## 10.1 Input parameters
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
```python
|
|
1504
|
+
radionuclide = 'Mo-99' # parent nuclide decaying during the measurement
|
|
1505
|
+
activity_unit = "Bq" # unit of the initial activity
|
|
1506
|
+
time_unit = "h" # time unit of the decay process
|
|
1507
|
+
A0 = 1 # initial activity (set to 1 in order to obtain relative activities)
|
|
1508
|
+
coolingTime = 30.0 # the cooling time
|
|
1509
|
+
|
|
1510
|
+
mode = "eff"
|
|
1511
|
+
L = 1 # free parameter (keV-1)
|
|
1512
|
+
kB = 1e-5 # Birks constant cm/keV
|
|
1513
|
+
V = 10 # volume of scintillator (mL)
|
|
1514
|
+
N = 1000 # number of simulated decays
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
## 10.2 Run radioactivedecay
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
```python
|
|
1521
|
+
rad_t0 = rd.Inventory({radionuclide: A0}, activity_unit)
|
|
1522
|
+
rad_t1 = rad_t0.decay(coolingTime, time_unit)
|
|
1523
|
+
A_t1 = rad_t1.activities(activity_unit)
|
|
1524
|
+
As_t1 = sum(A_t1.values())
|
|
1525
|
+
print(f"Activity at {coolingTime} {time_unit}")
|
|
1526
|
+
for key, val in A_t1.items(): print(f"\t {key}: {val} {activity_unit}")
|
|
1527
|
+
print("Total activity = ", As_t1, activity_unit)
|
|
1528
|
+
print(f"Relative activity at {coolingTime} {time_unit}")
|
|
1529
|
+
for key, val in A_t1.items(): print(f"\t {key}: {val/As_t1}")
|
|
1530
|
+
```
|
|
1531
|
+
|
|
1532
|
+
Activity at 30.0 h
|
|
1533
|
+
Mo-99: 0.7295308772422591 Bq
|
|
1534
|
+
Ru-99: 0.0 Bq
|
|
1535
|
+
Tc-99: 7.44742326547114e-09 Bq
|
|
1536
|
+
Tc-99m: 0.6738301487178286 Bq
|
|
1537
|
+
Total activity = 1.4033610334075108 Bq
|
|
1538
|
+
Relative activity at 30.0 h
|
|
1539
|
+
Mo-99: 0.5198454708913215
|
|
1540
|
+
Ru-99: 0.0
|
|
1541
|
+
Tc-99: 5.306847695056773e-09
|
|
1542
|
+
Tc-99m: 0.4801545238018309
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
## 10.3 Display the decay graph
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
```python
|
|
1549
|
+
nuc = rd.Nuclide(radionuclide)
|
|
1550
|
+
nuc.plot()
|
|
1551
|
+
```
|
|
1552
|
+
|
|
1553
|
+

|
|
1554
|
+
|
|
1555
|
+
## 10.4 Display the decay curve
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
```python
|
|
1559
|
+
rad_t0 .plot(coolingTime, time_unit, yunits=activity_unit)
|
|
1560
|
+
```
|
|
1561
|
+
|
|
1562
|
+

|
|
1563
|
+
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
## 10.5 Efficiency calculation as a function of the time
|
|
1567
|
+
|
|
1568
|
+
|
|
1569
|
+
```python
|
|
1570
|
+
timeVec = np.arange(0,30,2) # time vector
|
|
1571
|
+
effS, ueffS, effD, ueffD, effT, ueffT, effD2, ueffD2 = [], [], [], [], [], [], [],[]
|
|
1572
|
+
for t in timeVec:
|
|
1573
|
+
rad_t1 = rad_t0.decay(t, time_unit)
|
|
1574
|
+
A_t1 = rad_t1.activities(activity_unit)
|
|
1575
|
+
As_t1 = sum(A_t1.values())
|
|
1576
|
+
|
|
1577
|
+
rads = ""; pmf1 = ""
|
|
1578
|
+
for key, val in A_t1.items():
|
|
1579
|
+
if key != "Pb-208" and key != "Ru-99":
|
|
1580
|
+
rads += ', '+key
|
|
1581
|
+
pmf1 += ', '+str(val/As_t1)
|
|
1582
|
+
rads = rads[2:]
|
|
1583
|
+
pmf1 = pmf1[2:]
|
|
1584
|
+
|
|
1585
|
+
out=td.TDCRPy.TDCRPy(L, rads, pmf1, N, kB, V, mode)
|
|
1586
|
+
effD.append(out[2]); ueffD.append(out[3]); effT.append(out[4]); ueffT.append(out[5])
|
|
1587
|
+
effS.append(out[0]); ueffS.append(out[1]); effD2.append(out[12]); ueffD2.append(out[13])
|
|
1588
|
+
|
|
1589
|
+
effD = np.asarray(effD); effT = np.asarray(effT); ueffD = np.asarray(ueffD); ueffT = np.asarray(ueffT);
|
|
1590
|
+
effD2 = np.asarray(effD2); effS = np.asarray(effS); ueffD2 = np.asarray(ueffD2); ueffS = np.asarray(ueffS);
|
|
1591
|
+
tdcr = effT/effD
|
|
1592
|
+
```
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
## 10.6 Plot efficiency curves
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
```python
|
|
1599
|
+
# Create the plot
|
|
1600
|
+
plt.figure(figsize=(10, 6))
|
|
1601
|
+
plt.errorbar(timeVec, effS, yerr=ueffS, fmt='o', capsize=5, label=r'$\epsilon_S$')
|
|
1602
|
+
plt.errorbar(timeVec, effD, yerr=ueffD, fmt='o', capsize=5, label=r'$\epsilon_D$')
|
|
1603
|
+
plt.errorbar(timeVec, tdcr, yerr=ueffT , fmt='o', capsize=5, label=r'$\epsilon_T/\epsilon_D$')
|
|
1604
|
+
plt.errorbar(timeVec, effD2, yerr=ueffD2, fmt='o', capsize=5, label=r'$\epsilon_D$ (CIEMAT/NIST)')
|
|
1605
|
+
|
|
1606
|
+
# Adding titles and labels
|
|
1607
|
+
#plt.title('Efficiency (effD) as a Function of Time')
|
|
1608
|
+
plt.xlabel(f'cooling time /{time_unit}',fontsize=16)
|
|
1609
|
+
plt.ylabel(r'$\epsilon_D$ and $\epsilon_T/\epsilon_D$',fontsize=16)
|
|
1610
|
+
plt.legend(fontsize=16)
|
|
1611
|
+
plt.grid(True)
|
|
1612
|
+
|
|
1613
|
+
plt.savefig("plotDecay")
|
|
1614
|
+
# Show the plot
|
|
1615
|
+
plt.show()
|
|
1616
|
+
```
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
|
|
1620
|
+

|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
|
|
1625
|
+
```python
|
|
1626
|
+
|
|
1627
|
+
```
|
|
1628
|
+
|
|
1629
|
+
|
|
1630
|
+
|