TDCRPy 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Code/TDCR_model_lib.py ADDED
@@ -0,0 +1,1781 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Mon Jan 23 16:04:46 2023
4
+
5
+ Library of function of the TDCRpy code
6
+
7
+ @author: Romain Coulon, Jialin Hu
8
+ Bureau International des Poids et Mesures
9
+ """
10
+
11
+ ### IMPORT Python Module
12
+ import urllib.request as rq
13
+ import numpy as np
14
+ from numpy.core.multiarray import where
15
+ import zipfile as zf
16
+ # import statsmodels.api as sm
17
+ import matplotlib.pyplot as plt
18
+ import time
19
+ import re
20
+ absolutePath = False
21
+
22
+
23
+ def TicTocGenerator():
24
+ """
25
+ Generator that returns time differences
26
+ """
27
+ ti = 0 # initial time
28
+ tf = time.time() # final time
29
+ while True:
30
+ ti = tf
31
+ tf = time.time()
32
+ yield tf-ti # returns the time difference
33
+
34
+ TicToc = TicTocGenerator() # create an instance of the TicTocGen generator
35
+
36
+ # This will be the main function through which we define both tic() and toc()
37
+ def toc(tempBool=True):
38
+ """
39
+ Prints the time difference yielded by generator instance TicToc
40
+ """
41
+
42
+ tempTimeInterval = next(TicToc)
43
+ if tempBool:
44
+ print( "Elapsed time: %f seconds.\n" %tempTimeInterval )
45
+
46
+ def tic():
47
+ """
48
+ Records a time in TicToc, marks the beginning of a time interval
49
+ """
50
+ toc(False)
51
+
52
+ def normalise(p_x):
53
+ p_array = np.array(p_x)
54
+ if len(p_x)>1:
55
+ p_somme = sum(p_array)
56
+ if p_somme>0.0:
57
+ p_array = p_array/p_somme
58
+ else:
59
+ p_somme = p_x[0]
60
+ p_array = p_array/p_somme
61
+ p = list(p_array)
62
+ return p
63
+ #print(normalise([1, 0.9974641, 0]))
64
+
65
+ def sampling(p_x):
66
+ """
67
+ This function aims to sample in a pdf or a pmf
68
+
69
+ Parameters
70
+ ----------
71
+ p_x : float vector
72
+ Probability Density (or mass) Function (PDF or PMF) of the random variable x.
73
+
74
+
75
+ Returns
76
+ -------
77
+ i : integer
78
+ index in x pointing the sampled value of the random variable X.
79
+ """
80
+
81
+ cf = np.cumsum(p_x) # Cummulative Density (or mass) Function (CDF or CMF)
82
+ trial = float(np.random.rand(1)) # trial ~ U(0,1)
83
+
84
+ for i, p in enumerate(cf):
85
+ if p> trial: break
86
+ return i
87
+
88
+
89
+ def readPenNuc(rad):
90
+ """
91
+ This function reads the PenNuc files published in the DDEP web page
92
+ http://www.lnhb.fr/donnees-nucleaires/donnees-nucleaires-tableau/
93
+
94
+ Parameters
95
+ ----------
96
+ rad : string
97
+ Indentifier of the radionuclide (e.g. Na-22).
98
+
99
+ Returns
100
+ -------
101
+ out : list
102
+ list of elements in list describing the decay of the radionuclide with,
103
+ *particle* is the list of particle of the decay branches
104
+ *p_branch* is the list of probabilty of the decay branches
105
+ *e_branch* is the list of energy of the decay branches
106
+ *LevelDaughter* is the list of energy levels of the daughter nucleus following the decay branch
107
+ *levelNumber* is the list of number of the energy level of the daughter nucleus following the decay branch
108
+ *prob* is the list of probabilty of isomeric transitions
109
+ *levelEnergy* is the energy levels of the isomeric transitions
110
+ *transitionType* is the type of isomeric transitions
111
+ *e_trans* is the energy of the isomeric transitions
112
+ *next_level* is the possible next energy level following a given isomeric transtion
113
+ *Q_value_vec[dd]* is the Q-value of the decay when decaying to the daughter of index dd
114
+ *Daughter_vec[dd]* is the vecteur of daugher nuclei
115
+ *Pdaughter_vec[dd]* is the probability of daughter nuclei
116
+ """
117
+
118
+ url = "http://www.lnhb.fr/nuclides/"+rad+".PenNuc.txt"
119
+ file = rq.urlopen(url)
120
+
121
+ # Format the data
122
+ decayData = []
123
+ for line in file:
124
+ decayData.append(line.decode("utf-8"))
125
+ if "NDA " in decayData[-1]: decayData[-1] = decayData[-1].replace("NDA ", "NDA; ") # number of daughter
126
+ if "DAU " in decayData[-1]: decayData[-1] = decayData[-1].replace("DAU ", "DAU; ") # daughter
127
+ if "DDE " in decayData[-1]: decayData[-1] = decayData[-1].replace("DDE ", "DDE; ") # daughter description : probability of disintegration to NDA, uncertainty, number of excited levels of NDA; number of branche to NDA
128
+ if "Q " in decayData[-1]: decayData[-1] = decayData[-1].replace("Q ", "Q; ") # total energy of the branch, uncertainty
129
+ if "ALP " in decayData[-1]: decayData[-1] = decayData[-1].replace("ALP ", "ALP; ") # type of the disintegration = alpha
130
+ if "CK " in decayData[-1]: decayData[-1] = decayData[-1].replace("CK ", "CK; ") # type of the disintegration = Electron Capture K shell
131
+ if "CL " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL ", "CL; ") # type of the disintegration = Electron Capture L shell 1
132
+ if "CL1 " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL1 ", "CL1; ") # type of the disintegration = Electron Capture L shell 1
133
+ if "CL2 " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL2 ", "CL2; ") # type of the disintegration = Electron Capture L shell 2
134
+ if "CM " in decayData[-1]: decayData[-1] = decayData[-1].replace("CM ", "CM; ") # type of the disintegration = Electron Capture M shell
135
+ if "CN " in decayData[-1]: decayData[-1] = decayData[-1].replace("CN ", "CN; ") # type of the disintegration = Electron Capture N shell
136
+ if "BEM " in decayData[-1]: decayData[-1] = decayData[-1].replace("BEM ", "BEM; ") # type disintegration-beta- :branching ratio, uncertainty, level fed in daughter, energy, uncertainty,prohibition factor for beta emission
137
+ if "BEP " in decayData[-1]: decayData[-1] = decayData[-1].replace("BEP ", "BEP; ") # type disintegration-beta+ :branching ratio, uncertainty, level fed in daughter, energy, uncertainty,prohibition factor for beta emission
138
+ if "LED " in decayData[-1]: decayData[-1] = decayData[-1].replace("LED ", "LED; ") # level description:energy of level,uncertainty, number of transitions that depopulate this level,level time,uncertainty,level number
139
+ if "GA " in decayData[-1]: decayData[-1] = decayData[-1].replace("GA ", "GA; ") # type transition: gamma
140
+ if "EK " in decayData[-1]: decayData[-1] = decayData[-1].replace("EK ", "EK; ") # type transition: internal conversion -- electron K
141
+ if "EL1 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL1 ", "EL1; ") # type transition: internal conversion -- electron L1
142
+ if "EL2 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL2 ", "EL2; ") # type transition: internal conversion -- electron L2
143
+ if "EL3 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL3 ", "EL3; ") # type transition: internal conversion -- electron L3
144
+ if "EM " in decayData[-1]: decayData[-1] = decayData[-1].replace("EM ", "EM; ") # type transition: internal conversion -- electron M
145
+ if "EN " in decayData[-1]: decayData[-1] = decayData[-1].replace("EN ", "EN; ") # type transition: internal conversion -- electron N
146
+ if "COM" in decayData[-1]: decayData[-1] = decayData[-1].replace("COM ", "COM; ") # commentaire
147
+ decayData[-1]=decayData[-1].split(";")
148
+ if "\r\n" in decayData[-1][-1]: decayData[-1][-1] = decayData[-1][-1].replace("\r\n", " ")
149
+
150
+
151
+
152
+ """
153
+ LOOP IN NDAUGH (Daughters)
154
+ """
155
+ Daughter_vec = []; Pdaughter_vec = []; Q_value_vec = []
156
+ for d in decayData:
157
+ if d[0] == "NDA": Ndaughter = int(d[1]) # Read the number of daughter
158
+ if d[0] == "DAU" :
159
+ d[1] = d[1].replace(" ","")
160
+ Daughter_vec.append(d[1]) # Read the daughter
161
+ if d[0] == "DDE": Pdaughter_vec.append(float(d[1])) # Read the probability of disintegration to daughter
162
+ if d[0] == "Q": Q_value_vec.append(float(d[1])) # Read the Q-value
163
+
164
+ out = []
165
+ for dd in range(Ndaughter):
166
+
167
+ # index_Daughter = sampling(np.asarray(Pdaughter_vec)/sum(np.asarray(Pdaughter_vec)))
168
+ # Daughter = Daughter_vec[index_Daughter]
169
+ # Pdaughter = Pdaughter_vec[index_Daughter]
170
+ # Q_value = Q_value_vec[index_Daughter]
171
+
172
+
173
+ """
174
+ LOOP IN NBRANCH (Branches of each daughter)
175
+ """
176
+ # Probablity vector of the decay branch
177
+ particle=[]; LevelDaughter = []; p_branch = []; u_p_branch = []; e_branch = []; u_e_branch = []
178
+ daughterFlag = True
179
+ countBranch = 0
180
+ for d in decayData:
181
+ if d[0] == "DAU" and d[1] == Daughter_vec[dd]:
182
+ daughterFlag = True
183
+ if d[0] == "DAU" and d[1] != Daughter_vec[dd]:
184
+ daughterFlag = False
185
+
186
+ if daughterFlag:
187
+ # particle_i = []; p_branch_i=[]; u_p_branch_i=[]; e_branch_i=[]; u_e_branch_i=[]; LevelDaughter_i=[]
188
+ if d[0] =="COM":
189
+ if "Branch" in d[1] or "Level" in d[1]:
190
+ print(d[1])
191
+ if countBranch % 2 == 1:
192
+ p_branch.append(p_branch_i); u_p_branch.append(u_p_branch_i); # Branching ratio of the decay branch
193
+ e_branch.append(e_branch_i); u_e_branch.append(u_e_branch_i); # Energy of the decay branch (kinetic energy of the particle)
194
+ LevelDaughter.append(LevelDaughter_i); particle.append(particle_i)
195
+
196
+ particle_i = []; p_branch_i=[]; u_p_branch_i=[]; e_branch_i=[]; u_e_branch_i=[]; LevelDaughter_i=[]
197
+ else:
198
+ particle_i = []; p_branch_i=[]; u_p_branch_i=[]; e_branch_i=[]; u_e_branch_i=[]; LevelDaughter_i=[]
199
+
200
+
201
+ countBranch += 1
202
+ # p_branch=
203
+
204
+
205
+ if d[0] == "ALP" or d[0] == "BEM" or d[0] == "BEP" or d[0] == "CK" or d[0] == "CL" or d[0] == "CL1" or d[0] == "CL2" or d[0] == "CM" or d[0] == "CN": # Read information on the decay branch
206
+ if d[0] == "ALP": particle_i.append("alpha")
207
+ if d[0] == "BEP": particle_i.append("beta+")
208
+ if d[0] == "BEM": particle_i.append("beta")
209
+ if d[0] == "CK": particle_i.append("Atom_K")
210
+ if d[0] == "CL": particle_i.append("Atom_L")
211
+ if d[0] == "CL1": particle_i.append("Atom_L1")
212
+ if d[0] == "CL2": particle_i.append("Atom_L2")
213
+ if d[0] == "CM": particle_i.append("Atom_M")
214
+ if d[0] == "CN": particle_i.append("Atom_N")
215
+ if d[2] == " ": d[2]=0
216
+
217
+ p_branch_i.append(float(d[1])); u_p_branch_i.append(float(d[2])); # Branching ratio of the decay branch
218
+ e_branch_i.append(float(d[4])); u_e_branch_i.append(float(d[5])); # Energy of the decay branch (kinetic energy of the particle)
219
+ LevelDaughter_i.append(int(d[3])) # Level fed in daughter
220
+
221
+
222
+
223
+ """
224
+ LOOP IN NLEVEL (Levels for each daughter, starting in NLEVEL, ending in 1)
225
+ """
226
+ levelEnergy = []; fromBranch = []; lineL=[]; listTran = []; levelNumber = []
227
+ transitionType = []; prob = []; u_prob = []; e_trans = []; u_e_trans = []; next_level = []
228
+ transitionType_i = []; prob_i = []; u_prob_i = []; e_trans_i = []; u_e_trans_i = []; next_level_i = []; levelEnergy_i = []
229
+ for d in decayData:
230
+ if d[0] == "DAU" and d[1] == Daughter_vec[dd]:
231
+ daughterFlag = True
232
+ if d[0] == "DAU" and d[1] != Daughter_vec[dd]:
233
+ daughterFlag = False
234
+ if daughterFlag:
235
+ if d[0] == "LED":
236
+ # record transition details of the previous level
237
+ transitionType.append(transitionType_i); prob.append(prob_i); u_prob.append(u_prob_i); e_trans.append(e_trans_i); u_e_trans.append(u_e_trans_i); next_level.append(next_level_i);levelEnergy.append(levelEnergy_i)
238
+ # if int(d[6]) in LevelDaughter : # Read the information on the possible energy levels after the emission of the alpha particle
239
+ levelEnergy_i.append(float(d[1])) #levelEnergy.append(float(d[1])); # Energie (rounded) of the level
240
+ listTran.append(int(d[3])) # Number of transitions that depopulate this level
241
+ levelNumber.append(int(d[6])) # Level number
242
+ transitionType_i = []; next_level_i = []; levelEnergy_i = [];prob_i = []; u_prob_i = []; e_trans_i = []; u_e_trans_i = [];
243
+
244
+ """
245
+ LOOP IN NTRANS (Transitions depopulating this level)
246
+ """
247
+ if d[0] == "GA" or d[0] == "EK" or d[0] == "EL1" or d[0] == "EL2" or d[0] == "EL3" or d[0] == "EM" or d[0] == "EN":
248
+ if d[1] == ' ' or d[1] == ' ': d[1] = 0
249
+ if d[2] == ' ': d[2] = 0
250
+ if d[4] == ' ': d[4] = 0
251
+ transitionType_i.append(d[0]) # Read the type of transtion
252
+ prob_i.append(float(d[1])); u_prob_i.append(float(d[2])) # Read the emission probability of the transition
253
+ e_trans_i.append(float(d[3])); u_e_trans_i.append(float(d[4])) # Read the energy of the transition
254
+ next_level_i.append(int(d[5])) # Read the level fed by this transition
255
+
256
+ transitionType.append(transitionType_i); prob.append(prob_i); u_prob.append(u_prob_i); e_trans.append(e_trans_i); u_e_trans.append(u_e_trans_i); next_level.append(next_level_i);levelEnergy.append(levelEnergy_i)
257
+
258
+ out.append([particle, p_branch, e_branch, LevelDaughter, levelNumber, prob, levelEnergy, transitionType, e_trans, next_level, Q_value_vec[dd], Daughter_vec[dd], Pdaughter_vec[dd]])
259
+ return out
260
+ #out = readPenNuc('Am-242')
261
+ #print(len(out),out)
262
+ # tic()
263
+ # readPenNuc("Co-60")
264
+ # toc() # 0.016 s
265
+
266
+ if absolutePath: file_pennuc = 'G:\Python_modules\Jialin\Code\decayData\\All-nuclides_PenNuc.zip'
267
+ else: file_pennuc = "decayData//All-nuclides_PenNuc.zip"
268
+
269
+ z_PenNuc = zf.ZipFile(file_pennuc)
270
+
271
+ def readPenNuc2(rad,z1=z_PenNuc):
272
+ '''
273
+ =========
274
+ PARAMETRE
275
+ =========
276
+ rad -- type: str (par exemple: "Am-241") -- radionucléide
277
+
278
+ ======
279
+ RETURN
280
+ ======
281
+ daughter -- indice 0 -- des noyaux fils -- len = nb de noyaux fils
282
+ prob_daug -- indice 1 -- des probabilités de noyaux fils -- len = nb de noyaux fils
283
+ energy_Q -- indice 2 -- des énergies de désintégrations -- len = nb de noyaux fils
284
+
285
+ desin_type_tot -- indice 3 -- des types de désintégrations/particules émis
286
+ len = nb de noyaux fils
287
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
288
+ sous-list de sous-list -- des désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
289
+
290
+ desin_energy_tot -- indice 4 -- des énergies de désintégrations/énergies de patricules émis
291
+ len = nb de noyaux fils
292
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
293
+ sous-list de sous-list -- des énergies de désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
294
+
295
+ desin_prob_tot -- indice 5 -- des probabilités de désintégrations
296
+ len = nb de noyaux fils
297
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
298
+ sous-list de sous-list -- des probabilités de désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
299
+
300
+ desin_level_tot -- indice 6 -- des niveaux atteints après des désintégrations
301
+ len = nb de noyaux fils
302
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
303
+ sous-list de sous-list -- des niveaux après des désintégrations de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
304
+
305
+ prob_branch_tot -- indice 7 -- probabilités de chaque branch
306
+ len = nb de noyaux fils
307
+ sous-list -- des probabilités de branchs de noyau fil -- len de sous-list = nb de branch de chaque fil
308
+
309
+ tran_type_tot -- indice 8 -- transitions possibles
310
+ len = nb de noyaux fils
311
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
312
+ sous-list de sous-list -- des transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
313
+
314
+ tran_energy_tot -- indice 9 -- énergies de transitions
315
+ len = nb de noyaux fils
316
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
317
+ sous-list de sous-list -- des énergies de transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
318
+
319
+ tran_prob_tot -- indice 10 -- probabilités de transitions
320
+ len = nb de noyaux fils
321
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
322
+ sous-list de sous-list -- des probabilités de transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
323
+
324
+ tran_level_tot -- indice 11 -- niveaux de branch correspondants
325
+ len = nb de noyaux fils
326
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
327
+ sous-list de sous-list -- des niveaux de chaque branch avant des transitions -- len de sous-list de sous-list = 1
328
+
329
+ tran_level_end_tot -- indice 12 -- niveaux après des transitions
330
+ len = nb de noyaux fils
331
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
332
+ sous-list de sous-list -- des niveaux après des transitions de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
333
+
334
+ level_energy_tot -- indice 13 -- énergies de niveaux
335
+ len = nb de noyaux fils
336
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
337
+ sous-list de sous-list -- des énergies de niveaux de chaque branch -- len de sous-list de sous-list = 1
338
+
339
+ prob_tran_tot -- indice 14 -- la somme de transition de chaque branch
340
+ len = nb de noyaux fils
341
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
342
+ sous-list de sous-list -- des énergies de niveaux de chaque branch -- len de sous-list de sous-list = 1
343
+ '''
344
+ doc = rad + ".PenNuc.txt"
345
+ with z1.open(doc) as file_P:
346
+ decayData = file_P.readlines()
347
+
348
+ for i in range(np.size(decayData)):
349
+ decayData[i] = str(decayData[i])
350
+ decayData[i] = decayData[i].replace("b'","")
351
+ decayData[i] = decayData[i].replace("\\r\\n","")
352
+ decayData[i] = decayData[i].replace("'","")
353
+
354
+ for il in range(len(decayData)):
355
+ if "NDA " in decayData[il]: decayData[il] = decayData[il].replace("NDA ","NDA; ")
356
+ if "DAU " in decayData[il]: decayData[il] = decayData[il].replace("DAU ","DAU; ")
357
+ if "DDE " in decayData[il]: decayData[il] = decayData[il].replace("DDE ","DDE; ")
358
+ if "Q " in decayData[il]: decayData[il] = decayData[il].replace("Q ","Q; ")
359
+ if "ALP " in decayData[il]: decayData[il] = decayData[il].replace("ALP ","ALP; ")
360
+ if "CK " in decayData[il]: decayData[il] = decayData[il].replace("CK ","CK; ")
361
+ if "CL " in decayData[il]: decayData[il] = decayData[il].replace("CL ","CL; ")
362
+ if "CO " in decayData[il]: decayData[il] = decayData[il].replace("CO ","CO; ")
363
+ if "CL1 " in decayData[il]: decayData[il] = decayData[il].replace("CL1 ","CL1; ")
364
+ if "CL2 " in decayData[il]: decayData[il] = decayData[il].replace("CL2 ","CL2; ")
365
+ if "CL3 " in decayData[il]: decayData[il] = decayData[il].replace("CL3 ","CL3; ")
366
+ if "CN " in decayData[il]: decayData[il] = decayData[il].replace("CN ","CN; ")
367
+ if "CM " in decayData[il]: decayData[il] = decayData[il].replace("CM ","CM; ")
368
+ if "BEM " in decayData[il]: decayData[il] = decayData[il].replace("BEM ","BEM; ")
369
+ if "BEP " in decayData[il]: decayData[il] = decayData[il].replace("BEP ","BEP; ")
370
+ if "LED " in decayData[il]: decayData[il] = decayData[il].replace("LED ","LED; ")
371
+ if "GA " in decayData[il]: decayData[il] = decayData[il].replace("GA ","GA; ")
372
+ if "EK " in decayData[il]: decayData[il] = decayData[il].replace("EK ","EK; ")
373
+ if "EL " in decayData[il]: decayData[il] = decayData[il].replace("EL ","EL; ")
374
+ if "EL1 " in decayData[il]: decayData[il] = decayData[il].replace("EL1 ","EL1; ")
375
+ if "EL2 " in decayData[il]: decayData[il] = decayData[il].replace("EL2 ","EL2; ")
376
+ if "EL3 " in decayData[il]: decayData[il] = decayData[il].replace("EL3 ","EL3; ")
377
+ if "EM " in decayData[il]: decayData[il] = decayData[il].replace("EM ","EM; ")
378
+ if "EN " in decayData[il]: decayData[il] = decayData[il].replace("EN ","EN; ")
379
+ if "COM " in decayData[il]: decayData[il] = decayData[il].replace("COM ","COM; ")
380
+ decayData[il] = decayData[il].split(';')
381
+
382
+ for a1 in decayData:
383
+ for a2 in range(len(a1)):
384
+ a1[a2] = a1[a2].strip()
385
+
386
+ '''
387
+ ========================
388
+ Repérer chaque noyau fil
389
+ ========================
390
+
391
+ daughter -- noyau(x) fil(s)
392
+ posi_daug -- l'indice de démarcation de noyau fil
393
+ posi_branch -- l'indice de démarcation de chaque branch
394
+ posi_tran -- l'indice de démarcation de transition
395
+ prob_daug -- probabilité de produire des noyaux fils
396
+ nb_branch -- nombre de branch possible au dessus de l'état fonda (n>0)
397
+ energy_Q -- l'énergie de désintégration
398
+
399
+ '''
400
+ daughter = [];posi_daug = [];prob_daug=[];nb_branch=[];energy_Q=[];
401
+ end = len(decayData)
402
+ for indice,line in enumerate(decayData):
403
+ if "NDA" == line[0]:
404
+ nb_daug = int(line[1])
405
+ if "DAU" == line[0]:
406
+ daughter.append(line[1].replace(" ",""))
407
+ if "COM" == line[0] and "Daughter" in line[1]:
408
+ posi_daug.append(indice)
409
+ if "Q" == line[0]:
410
+ energy_Q.append(float(line[1]))
411
+ if "DDE" == line[0]:
412
+ prob_daug.append(float(line[1]))
413
+ nb_branch.append(int(line[-2]))
414
+ '''
415
+ ==========
416
+ LOOP START
417
+ ==========
418
+
419
+ '''
420
+ posi_end=[]
421
+ desin_type_tot=[];desin_energy_tot=[];desin_prob_tot=[];desin_level_tot=[]
422
+ tran_type_tot=[];tran_energy_tot=[];tran_prob_tot=[];tran_level_end_tot=[];
423
+ tran_level_tot=[];level_energy_tot=[]
424
+ prob_branch_tot=[];prob_tran_tot=[]
425
+
426
+ '''
427
+ =============
428
+ LOOP DAUGHTER
429
+ =============
430
+
431
+ '''
432
+ for i1 in range(nb_daug):
433
+ start_p = posi_daug[i1]
434
+ if i1+1 == nb_daug:
435
+ end_p = end
436
+ else:
437
+ end_p = posi_daug[i1+1]
438
+
439
+ posi_end_i = []
440
+ for i2 in range(start_p,end_p):
441
+ if "COM" == decayData[i2][0] and "Branch" in decayData[i2][1]:
442
+ posi_end_i.append(i2)
443
+ if "COM" == decayData[i2][0] and "Level" in decayData[i2][1]:
444
+ posi_end_i.append(i2)
445
+ if end_p == end:
446
+ posi_end_i.append(end)
447
+ else:
448
+ posi_end_i.append(posi_daug[i1+1])
449
+ posi_end.append(posi_end_i)
450
+
451
+ '''
452
+ ==========================
453
+ LOOP Branch and Transition
454
+ ==========================
455
+ '''
456
+ desin_type_daug=[];desin_energy_daug=[];desin_prob_daug=[];desin_level_daug=[];
457
+ tran_type_daug=[];tran_energy_daug=[];tran_prob_daug=[];tran_level_end_daug=[];
458
+ tran_level_daug=[];level_energy_daug=[]
459
+ prob_branch_daug=[];prob_tran_daug=[]
460
+
461
+ for i3 in range(len(posi_end_i)-1):
462
+ start_p1 = posi_end_i[i3]
463
+ end_p1 = posi_end_i[i3+1]
464
+ branch = False
465
+ transition = False
466
+ if "COM" == decayData[start_p1][0] and "Branch" in decayData[start_p1][1]:
467
+ branch=True
468
+ if "COM" == decayData[start_p1][0] and "Level" in decayData[start_p1][1]:
469
+ transition = True
470
+
471
+ '''
472
+ ====================================
473
+ LOOP EACH BLOCK OF BRANCH/TRANSITION
474
+ ====================================
475
+ '''
476
+ tran_type_b=[];tran_prob_b=[];tran_energy_b=[]; tran_level_end_b=[];
477
+ tran_level_b=[];level_energy_b=[]
478
+ desin_type_b=[];desin_energy_b=[];desin_prob_b=[];desin_level_b=[];
479
+
480
+ for i4 in decayData[start_p1+1:end_p1]:
481
+ if start_p1+1 == end_p1:
482
+ break
483
+ if branch:
484
+ if "ALP" == i4[0]:
485
+ desin_type_b.append("alpha")
486
+ if "BEP" == i4[0]:
487
+ desin_type_b.append("beta+")
488
+ if "BEM" == i4[0]:
489
+ desin_type_b.append("beta")
490
+ if "CK" == i4[0]:
491
+ desin_type_b.append("Atom_K")
492
+ if "CL" == i4[0]:
493
+ desin_type_b.append("Atom_L")
494
+ if "CL1" == i4[0]:
495
+ desin_type_b.append("Atom_L1")
496
+ if "CL2" == i4[0]:
497
+ desin_type_b.append("Atom_L2")
498
+ if "CL3" == i4[0]:
499
+ desin_type_b.append("Atom_L3")
500
+ if "CM" == i4[0]:
501
+ desin_type_b.append("Atom_M")
502
+ if "CN" == i4[0]:
503
+ desin_type_b.append("Atom_N")
504
+ if "CO" == i4[0]:
505
+ desin_type_b.append("Atom_O")
506
+ desin_prob_b.append(float(i4[1]))
507
+ desin_level_b.append(int(i4[3]))
508
+ desin_energy_b.append(float(i4[4]))
509
+ if transition:
510
+ if i4[1] == '' or i4[1] == ' ': i4[1] = 0
511
+ if len(i4)>2 and i4[2] == '': i4[2] = 0
512
+ if len(i4)>4 and i4[4] == '': i4[4] = 0
513
+ if len(i4)>5 and i4[5] == '': i4[5] = 0
514
+ if "LED" == i4[0]:
515
+ tran_level_b.append(int(i4[-1]))
516
+ level_energy_b.append(float(i4[1]))
517
+ if i4[0] == "GA" or i4[0] == "EK" or i4[0] == "EL" or i4[0] == "EL1" or i4[0] == "EL2" or i4[0] == "EL3" or i4[0] == "EM" or i4[0] == "EN":
518
+ #print(i4)
519
+ tran_type_b.append(i4[0])
520
+ tran_prob_b.append(float(i4[1]))
521
+ tran_energy_b.append(float(i4[3]))
522
+ tran_level_end_b.append(int(i4[5]))
523
+ if branch:
524
+ desin_type_daug.append(desin_type_b)
525
+ desin_energy_daug.append(desin_energy_b)
526
+ desin_prob_daug.append(desin_prob_b)
527
+ desin_level_daug.append(desin_level_b)
528
+
529
+ if transition:
530
+ tran_type_daug.append(tran_type_b)
531
+ tran_energy_daug.append(tran_energy_b)
532
+ tran_prob_daug.append(tran_prob_b)
533
+ tran_level_end_daug.append(tran_level_end_b)
534
+ tran_level_daug.append(tran_level_b)
535
+ level_energy_daug.append(level_energy_b)
536
+
537
+ if len(desin_prob_b)>0:
538
+ desin_prob_array = np.array(desin_prob_b)
539
+ prob_branch_i = np.sum(desin_prob_array)
540
+ if prob_branch_i >= 1:
541
+ prob_branch_i = 1
542
+ prob_branch_daug.append(prob_branch_i)
543
+ elif branch and len(desin_prob_b)==0:
544
+ prob_branch_daug.append(0)
545
+
546
+ if len(tran_prob_b)>0:
547
+ tran_prob_array = np.array(tran_prob_b)
548
+ prob_tran_i = np.sum(tran_prob_array)
549
+ if prob_tran_i >= 1:
550
+ prob_tran_i = 1
551
+ prob_tran_daug.append(prob_tran_i)
552
+ elif transition and len(tran_prob_b)==0:
553
+ prob_tran_daug.append(0)
554
+
555
+ tran_type_daug.append([])
556
+ tran_prob_daug.append([])
557
+ tran_energy_daug.append([])
558
+ tran_level_end_daug.append([])
559
+ tran_level_daug.append([])
560
+ level_energy_daug.append([])
561
+ prob_tran_daug.append(0)
562
+
563
+ desin_type_tot.append(desin_type_daug)
564
+ desin_energy_tot.append(desin_energy_daug)
565
+ desin_prob_tot.append(desin_prob_daug)
566
+ desin_level_tot.append(desin_level_daug)
567
+
568
+ tran_type_tot.append(tran_type_daug)
569
+ tran_energy_tot.append(tran_energy_daug)
570
+ tran_prob_tot.append(tran_prob_daug)
571
+ tran_level_end_tot.append(tran_level_end_daug)
572
+ tran_level_tot.append(tran_level_daug)
573
+ level_energy_tot.append(level_energy_daug)
574
+ prob_branch_tot.append(prob_branch_daug)
575
+ prob_tran_tot.append(prob_tran_daug)
576
+ out = [daughter,prob_daug,energy_Q,desin_type_tot,desin_energy_tot,desin_prob_tot,desin_level_tot,prob_branch_tot,tran_type_tot,tran_energy_tot,tran_prob_tot,tran_level_tot,tran_level_end_tot,level_energy_tot,prob_tran_tot]
577
+ return out
578
+ #tic()
579
+ #o = readPenNuc2("Sb-127")
580
+ #toc()
581
+ #print(o[-4])
582
+
583
+
584
+ def readPenNuc1(rad):
585
+ '''
586
+ =========
587
+ PARAMETRE
588
+ =========
589
+ rad -- type: str (par exemple: "Am-241") -- radionucléide
590
+
591
+ ======
592
+ RETURN
593
+ ======
594
+ daughter -- indice 0 -- des noyaux fils -- len = nb de noyaux fils
595
+ prob_daug -- indice 1 -- des probabilités de noyaux fils -- len = nb de noyaux fils
596
+ energy_Q -- indice 2 -- des énergies de désintégrations -- len = nb de noyaux fils
597
+
598
+ desin_type_tot -- indice 3 -- des types de désintégrations/particules émis
599
+ len = nb de noyaux fils
600
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
601
+ sous-list de sous-list -- des désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
602
+
603
+ desin_energy_tot -- indice 4 -- des énergies de désintégrations/énergies de patricules émis
604
+ len = nb de noyaux fils
605
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
606
+ sous-list de sous-list -- des énergies de désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
607
+
608
+ desin_prob_tot -- indice 5 -- des probabilités de désintégrations
609
+ len = nb de noyaux fils
610
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
611
+ sous-list de sous-list -- des probabilités de désintégrations possibles de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
612
+
613
+ desin_level_tot -- indice 6 -- des niveaux atteints après des désintégrations
614
+ len = nb de noyaux fils
615
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
616
+ sous-list de sous-list -- des niveaux après des désintégrations de chaque branch -- len de sous-list de sous-list = nb de type de désintégrations de chaque branch
617
+
618
+ prob_branch_tot -- indice 7 -- probabilités de chaque branch
619
+ len = nb de noyaux fils
620
+ sous-list -- des probabilités de branchs de noyau fil -- len de sous-list = nb de branch de chaque fil
621
+
622
+ tran_type_tot -- indice 8 -- transitions possibles
623
+ len = nb de noyaux fils
624
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
625
+ sous-list de sous-list -- des transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
626
+
627
+ tran_energy_tot -- indice 9 -- énergies de transitions
628
+ len = nb de noyaux fils
629
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
630
+ sous-list de sous-list -- des énergies de transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
631
+
632
+ tran_prob_tot -- indice 10 -- probabilités de transitions
633
+ len = nb de noyaux fils
634
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
635
+ sous-list de sous-list -- des probabilités de transitions possibles de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
636
+
637
+ tran_level_tot -- indice 11 -- niveaux de branch correspondants
638
+ len = nb de noyaux fils
639
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
640
+ sous-list de sous-list -- des niveaux de chaque branch avant des transitions -- len de sous-list de sous-list = 1
641
+
642
+ tran_level_end_tot -- indice 12 -- niveaux après des transitions
643
+ len = nb de noyaux fils
644
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
645
+ sous-list de sous-list -- des niveaux après des transitions de chaque branch -- len de sous-list de sous-list = nb de type de transitions de chaque branch
646
+
647
+ level_energy_tot -- indice 13 -- énergies de niveaux
648
+ len = nb de noyaux fils
649
+ sous-list -- des branchs possibles de noyau fil -- len de sous-list = nb de branch de chaque fil
650
+ sous-list de sous-list -- des énergies de niveaux de chaque branch -- len de sous-list de sous-list = 1
651
+ '''
652
+
653
+ url = "http://www.lnhb.fr/nuclides/"+rad+".PenNuc.txt"
654
+ file = rq.urlopen(url)
655
+
656
+ # Format the data
657
+ decayData = []
658
+ for line in file:
659
+ decayData.append(line.decode("utf-8"))
660
+ if "NDA " in decayData[-1]: decayData[-1] = decayData[-1].replace("NDA ", "NDA; ") # number of daughter
661
+ if "DAU " in decayData[-1]: decayData[-1] = decayData[-1].replace("DAU ", "DAU; ") # daughter
662
+ if "DDE " in decayData[-1]: decayData[-1] = decayData[-1].replace("DDE ", "DDE; ") # daughter description : probability of disintegration to NDA, uncertainty, number of excited levels of NDA; number of branche to NDA
663
+ if "Q " in decayData[-1]: decayData[-1] = decayData[-1].replace("Q ", "Q; ") # total energy of the branch, uncertainty
664
+ if "ALP " in decayData[-1]: decayData[-1] = decayData[-1].replace("ALP ", "ALP; ") # type of the disintegration = alpha
665
+ if "CK " in decayData[-1]: decayData[-1] = decayData[-1].replace("CK ", "CK; ") # type of the disintegration = Electron Capture K shell
666
+ if "CL " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL ", "CL; ") # type of the disintegration = Electron Capture L shell
667
+ if "CL1 " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL1 ", "CL1; ") # type of the disintegration = Electron Capture L shell 1
668
+ if "CL2 " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL2 ", "CL2; ") # type of the disintegration = Electron Capture L shell 2
669
+ if "CL3 " in decayData[-1]: decayData[-1] = decayData[-1].replace("CL3 ", "CL3; ") # type of the disintegration = Electron Capture L shell 3
670
+ if "CM " in decayData[-1]: decayData[-1] = decayData[-1].replace("CM ", "CM; ") # type of the disintegration = Electron Capture M shell
671
+ if "CN " in decayData[-1]: decayData[-1] = decayData[-1].replace("CN ", "CN; ") # type of the disintegration = Electron Capture N shell
672
+ if "BEM " in decayData[-1]: decayData[-1] = decayData[-1].replace("BEM ", "BEM; ") # type disintegration-beta- :branching ratio, uncertainty, level fed in daughter, energy, uncertainty,prohibition factor for beta emission
673
+ if "BEP " in decayData[-1]: decayData[-1] = decayData[-1].replace("BEP ", "BEP; ") # type disintegration-beta+ :branching ratio, uncertainty, level fed in daughter, energy, uncertainty,prohibition factor for beta emission
674
+ if "LED " in decayData[-1]: decayData[-1] = decayData[-1].replace("LED ", "LED; ") # level description:energy of level,uncertainty, number of transitions that depopulate this level,level time,uncertainty,level number
675
+ if "GA " in decayData[-1]: decayData[-1] = decayData[-1].replace("GA ", "GA; ") # type transition: gamma
676
+ if "EK " in decayData[-1]: decayData[-1] = decayData[-1].replace("EK ", "EK; ") # type transition: internal conversion -- electron K
677
+ if "EL " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL ", "EL; ") # type transition: internal conversion -- electron L
678
+ if "EL1 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL1 ", "EL1; ") # type transition: internal conversion -- electron L1
679
+ if "EL2 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL2 ", "EL2; ") # type transition: internal conversion -- electron L2
680
+ if "EL3 " in decayData[-1]: decayData[-1] = decayData[-1].replace("EL3 ", "EL3; ") # type transition: internal conversion -- electron L3
681
+ if "EM " in decayData[-1]: decayData[-1] = decayData[-1].replace("EM ", "EM; ") # type transition: internal conversion -- electron M
682
+ if "EN " in decayData[-1]: decayData[-1] = decayData[-1].replace("EN ", "EN; ") # type transition: internal conversion -- electron N
683
+ if "COM " in decayData[-1]: decayData[-1] = decayData[-1].replace("COM ", "COM; ")
684
+ decayData[-1]=decayData[-1].split(";")
685
+ if "\r\n" in decayData[-1][-1]: decayData[-1][-1] = decayData[-1][-1].replace("\r\n", " ")
686
+
687
+ '''
688
+ ========================
689
+ Repérer chaque noyau fil
690
+ ========================
691
+
692
+ daughter -- noyau(x) fil(s)
693
+ posi_daug -- l'indice de démarcation de noyau fil
694
+ posi_branch -- l'indice de démarcation de chaque branch
695
+ posi_tran -- l'indice de démarcation de transition
696
+ prob_daug -- probabilité de produire des noyaux fils
697
+ nb_branch -- nombre de branch possible au dessus de l'état fonda (n>0)
698
+ energy_Q -- l'énergie de désintégration
699
+
700
+ '''
701
+ daughter = [];posi_daug = [];prob_daug=[];nb_branch=[];energy_Q=[];
702
+ end = len(decayData)
703
+ for indice,line in enumerate(decayData):
704
+ if "NDA" == line[0]:
705
+ nb_daug = int(line[1])
706
+ if "DAU" == line[0]:
707
+ daughter.append(line[1].replace(" ",""))
708
+ if "COM" == line[0] and "Daughter" in line[1]:
709
+ posi_daug.append(indice)
710
+ if "Q" == line[0]:
711
+ energy_Q.append(float(line[1]))
712
+ if "DDE" == line[0]:
713
+ prob_daug.append(float(line[1]))
714
+ nb_branch.append(int(line[-2]))
715
+
716
+ '''
717
+ ==========
718
+ LOOP START
719
+ ==========
720
+
721
+ '''
722
+ posi_end=[]
723
+ desin_type_tot=[];desin_energy_tot=[];desin_prob_tot=[];desin_level_tot=[]
724
+ tran_type_tot=[];tran_energy_tot=[];tran_prob_tot=[];tran_level_end_tot=[];
725
+ tran_level_tot=[];level_energy_tot=[]
726
+ prob_branch_tot=[]
727
+
728
+ '''
729
+ =============
730
+ LOOP DAUGHTER
731
+ =============
732
+ '''
733
+ for i1 in range(nb_daug):
734
+ start_p = posi_daug[i1]
735
+ if i1+1 == nb_daug:
736
+ end_p = end
737
+ else:
738
+ end_p = posi_daug[i1+1]
739
+
740
+ posi_end_i = []
741
+ for i2 in range(start_p,end_p):
742
+ if "COM" == decayData[i2][0] and "Branch" in decayData[i2][1]:
743
+ posi_end_i.append(i2)
744
+ if "COM" == decayData[i2][0] and "Level" in decayData[i2][1]:
745
+ posi_end_i.append(i2)
746
+ if end_p == end:
747
+ posi_end_i.append(end)
748
+ else:
749
+ posi_end_i.append(posi_daug[i1+1])
750
+ posi_end.append(posi_end_i)
751
+
752
+ '''
753
+ ==========================
754
+ LOOP Branch and Transition
755
+ ==========================
756
+ '''
757
+
758
+ desin_type_daug=[];desin_energy_daug=[];desin_prob_daug=[];desin_level_daug=[];
759
+ tran_type_daug=[];tran_energy_daug=[];tran_prob_daug=[];tran_level_end_daug=[];
760
+ tran_level_daug=[];level_energy_daug=[]
761
+ prob_branch_daug=[]
762
+
763
+ for i3 in range(len(posi_end_i)-1):
764
+ start_p1 = posi_end_i[i3]
765
+ end_p1 = posi_end_i[i3+1]
766
+ branch = False
767
+ transition = False
768
+ if "COM" == decayData[start_p1][0] and "Branch" in decayData[start_p1][1]:
769
+ branch=True
770
+ if "COM" == decayData[start_p1][0] and "Level" in decayData[start_p1][1]:
771
+ transition = True
772
+
773
+ '''
774
+ ====================================
775
+ LOOP EACH BLOCK OF BRANCH/TRANSITION
776
+ ====================================
777
+ '''
778
+ tran_type_b=[];tran_prob_b=[];tran_energy_b=[]; tran_level_end_b=[];
779
+ tran_level_b=[];level_energy_b=[]
780
+ desin_type_b=[];desin_energy_b=[];desin_prob_b=[];desin_level_b=[];
781
+
782
+ for i4 in decayData[start_p1+1:end_p1]:
783
+
784
+ if start_p1+1 == end_p1:
785
+ break
786
+ if branch:
787
+ if "ALP" == i4[0]:
788
+ desin_type_b.append("alpha")
789
+ if "BEP" == i4[0]:
790
+ desin_type_b.append("beta+")
791
+ if "BEM" == i4[0]:
792
+ desin_type_b.append("beta")
793
+ if "CK" == i4[0]:
794
+ desin_type_b.append("Atom_K")
795
+ if "CL" == i4[0]:
796
+ desin_type_b.append("Atom_L")
797
+ if "CL1" == i4[0]:
798
+ desin_type_b.append("Atom_L1")
799
+ if "CL2" == i4[0]:
800
+ desin_type_b.append("Atom_L2")
801
+ if "CL3" == i4[0]:
802
+ desin_type_b.append("Atom_L3")
803
+ if "CM" == i4[0]:
804
+ desin_type_b.append("Atom_M")
805
+ if "CN" == i4[0]:
806
+ desin_type_b.append("Atom_N")
807
+ desin_prob_b.append(float(i4[1]))
808
+ desin_level_b.append(int(i4[3]))
809
+ desin_energy_b.append(float(i4[4]))
810
+
811
+ if transition:
812
+ if i4[1] == ' ' or i4[1] == ' ': i4[1] = 0
813
+ if len(i4)>2 and i4[2] == ' ': i4[2] = 0
814
+ if len(i4)>4 and i4[4] == ' ': i4[4] = 0
815
+ if len(i4)>5 and i4[5] == ' ': i4[5] = 0
816
+ if "LED" == i4[0]:
817
+ tran_level_b.append(int(i4[-1]))
818
+ level_energy_b.append(float(i4[1]))
819
+ if i4[0] == "GA" or i4[0] == "EK" or i4[0] == "EL" or i4[0] == "EL1" or i4[0] == "EL2" or i4[0] == "EL3" or i4[0] == "EM" or i4[0] == "EN":
820
+ tran_type_b.append(i4[0])
821
+ tran_prob_b.append(float(i4[1]))
822
+ tran_energy_b.append(float(i4[3]))
823
+ tran_level_end_b.append(float(i4[5]))
824
+
825
+ if branch:
826
+ desin_type_daug.append(desin_type_b)
827
+ desin_energy_daug.append(desin_energy_b)
828
+ desin_prob_daug.append(desin_prob_b)
829
+ desin_level_daug.append(desin_level_b)
830
+
831
+ if transition:
832
+ tran_type_daug.append(tran_type_b)
833
+ tran_energy_daug.append(tran_energy_b)
834
+ tran_prob_daug.append(tran_prob_b)
835
+ tran_level_end_daug.append(tran_level_end_b)
836
+ tran_level_daug.append(tran_level_b)
837
+ level_energy_daug.append(level_energy_b)
838
+
839
+ if len(desin_prob_b)>0:
840
+ desin_prob_array = np.array(desin_prob_b)
841
+ prob_branch_i = np.sum(desin_prob_array)
842
+ if prob_branch_i >= 1:
843
+ prob_branch_i = 1
844
+ prob_branch_daug.append(prob_branch_i)
845
+ elif branch and len(desin_prob_b)==0:
846
+ prob_branch_daug.append(0)
847
+
848
+ tran_type_daug.append([])
849
+ tran_prob_daug.append([])
850
+ tran_energy_daug.append([])
851
+ tran_level_end_daug.append([])
852
+ tran_level_daug.append([])
853
+ level_energy_daug.append([])
854
+
855
+ desin_type_tot.append(desin_type_daug)
856
+ desin_energy_tot.append(desin_energy_daug)
857
+ desin_prob_tot.append(desin_prob_daug)
858
+ desin_level_tot.append(desin_level_daug)
859
+
860
+ tran_type_tot.append(tran_type_daug)
861
+ tran_energy_tot.append(tran_energy_daug)
862
+ tran_prob_tot.append(tran_prob_daug)
863
+ tran_level_end_tot.append(tran_level_end_daug)
864
+ tran_level_tot.append(tran_level_daug)
865
+ level_energy_tot.append(level_energy_daug)
866
+ prob_branch_tot.append(prob_branch_daug)
867
+
868
+ out = [daughter,prob_daug,energy_Q,desin_type_tot,desin_energy_tot,desin_prob_tot,desin_level_tot,prob_branch_tot,tran_type_tot,tran_energy_tot,tran_prob_tot,tran_level_tot,tran_level_end_tot,level_energy_tot]
869
+ return out
870
+
871
+ #tic()
872
+ #o = readPenNuc1("Ag-110m")
873
+ #print(o[-4])
874
+ #toc()
875
+ #===============================================================================================================
876
+ '''
877
+ rad = "Am-244m"
878
+ out1 = readPenNuc1(rad)
879
+ print(rad)
880
+ print(" ")
881
+ print("DAU",out1[0])
882
+ print(" ")
883
+ print("prob_daug",out1[1])
884
+ print(" ")
885
+ print("Q",out1[2])
886
+ print(" ")
887
+ print("desin_type",out1[3],len(out1[3]))
888
+ print(" ")
889
+ print("desin-prob",out1[5],len(out1[5]))
890
+ print(" ")
891
+ print("desin-level",out1[6],len(out1[6]))
892
+ print(" ")
893
+ print("prob-branch",out1[7])
894
+ print(" ")
895
+ print("len-tran-type",len(out1[8]))
896
+ for i in range(len(out1[8])):
897
+ print("fil",i)
898
+ for i1,p1 in enumerate(out1[8][i]):
899
+ print(p1,len(p1))
900
+ print("energy")
901
+ for i2,p2 in enumerate(out1[9][i]):
902
+ print(p2,len(p2))
903
+ print("tran-prob")
904
+ for i4,p4 in enumerate(out1[10][i]):
905
+ print(p4)
906
+ print("end_level")
907
+ for i3,p3 in enumerate(out1[12][i]):
908
+ print(p3,len(p3))
909
+ '''
910
+ #print(readPenNuc1('Tc-99m'))
911
+ #out = readPenNuc1('Tc-99m')
912
+ #print(sampling(out[1]))
913
+ #================================== StoppingPower for alpha particle ===========================================
914
+
915
+ if absolutePath: f_alpha = open('G:\Python_modules\Jialin\Code\Quenching\\alpha_toulene.txt')
916
+ else: f_alpha = open('Quenching/alpha_toulene.txt')
917
+ data_ASTAR = f_alpha.readlines()
918
+ f_alpha.close()
919
+ energy_alph = []
920
+ dEdx_alph = []
921
+ for i in range(np.size(data_ASTAR)):
922
+ data_ASTAR[i] = data_ASTAR[i].split()
923
+ for j in range(2):
924
+ data_ASTAR[i][j] = float(data_ASTAR[i][j])*1e3 # dEdx from MeV.cm2/g to keV.cm2/g; energy from MeV to keV
925
+ energy_alph.append(data_ASTAR[i][0])
926
+ dEdx_alph.append(data_ASTAR[i][1])
927
+
928
+ def stoppingpowerA(e,rho=0.96,energy_alpha=energy_alph,dEdx_alpha=dEdx_alph):
929
+ """
930
+ Estimation of the stopping power of alpha particles using tabulated values form the ASTAR code
931
+ ref: https://dx.doi.org/10.18434/T4NC7P
932
+
933
+ Parameters
934
+ ----------
935
+ e : float
936
+ energy of the alpha particle in keV.
937
+ rho : float, optional
938
+ density of the source in g.cm-3. The default is 0.96.
939
+ energy_alpha : list, optional
940
+ the list of energy (in keV) for which the stopping power was calculated with ASTAR. The default is energy_alph.
941
+ dEdx_alpha : list, optional
942
+ the list of stopping powers (in keV.cm2/g) associated with the energy vector. The default is dEdx_alph.
943
+
944
+ Returns
945
+ -------
946
+ float
947
+ Interpolated ASTAR estimation of the stopping power.
948
+
949
+ """
950
+
951
+ energy_alpha = np.array(energy_alpha)
952
+ dEdx_alpha = np.array(dEdx_alpha)
953
+ dEdx = np.interp(e,energy_alpha ,dEdx_alpha)
954
+ return dEdx*rho #unit keV.cm-1
955
+
956
+ # tic()
957
+ # stoppingpowerA(5000,rho=0.96,energy_alpha=energy_alph,dEdx_alpha=dEdx_alph)
958
+ # toc() # 0 s
959
+
960
+ #===============================================================================================
961
+
962
+ #======================== Nouveau modèle pour calculer le pouvoir d'arrête d'électron ========
963
+
964
+
965
+ if absolutePath: file_TanXia=open('G:\Python_modules\Jialin\Code\Quenching\\TandataUG.txt', "r")
966
+ else: file_TanXia=open('Quenching/TandataUG.txt', "r")
967
+ data_TanXia=file_TanXia.read(); file_TanXia.close()
968
+ data_TanXia=data_TanXia.split("\n"); data_TanXia_f = np.empty(len(data_TanXia))
969
+ for i, x in enumerate(data_TanXia):
970
+ if i<len(data_TanXia)-1: data_TanXia_f[i]=float(x)
971
+
972
+ def stoppingpower(e,rho=0.96,Z=5.2,A=11.04,emin=0,file=data_TanXia_f):
973
+ """
974
+ The stopping power of electrons between 20 keV and 1000 keV is a mixture of a radiative loss model [1], and a collision model [2] that has been validated agaisnt the NIST model ESTAR [3] recommanded by the ICRU Report 37 [4].
975
+ At low energy - between 10 eV and 20 keV - the model from Tan and Xia [5] is implemented.
976
+ Refs:
977
+ [1] https://doi.org/10.1016/0020-708x(82)90244-7
978
+ [2] https://www.ijstr.org/final-print/jan2017/Calculations-Of-Stopping-Power-And-Range-Of-Electrons-Interaction-With-Different-Material-And-Human-Body-Parts.pdf
979
+ [3] https://dx.doi.org/10.18434/T4NC7P
980
+ [4] ICRU Report 37, Stopping Powers for Electrons and Positrons
981
+ [5] https://doi.org/10.1016/j.apradiso.2011.08.012
982
+
983
+ Parameters
984
+ ----------
985
+ e : float
986
+ Energy of the electron in eV.
987
+ rho : float, optional
988
+ density of the source in g.cm-3. The default is 0.96.
989
+ Z : float, optional
990
+ mean charge number of the source. The default is 5.2.
991
+ A : float, optional
992
+ mean mass number of the source. The default is 11.04.
993
+ emin : float, optional
994
+ the minimal energy to consider. The default is 0.
995
+ file : list, optional
996
+ tabulated data form the Tan and Xia model. The default is data_TanXia_f.
997
+
998
+ Returns
999
+ -------
1000
+ dEdx : float
1001
+ Calculated stopping power in MeV.cm-1.
1002
+
1003
+ """
1004
+ # e:eV ;rho: g.cm-3
1005
+ mc_2 = 0.511 #MeV
1006
+ I = 65e-6 #MeV
1007
+ NA = 6.02e23
1008
+ ahc = 1.437e-13 #MeV.cm
1009
+ if e>=20000:
1010
+ e1 = e*1e-6 #MeV
1011
+ gamma = (e1+mc_2)/mc_2
1012
+ gamma_2 = gamma*gamma
1013
+ beta = np.sqrt(1-(1/gamma_2))
1014
+ beta_2 = beta**2
1015
+ tau = e1/mc_2
1016
+ terma = np.log(tau**2*(tau+2)/2)
1017
+ termb = 1+tau*tau/8-(2*tau+1)*np.log(2)
1018
+ termc = (tau+1)**2
1019
+ B0 = terma + termb/termc
1020
+ sc = 0.1535/beta_2*Z/A*(B0-2*np.log(I/mc_2))
1021
+ term3 = NA*(Z**2)*rho*(e1+mc_2)/(137*(mc_2**2)*A)
1022
+ term4 = 4* np.log(2*gamma) -4/3
1023
+ sr = (ahc**2)*term3*term4
1024
+ #if T<1:sr=0
1025
+ dEdx = (sc + sr)*rho #MeV.cm-1
1026
+ else:
1027
+ if e>emin:
1028
+ dEdx=float(file[int(e)]) #MeV.cm-1
1029
+ else:
1030
+ dEdx=0
1031
+ if dEdx<0:
1032
+ dEdx=0
1033
+ return dEdx
1034
+
1035
+ # tic()
1036
+ # stoppingpower(100,rho=0.96,Z=5.2,A=11.04,emin=0,file=data_TanXia_f)
1037
+ # toc() # 0 s
1038
+ #===================================================================================================
1039
+
1040
+ #===================================================================================================
1041
+ #============================tracer stopping power of electron and alpha ===========================
1042
+
1043
+ '''
1044
+ e1 = np.linspace(10,1.99e4,10000)
1045
+ e2 = np.linspace(1.99e4,1e8,20000)
1046
+ sp1 = []
1047
+ for i in e1:
1048
+ sp1.append(stoppingpower(i))
1049
+ sp2=[]
1050
+ for i in e2:
1051
+ sp2.append(stoppingpower(i))
1052
+
1053
+ ea = np.linspace(1,8e3,4000)
1054
+ spa = []
1055
+ for i in ea:
1056
+ spa.append(stoppingpowerA(i)*1e-3)
1057
+ x = ea*1e3
1058
+ plt.plot(e1,sp1,color='blue',label="pouvoir d'arrête électron")
1059
+ plt.plot(e2,sp2,color='blue')
1060
+ plt.plot(x,spa,label="pouvoir d'arrête alpha")
1061
+ plt.xscale('log')
1062
+ plt.yscale('log')
1063
+ plt.title("pouvoir d'arrête d'electron et alpha")
1064
+ plt.ylabel("pouvoir d'arrête/MeV.cm-1")
1065
+ plt.xlabel('énergie cinétique/eV')
1066
+ plt.legend(fontsize=10,loc='best')
1067
+ plt.savefig('Quenching/stoppingpowerE_A.png')
1068
+
1069
+ '''
1070
+
1071
+ #=============================================================================================
1072
+
1073
+ #==================== Fonction pour lire BetaShape ========================================
1074
+ file_betashape = "decayData//All-nuclides_BetaShape.zip"
1075
+ z_betashape = zf.ZipFile(file_betashape)
1076
+
1077
+ def readBetaShape(rad,mode,level,z=z_betashape):
1078
+ """
1079
+ This funcion reads the beta spectra calculated by the code BetaShape and published in the DDEP web page.
1080
+ refs:
1081
+ https://doi.org/10.1103/PhysRevC.92.059902
1082
+ http://www.lnhb.fr/ddep_wg/
1083
+
1084
+ Parameters
1085
+ ----------
1086
+ rad : string
1087
+ identifier of the radionuclide. e.g. 'Na-22'
1088
+ mode : string
1089
+ identifier of the decay mode. 'beta-' or 'beta+'
1090
+ level : int
1091
+ level of the daughter after decay. 0,1,2,3 ....
1092
+ Returns
1093
+ -------
1094
+ e : list
1095
+ the energy vector in keV.
1096
+ dNdx : list
1097
+ the probability density in keV-1.
1098
+
1099
+ """
1100
+
1101
+ Rad = rad.replace('-','')
1102
+ name_doc = Rad+'/'+mode+'_'+Rad+'_'+ "trans" + str(level) +'.bs'
1103
+ with z.open(name_doc) as file_trans:
1104
+ data = file_trans.readlines()
1105
+
1106
+ for i in range(np.size(data)):
1107
+ data[i] = str(data[i])
1108
+ data[i] = data[i].replace("b'",'')
1109
+ data[i] = data[i].replace("\\r\\n",'')
1110
+ data[i] = data[i].replace("'",'')
1111
+ for i in range(np.size(data)):
1112
+ data[i] = data[i].split()
1113
+ e = []
1114
+ dNdx = []
1115
+
1116
+ while [] in data:
1117
+ data.remove([])
1118
+
1119
+ for i in range(len(data)):
1120
+ ind = i
1121
+ if data[i][0] == 'E(keV)':break
1122
+
1123
+ for j in range(i+1,len(data)):
1124
+ e.append(float(data[j][0])) # convert to float
1125
+ dNdx.append(float(data[j][1])) # convert to float
1126
+ dNdx /= sum(np.asarray(dNdx)) # normalization
1127
+ dNdx = list(dNdx)
1128
+ return e, dNdx
1129
+
1130
+ #tic()
1131
+ #e,p = readBetaShape('C-11','beta+',0)
1132
+ #toc()
1133
+ #print(p,type(p))
1134
+
1135
+ # tic()
1136
+ # e,p = readBetaShape('C-11','beta+',0)
1137
+ # toc() # 0.016 s > 0s
1138
+
1139
+ def readTDCR17spectra(rad):
1140
+ file = open("decayData/spectra/spectrumTDCR17_"+rad+".dat")
1141
+ data = file.read()
1142
+ file.close()
1143
+ data = data.split("\n")
1144
+ e = []; r = []
1145
+ for i in data:
1146
+ if "keV" not in i:
1147
+ a = i.split(" ")
1148
+ if len(a)>1:
1149
+ e.append(float(a[1])*1e-3)
1150
+ r.append(float(a[2]))
1151
+ return e, r
1152
+
1153
+
1154
+ # tic()
1155
+ # e,r = readBetaShape("Nb-95m", "beta-", 1)
1156
+ # # print(e[-1])
1157
+ # toc() # 0.016 s > 0 s
1158
+
1159
+ #=====================================================================================
1160
+
1161
+ ## Display beta spectra
1162
+ # rplot = "S-35"
1163
+ # out = readBetaShape(rplot, "beta-", "tot"); print(sum(out[1]))
1164
+ # out_t = readTDCR17spectra(rplot); print(sum(out_t[1])) # TDCR17 spectra
1165
+ # plt.figure("beta spectrum")
1166
+ # plt.clf()
1167
+ # plt.plot(out[0],out[1]/(out[0][1]-out[0][0]),label='Beta spectrum - BetaShape',ls='-',color='red',lw=3)
1168
+ # plt.plot(out_t[0],np.asarray(out_t[1])/(out_t[0][1]-out_t[0][0]),label='Beta spectrum - TDCR17',ls='-',color='blue',lw=3)
1169
+ # plt.xscale('linear')
1170
+ # plt.legend(fontsize=12,loc='best')
1171
+ # plt.xlabel(r'$E$ /keV', fontsize=12)
1172
+ # plt.ylabel(r'd$N$/d$E$ /keV$^{-1}$',fontsize=12)
1173
+ # plt.savefig("decayData/spectra/BetaSpectrum_"+rplot+".png")
1174
+
1175
+ #=======================================================================================
1176
+
1177
+ #============================ Fonction quenching =====================================
1178
+
1179
+ def E_quench_e(e,kB,nE):
1180
+ """
1181
+ This function calculate the quenched energy of electrons according to the Birks model of scintillation quenching
1182
+
1183
+ Parameters
1184
+ ----------
1185
+ e : float
1186
+ energy of the electron in eV.
1187
+ kB : float
1188
+ Birks constant in cm/MeV.
1189
+
1190
+ Returns
1191
+ -------
1192
+ float
1193
+ Quenched energy in eV.
1194
+
1195
+ """
1196
+
1197
+ e_dis = np.linspace(0,e,nE)
1198
+ delta = e_dis[2] - e_dis[1]
1199
+ q = 0
1200
+ for i in e_dis:
1201
+ q += delta/(1+kB*stoppingpower(i))
1202
+ return q
1203
+
1204
+ def E_quench_a(e,kB,nE):
1205
+ """
1206
+ This function calculate the quenched energy alpha particles according to the Birks model of scintillation quenching
1207
+
1208
+ Parameters
1209
+ ----------
1210
+ e : float
1211
+ energy of the alpha particle in keV.
1212
+ kB : float
1213
+ Birks constant in cm/keV.
1214
+
1215
+ Returns
1216
+ -------
1217
+ float
1218
+ Quenched energy in keV.
1219
+
1220
+ """
1221
+
1222
+ e_dis = np.linspace(1,e,nE)
1223
+ delta = e_dis[2] - e_dis[1]
1224
+ q = 0
1225
+ for i in e_dis:
1226
+ q += delta/(1+kB*stoppingpowerA(i))
1227
+ return q
1228
+
1229
+ #=========================================================================================
1230
+
1231
+
1232
+
1233
+ #print(E_quench_e(3.996e5,1e-2,1000)*1e-3)
1234
+
1235
+ #======================================================================================
1236
+
1237
+ #========================= Tracer les courbes avec kB différents ======================
1238
+
1239
+ '''
1240
+
1241
+ # s1 = []
1242
+ # s2 = []
1243
+ # s3 = []
1244
+ # x = np.linspace(5,8000,4000)
1245
+
1246
+ # for i in x:
1247
+ # s1.append(E_quench_a(i,kB=7e-6)/i)
1248
+ # s2.append(E_quench_a(i,kB=1e-5)/i)
1249
+ # s3.append(E_quench_a(i,kB=1.4e-5)/i)
1250
+
1251
+ # plt.plot(x,s1,label='kB=0.007cm/MeV',color='green',lw=2)
1252
+ # plt.plot(x,s2,label='kB=0.01cm/MeV',ls=':',color='red',lw=3)
1253
+ # plt.plot(x,s3,label='kB=0.014cm/MeV')
1254
+ # plt.xscale('log')
1255
+ # #plt.yscale('log')
1256
+ # plt.legend(fontsize=12,loc='best')
1257
+ # plt.xlabel('E de particule/keV')
1258
+ # plt.ylabel("énergie d'extinction/E")
1259
+ # plt.savefig("Quenching/beta 100-10K E_Q sur E.png")
1260
+
1261
+ #'''
1262
+ #============================================================================================
1263
+
1264
+ #============================================================================================
1265
+
1266
+ #========================= énergie gamma ===================================================
1267
+ #'''
1268
+ if absolutePath:
1269
+ fp1 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_p_1_200k.txt' #gamma-10ml-1-200keV-niveau 0
1270
+ fp2 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_p_200_2000k.txt' #gamma-10ml-200-2000keV-niveau 0
1271
+ fp3 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_p_2000_10000k.txt' #gamma-10ml-2000-10000keV-niveau 0
1272
+ fe = "G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/E_depose.txt"
1273
+ else:
1274
+ fp1 = 'MCNP-MATRIX/matrice/fichier/matrice_p_1_200k.txt' #gamma-10ml-1-200keV-niveau 0
1275
+ fp2 = 'MCNP-MATRIX/matrice/fichier/matrice_p_200_2000k.txt' #gamma-10ml-200-2000keV-niveau 0
1276
+ fp3 = 'MCNP-MATRIX/matrice/fichier/matrice_p_2000_10000k.txt' #gamma-10ml-2000-10000keV-niveau 0
1277
+ fe = "MCNP-MATRIX/matrice/fichier/E_depose.txt"
1278
+ '''
1279
+ data1 = f1.readlines()
1280
+ data2 = f2.readlines()
1281
+ data3 = f3.readlines()
1282
+ data_e = fe.readlines()
1283
+
1284
+ Matrice1 = np.zeros((1003,200))
1285
+ Matrice2 = np.zeros((1003,901))
1286
+ Matrice3 = np.zeros((1003,801))
1287
+ Matrice_e = np.zeros((1002,3))
1288
+
1289
+ for i in range(1002):
1290
+ data_e[i] = data_e[i].split()
1291
+ for j in range(3):
1292
+ Matrice_e[i][j] = float(data_e[i][j])
1293
+ for i in range(1003):
1294
+ data1[i] = data1[i].split()
1295
+ data2[i] = data2[i].split()
1296
+ data3[i] = data3[i].split()
1297
+ for j in range(200):
1298
+ Matrice1[i][j] = float(data1[i][j])
1299
+ for k in range(901):
1300
+ Matrice2[i][k] = float(data2[i][k])
1301
+ for l in range(801):
1302
+ Matrice3[i][l] = float(data3[i][l])
1303
+ '''
1304
+
1305
+ def read_matrice(path,niveau):
1306
+ f = open(path)
1307
+ data = f.readlines()
1308
+ if niveau == 0:
1309
+ taille_x = 200
1310
+ taille_y = 1003
1311
+ elif niveau == 1:
1312
+ taille_x = 901
1313
+ taille_y = 1003
1314
+ elif niveau == 2:
1315
+ taille_x = 801
1316
+ taille_y = 1003
1317
+ elif niveau=='e':
1318
+ taille_x = 3
1319
+ taille_y = 1002
1320
+
1321
+ matrice = np.zeros((taille_y,taille_x))
1322
+ for i in range(taille_y):
1323
+ data[i] = data[i].split()
1324
+ for j in range(taille_x):
1325
+ matrice[i][j] = float(data[i][j])
1326
+ return matrice
1327
+
1328
+
1329
+ Matrice10_p_1 = read_matrice(fp1,0)
1330
+ Matrice10_p_2 = read_matrice(fp2,1)
1331
+ Matrice10_p_3 = read_matrice(fp3,2)
1332
+ Matrice_e = read_matrice(fe,'e')
1333
+
1334
+ def energie_dep_gamma(e_inci,*,matrice10_1=Matrice10_p_1,matrice10_2=Matrice10_p_2,matrice10_3=Matrice10_p_3,ed=Matrice_e):
1335
+ """
1336
+ ----------
1337
+ Parameters
1338
+ ----------
1339
+ e_inci : float
1340
+ l'énergie incidente de particule.
1341
+ * : TYPE
1342
+ DESCRIPTION.
1343
+ matrice10_1 : matrix
1344
+ matrice de photon de 1-200keV de solution 10ml.
1345
+ matrice2 : TYPE, optional
1346
+ matrice de photon de 200-2000keV de solution 10ml.
1347
+ matrice3 : TYPE, optional
1348
+ matrice de photon de 2000-10000keV de solution 10ml.
1349
+ ed : TYPE, optional
1350
+ matrice de bins d'énergie. colonne 0: 1-200keV; colonne 1: 200-2000keV
1351
+
1352
+ Returns
1353
+ -------
1354
+ result : float
1355
+ l'énergie déposée.
1356
+
1357
+ """
1358
+ ## sort keV / entrée : keV
1359
+ if e_inci <= 200:
1360
+ index = int(e_inci) # index de colonne de la matrice de l'énergie incidente la plus proche
1361
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_1_200k.txt'
1362
+ matrice = matrice1
1363
+ #taille_x = 200
1364
+ e = ed[:,0]
1365
+
1366
+ elif e_inci <= 2000:
1367
+ index = int((e_inci-200)/2)
1368
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_200_2000k.txt'
1369
+ matrice = matrice2
1370
+ #taille_x = 901
1371
+ e = ed[:,1]
1372
+
1373
+ else:
1374
+ index = (int(e_inci)-2000)//10
1375
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_2000_10000k.txt'
1376
+ matrice = matrice3
1377
+ #taille_x = 801
1378
+ e = ed[:,2]
1379
+
1380
+ '''
1381
+ with open(doc) as f:
1382
+ data = f.readlines()
1383
+
1384
+ matrice = np.zeros((1002,taille_x))
1385
+
1386
+ for i in range(1002):
1387
+ data[i] = data[i].split()
1388
+ for j in range(taille_x):
1389
+ matrice[i][j] = float(data[i][j])
1390
+ '''
1391
+ inde = sampling(matrice[1:,index])
1392
+ if inde == 1 : result = 0
1393
+ #elif e_inci<25: result = e[inde-1]*1e3*e_inci/matrice[0][index]
1394
+ else: result = e[inde]*1e3*e_inci/matrice[0][index]
1395
+ if result > e_inci: result = e_inci
1396
+ return result
1397
+
1398
+ #for i in range(50):
1399
+ #print(energie_dep_gamma(511))
1400
+
1401
+
1402
+ if absolutePath:
1403
+ fe1 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_beta-_1_200k.txt' # electron-10ml-1-200keV-niveau 0
1404
+ fe2 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_beta-_200_2000k.txt' # electron-10ml-200-2000keV-niveau 1
1405
+ fe3 = 'G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/matrice_beta-_2000_10000k.txt' # electron-10ml-2000-10000keV-niveau 2
1406
+ fe = "G:\Python_modules\Jialin\Code\\MCNP-MATRIX/matrice/fichier/E_depose.txt" # electron-10ml-énergie-niveau 'e'
1407
+ else:
1408
+ fe1 = 'MCNP-MATRIX/matrice/fichier/matrice_beta-_1_200k.txt' # electron-10ml-1-200keV-niveau 0
1409
+ fe2 = 'MCNP-MATRIX/matrice/fichier/matrice_beta-_200_2000k.txt' # electron-10ml-200-2000keV-niveau 1
1410
+ fe3 = 'MCNP-MATRIX/matrice/fichier/matrice_beta-_2000_10000k.txt' # electron-10ml-2000-10000keV-niveau 2
1411
+ fe = "MCNP-MATRIX/matrice/fichier/E_depose.txt" # electron-10ml-énergie-niveau 'e'
1412
+
1413
+
1414
+
1415
+ Matrice10_e_1 = read_matrice(fe1,0)
1416
+ Matrice10_e_2 = read_matrice(fe2,1)
1417
+ Matrice10_e_3 = read_matrice(fe3,2)
1418
+ #Matrice_e = read_matrice(fe,'e')
1419
+
1420
+
1421
+ def energie_dep_beta(e_inci,*,matrice10_1=Matrice10_e_1,matrice10_2=Matrice10_e_2,matrice10_3=Matrice10_e_3,ed=Matrice_e):
1422
+ """
1423
+ ----------
1424
+ Parameters
1425
+ ----------
1426
+ e_inci : float
1427
+ l'énergie incidente de particule.
1428
+ * : TYPE
1429
+ DESCRIPTION.
1430
+ matrice10_1 : matrix
1431
+ matrice d'électrons de 1-200keV de solution 10ml.
1432
+ matrice2 : TYPE, optional
1433
+ matrice d'électrons de 200-2000keV de solution 10ml.
1434
+ matrice3 : TYPE, optional
1435
+ matrice d'électrons de 2000-10000keV de solution 10ml.
1436
+ ed : TYPE, optional
1437
+ matrice de bins d'énergie. colonne 0: 1-200keV; colonne 1: 200-2000keV
1438
+
1439
+ Returns
1440
+ -------
1441
+ result : float
1442
+ l'énergie déposée.
1443
+
1444
+ """
1445
+ ## sort keV / entrée : keV
1446
+ if e_inci <= 200:
1447
+ index = int(e_inci) # index de colonne de la matrice de l'énergie incidente la plus proche
1448
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_1_200k.txt'
1449
+ matrice = matrice10_1
1450
+ #taille_x = 200
1451
+ e = ed[:,0]
1452
+
1453
+ elif e_inci <= 2000:
1454
+ index = int((e_inci-200)/2)
1455
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_200_2000k.txt'
1456
+ matrice = matrice10_2
1457
+ #taille_x = 901
1458
+ e = ed[:,1]
1459
+
1460
+ else:
1461
+ index = (int(e_inci)-2000)//10
1462
+ #doc = 'MCNP-MATRIX/matrice/matrice_p_2000_10000k.txt'
1463
+ matrice = matrice10_3
1464
+ #taille_x = 801
1465
+ e = ed[:,2]
1466
+
1467
+ inde = sampling(matrice[1:,index])
1468
+ if inde == 1 : result = 0
1469
+ #elif e_inci<25: result = e[inde-1]*1e3*e_inci/matrice[0][index]
1470
+ else: result = e[inde]*1e3*e_inci/matrice[0][index]
1471
+ if result > e_inci: result = e_inci
1472
+ return result
1473
+
1474
+ '''
1475
+ r = []
1476
+ for i in range(10):
1477
+ r.append(energie_dep_beta(17.055))
1478
+ print(r)
1479
+ '''
1480
+ #print(Matrice_e[0:5,:])
1481
+
1482
+ # tic()
1483
+ # energie_dep_gamma(800)
1484
+ # toc() # 0 s
1485
+
1486
+
1487
+
1488
+ ## Non parametric regression
1489
+
1490
+ # def regress(x,y):
1491
+ # z = sm.nonparametric.lowess(y, x, return_sorted = True)
1492
+ # return z
1493
+
1494
+
1495
+
1496
+ def writeEffcurves(x,y,uy,rad,p,kB,SDT):
1497
+ if SDT == "S":
1498
+ file = open("EfficiencyCurves/"+''.join(rad)+"/EffS_"+''.join(rad)+'_'+''.join(str(p))+'_'+str(kB)+".txt","w")
1499
+ elif SDT == "D":
1500
+ file = open("EfficiencyCurves/"+''.join(rad)+"/EffD_"+''.join(rad)+'_'+''.join(str(p))+'_'+str(kB)+".txt","w")
1501
+ elif SDT == "T":
1502
+ file = open("EfficiencyCurves/"+''.join(rad)+"/EffT_"+''.join(rad)+'_'+''.join(str(p))+'_'+str(kB)+".txt","w")
1503
+ else:
1504
+ print("Warning: unknown profil type")
1505
+ for i, xi in enumerate(x):
1506
+ file.write(str(xi)+" "+str(y[i])+" "+str(uy[i])+"\n")
1507
+ file.close()
1508
+
1509
+ #======================== read ENSDF ============================================
1510
+ def transf_name(rad): # transformer le nom de rad par exemple '11C' à 'C11'
1511
+ """
1512
+ ---------
1513
+ PARAMETRE
1514
+ ---------
1515
+ rad -- type: str par exemple '108AG'
1516
+
1517
+ ------
1518
+ RETURN
1519
+ ------
1520
+ RAD -- type: str par exemple 'AG108' qui correspond à la structure de fille de PenNuc
1521
+
1522
+ """
1523
+ # rad -- type : str par exemple '108AG'
1524
+
1525
+ name_lis = re.split('(\d+)',rad)
1526
+ RAD = name_lis[2]+name_lis[1]
1527
+ return RAD
1528
+
1529
+ #print(transf_name('108PD'))
1530
+
1531
+ file_ensdf = 'decayData//All-nuclides_Ensdf.zip'
1532
+ z_ensdf = zf.ZipFile(file_ensdf)
1533
+ #print(z.namelist())
1534
+ def readEShape(rad, *, z=z_ensdf):
1535
+ """
1536
+ --------------------------------------------------
1537
+ pour lire les fichiers dans All-nuclides_Ensdf.zip
1538
+ --------------------------------------------------
1539
+ ---------
1540
+ PARAMETRE
1541
+ ---------
1542
+ rad -- type: str par exemple 'Ag-108'
1543
+ z -- ENSDF files
1544
+
1545
+ ------
1546
+ RETURN
1547
+ ------
1548
+ daug_name -- type: list -- les filles de désintégration
1549
+ Energy ----- type: list -- chaque élément comprend toutes les énergies de transition de la fille de même indice
1550
+ Prob ------- type: list -- chaque élément comprend toutes les proba de transition de la fille de même indice
1551
+ Type ------- type: list -- chaque élément comprend touts les types de transition de la fille de même indice
1552
+
1553
+ """
1554
+
1555
+ name = rad + '.txt'
1556
+ with z.open(name) as f:
1557
+ data = f.readlines()
1558
+ nl = np.size(data)
1559
+ #print(data)
1560
+ for i in range(nl):
1561
+ data[i] = str(data[i])
1562
+ data[i] = data[i].replace("b",'')
1563
+ data[i] = data[i].replace("\\r\\n",'')
1564
+ data[i] = data[i].replace("'",'')
1565
+ if "\\n" in data[i]:data[i] = data[i].replace("\\n","") # pour traiter "\\n" dans Mn-52 et Mn-52m (cas particuliers)
1566
+ #print(data)
1567
+ for i in range(nl):
1568
+ data[i] = data[i].split()
1569
+
1570
+ for i in range(nl):
1571
+ if i>0 and ('L' in data[i]) and ("AUGER" in data[i]) and ("|]" in data[i-1]):
1572
+ data.insert(i,[data[i][0],'T'])
1573
+ #print(data)
1574
+ index_auger = []
1575
+ index_end = []
1576
+ daug_name = []
1577
+ posi = []
1578
+ for i,p in enumerate(data):
1579
+ if 'DECAY' in p:
1580
+ daug_name.append(transf_name(p[0]))
1581
+ if 'Auger' in p:
1582
+ index_auger.append(i)
1583
+ if len(p)==2 and 'T' in p:
1584
+ posi.append(i)
1585
+ if 'P' in p:
1586
+ index_end.append(i)
1587
+ posi.append(i)
1588
+
1589
+ Energy = [] # enregistrer les résultats (énergie) complètes
1590
+ energy = [] # enregistrer les résultats (énergie) d'une fille
1591
+ Type = [] # enregistrer les résultats (type de transition) complètes
1592
+ type_ = [] # enregistrer les résultats (type de transition) d'une fille
1593
+ Prob = [] # enregistrer les résultats (proba de transition) complètes
1594
+ prob = [] # enregistrer les résultats (proba de transition) d'une fille
1595
+
1596
+ for i in range(len(posi)-1):
1597
+ start = posi[i]+1
1598
+ end = posi[i+1]
1599
+ d = data[start:end] # bloc
1600
+ e = [] # enregistrer les résultats (énergie) d'un bloc
1601
+ prob_b = [] # enregistrer les résultats (proba) d'un bloc
1602
+ type_b = [] # enregistrer les résultats (type) d'un bloc
1603
+ if start==end: # sauter les lignes blaches et continues
1604
+ continue
1605
+ if start-1 in index_end: # sauter le bloc entre deux filles
1606
+ continue
1607
+
1608
+ for n,p1 in enumerate(d):
1609
+ if '-' in p1[2]: # calculer et remplacer les intervalles
1610
+ x = p1[2].split('-')
1611
+ p1[2] = round((float(x[0])+float(x[1]))/2,3)
1612
+
1613
+ if '(total)' in d[0]: # traiter le bloc qui comprend (total) dans la première ligne
1614
+ if '(total)' in p1:
1615
+ prob_b.append(float(p1[3]))
1616
+ e.append(p1[2])
1617
+ type_b.append(p1[-2])
1618
+ continue
1619
+ elif '|]' in p1: # traiter un bloc qui comprend |]
1620
+ if len(p1)>6: # repérer la ligne qui comprend la proba
1621
+ prob_b.append(float(p1[4]))
1622
+ e.append(float(p1[2])) # enregistrer les valeurs d'énergie
1623
+ if 'AUGER' in p1: # traiter le cas d'auger et |]
1624
+ if 'K' in p1[-2]: # Auger K
1625
+ type_b.append('Auger K')
1626
+ else:
1627
+ print('erreur')
1628
+ elif 'X' in p1[-1]: # Rayon X
1629
+ type_b.append(p1[-1][0:3])
1630
+ else: # traiter le cas sans |] ni (total)
1631
+ if len(p1)==4 and 'X' in p1[-1]: # le cas de rayon X sans |] ni (total) ni proba
1632
+ continue # sauter cette ligne
1633
+ elif len(p1)==5 and 'L' in p1: # le cas de Auger L sans |] ni (total) ni proba
1634
+ continue # sauter cette ligne
1635
+ else: # traiter le cas sans |] ni (total) mais complet
1636
+ e.append(float(p1[2])) # enregistrer énergie
1637
+ prob_b.append(float(p1[3])) # enregistrer proba
1638
+ if 'L' in p1:
1639
+ type_b.append('Auger L') # enregistrer type Auger L
1640
+ else:
1641
+ type_b.append(p1[-1][0:3]) # enregistrer type Rayon X
1642
+
1643
+ if len(prob_b)==1 and len(e)>1: # calculer la valeur moyenne et l'enregistrer au cas où |] compris et valeurs complètes
1644
+ energy.append(np.mean(e))
1645
+ prob.append(prob_b[0])
1646
+ type_.append(type_b[0])
1647
+ elif len(e)==len(prob_b) and len(e)>=1: # enregistrer les valeurs au cas où sans |] et valeurs complètes
1648
+ for i in range(len(e)):
1649
+ energy.append(e[i])
1650
+ prob.append(prob_b[i])
1651
+ type_.append(type_b[i])
1652
+ if end in index_end or end+1 in index_end: # enregistrer les résultats à la fin d'une fille
1653
+ Energy.append(energy)
1654
+ Prob.append(prob)
1655
+ Type.append(type_)
1656
+ energy = []
1657
+ prob = []
1658
+ type_ = []
1659
+ #Energy = np.array(Energy)
1660
+ #Prob = np.array(Prob)
1661
+ return daug_name,Energy,Prob,Type
1662
+
1663
+ # tic()
1664
+ # d,e,p,t = readEShape('Cf-252')
1665
+ # toc() # 0 s
1666
+ #======== tester readEShape ==============
1667
+ # tic()
1668
+ # d,e,p,t = readEShape('Cf-252')
1669
+ #print(d,e,p,t)
1670
+ #d1,e1,p1,t1 = readEShape('At-218')
1671
+ #print(d1,e1,p1,t1)
1672
+ # toc()
1673
+ # print(d,e[0][1],p[1][2],t)
1674
+ # print(' ')
1675
+ # for i in range(len(d)):
1676
+ # print(d[i],e[i],p[i],t[i])
1677
+ # print(' ')
1678
+ # print(len(e[i]),len(p[i]),len(t[i]))
1679
+
1680
+ #============ traiter la relaxation ===============
1681
+ def relaxation_atom(daugther,rad,lacune='defaut'):
1682
+ """
1683
+ ---------
1684
+ PARAMETRE
1685
+ ---------
1686
+ daugther -- type: str -- la fille tirée dans cette itération (par exemple NB95,PD110 etc.)
1687
+ rad ------- type: str -- le radionucléide étudié (par exemple Am-241, C-11 etc.)
1688
+ lacuen ---- type: str -- la lacune atomique (par exemple 'Atom_K','Atom_L' etc.)
1689
+
1690
+ ------
1691
+ RETURN
1692
+ ------
1693
+ Type ---- type de transition: Auger L ou K ou Rayon X
1694
+ Energy -- énergie correspondante
1695
+
1696
+ """
1697
+ daug_name,Energy,Prob,Type = readEShape(rad) # tirer les vecteurs de rad d'Ensdf
1698
+
1699
+ index_daug = daug_name.index(daugther) # repérer l'indice de fille correspondante
1700
+
1701
+ Energie = np.array(Energy[index_daug]) # tirer le vecteur d'énergie
1702
+ probability = np.array(Prob[index_daug]) # tirer le vecteur de proba
1703
+ type_transi = Type[index_daug] # tirer le vecteur de type
1704
+
1705
+
1706
+ if len(probability) > 0: # le cas où le vecteur de proba/energie/type n'est pas vide
1707
+ '''
1708
+ posi_L = []
1709
+ posi_K = []
1710
+
1711
+ for i, p in enumerate(type_transi): # repérer les indices de transition L ou K
1712
+ if 'L' in p:
1713
+ posi_L.append(i) # enregistrer la posotion de transition L
1714
+
1715
+ elif 'K' in p:
1716
+ posi_K.append(i) # enregistrer la posotion de transition L
1717
+ '''
1718
+ if 'L' in lacune: # traiter le transition de couche L
1719
+ prob_2 = []
1720
+ energy_2 = []
1721
+ type_2 = []
1722
+ for il, pl in enumerate(type_transi):
1723
+ if 'L' in pl:
1724
+ prob_2.append(probability[il]) # enregistrer les proba de transition L
1725
+ energy_2.append(Energie[il]) # enregistrer les energies de transition L
1726
+ type_2.append(type_transi[il]) # enregistrer les types de transition L
1727
+
1728
+ elif 'K' in lacune: # traiter le transition de couche K
1729
+ prob_2 = []
1730
+ energy_2 = []
1731
+ type_2 = []
1732
+ for ik, pk in enumerate(type_transi):
1733
+ if 'K' in pk:
1734
+ prob_2.append(probability[ik]) # enregistrer les proba de transition K
1735
+ energy_2.append(Energie[ik]) # enregistrer les energie de transition K
1736
+ type_2.append(type_transi[ik]) # enregistrer les type de transition K
1737
+
1738
+ #elif lacune=='defaut': # traiter le cas particulier qui ne précise pas la lacune
1739
+ #prob_2 = probability
1740
+ #energy_2 = Energie
1741
+ #type_2 = type_transi
1742
+
1743
+ else: # try to debugg
1744
+ # print("issue: ", lacune)
1745
+ prob_2 = 0 #probability
1746
+ energy_2 = 0 # Energie
1747
+ #if "M" in lacune:
1748
+ #type_2 = "Atom_M" #type_transi
1749
+ #if "N" in lacune:
1750
+ #type_2 = "Atom_N"
1751
+
1752
+ # sampling
1753
+ #if len(probability)>1: # le cas où la taille du vecteur de proba supérieur à 1
1754
+
1755
+ #prob_somme = np.sum(prob_2) # calculer la somme de proba
1756
+ #prob_2 /= prob_somme # normaliser la proba
1757
+ if lacune != "Atom_M" and lacune != "Atom_N":
1758
+ if len(prob_2) != 0:
1759
+ prob_2 = np.array(prob_2) # convert to array
1760
+ if len(probability)>1:
1761
+ prob_somme = np.sum(prob_2) # calculer la somme de proba
1762
+ prob_2 /= prob_somme
1763
+ index_fin = sampling(prob_2) # sample in probability of transition
1764
+ type_fin = type_2[index_fin] # type of transition
1765
+ energie_fin = energy_2[index_fin] # energy of the transition
1766
+ else:
1767
+ # print("pas de transition de rayon X ni d'électron Auger pour cette lacune: ",lacune)
1768
+ type_fin = 'NON'
1769
+ energie_fin = 0
1770
+ else:
1771
+ type_fin = 'NON'
1772
+ energie_fin = 0
1773
+ else: # le cas où le vecteur de proba est vide
1774
+ #print("pas de transition de rayon X ni d'électron Auger")
1775
+ type_fin = 'NON'
1776
+ energie_fin = 0
1777
+ return type_fin,energie_fin
1778
+ # tic()
1779
+ # tf,ef = relaxation_atom('CR52', 'Mn-52', 'Atom_K')
1780
+ # toc() # 0 s
1781
+ #print(tf,ef)