ararpy 0.1.199__py3-none-any.whl → 0.2.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.
Files changed (40) hide show
  1. ararpy/Example - Check arr.py +52 -0
  2. ararpy/Example - Granite Cooling History.py +411 -0
  3. ararpy/Example - Plot temperature calibration.py +291 -0
  4. ararpy/Example - Show MDD results.py +561 -0
  5. ararpy/Example - Show all Kfs age spectra.py +344 -0
  6. ararpy/Example - Show random walk results.py +363 -0
  7. ararpy/Example - Tc calculation.py +437 -0
  8. ararpy/__init__.py +3 -4
  9. ararpy/calc/age.py +34 -36
  10. ararpy/calc/arr.py +0 -20
  11. ararpy/calc/basic.py +26 -3
  12. ararpy/calc/corr.py +131 -85
  13. ararpy/calc/plot.py +1 -2
  14. ararpy/calc/raw_funcs.py +41 -2
  15. ararpy/calc/regression.py +224 -132
  16. ararpy/files/arr_file.py +2 -1
  17. ararpy/files/basic.py +0 -22
  18. ararpy/files/calc_file.py +107 -84
  19. ararpy/files/raw_file.py +242 -229
  20. ararpy/smp/basic.py +133 -34
  21. ararpy/smp/calculation.py +6 -6
  22. ararpy/smp/corr.py +339 -153
  23. ararpy/smp/diffusion_funcs.py +345 -36
  24. ararpy/smp/export.py +247 -129
  25. ararpy/smp/info.py +2 -2
  26. ararpy/smp/initial.py +93 -45
  27. ararpy/smp/json.py +2 -2
  28. ararpy/smp/plots.py +144 -164
  29. ararpy/smp/raw.py +11 -15
  30. ararpy/smp/sample.py +222 -181
  31. ararpy/smp/style.py +26 -7
  32. ararpy/smp/table.py +42 -33
  33. ararpy/thermo/atomic_level_random_walk.py +56 -48
  34. ararpy/thermo/basic.py +2 -2
  35. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/METADATA +1 -1
  36. ararpy-0.2.1.dist-info/RECORD +73 -0
  37. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/WHEEL +1 -1
  38. ararpy-0.1.199.dist-info/RECORD +0 -66
  39. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/licenses/LICENSE +0 -0
  40. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/top_level.txt +0 -0
ararpy/smp/corr.py CHANGED
@@ -17,56 +17,46 @@ import re
17
17
 
18
18
  from .. import calc
19
19
  from .sample import Sample
20
+ from . basic import validate_params
20
21
 
21
22
 
22
23
  # =======================
23
- # Corr Gain
24
+ # Corr Blank
24
25
  # =======================
25
- def corr_gain(sample: Sample):
26
+ def corr_blank(sample: Sample):
26
27
  """Blank Correction"""
27
- corrGain = True
28
- gain_corrected = np.zeros([10, sample.Info.experiment.step_num])
29
28
  try:
30
- for i in range(5):
31
- f, sf = np.array(sample.TotalParam[126 + i * 2:128 + i * 2])
32
- sf = f * sf / 100
33
- gain_corrected[i * 2:2 + i * 2] = calc.corr.gain(*sample.SampleIntercept[i * 2:2 + i * 2], f, sf)
34
- except (Exception, BaseException) as e:
35
- print(f"Gain correction failed: \n{traceback.format_exc()}")
29
+ params_to_check = {
30
+ 'unknown intercepts': {'data': sample.SampleIntercept[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
31
+ 'blank intercepts': {'data': sample.BlankIntercept[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
32
+ 'gain factors': {'data': sample.TotalParam[126:136], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
33
+ }
34
+ except (IndexError, AttributeError) as e:
36
35
  raise
37
- for i in range(0, 10, 2):
38
- gain_corrected[i] = [gain_corrected[i][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i])]
39
- gain_corrected[i + 1] = [gain_corrected[i + 1][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i + 1])]
40
- sample.CorrectedValues = copy.deepcopy(gain_corrected)
41
-
36
+ if not validate_params(**params_to_check):
37
+ return
42
38
 
43
- # =======================
44
- # Corr Blank
45
- # =======================
46
- def corr_blank(sample: Sample):
47
- """Blank Correction"""
48
- blank_corrected = np.zeros([10, len(sample.SequenceName)])
39
+ blank_corrected = np.zeros([10, sample.Info.experiment.step_num])
49
40
  try:
50
41
  for i in range(5):
51
- b, sb = copy.deepcopy(sample.BlankIntercept[i * 2: i * 2 + 2])
52
- f, sf = np.array(sample.TotalParam[126 + i * 2:128 + i * 2])
53
- sf = f * sf / 100
54
- _ = calc.corr.gain(*sample.BlankIntercept[i * 2:2 + i * 2], f, sf)
55
- for index in range(len(sample.BlankIntercept[i * 2])):
56
- if sample.TotalParam[111][index]: # use same parameters to correct blank intercepts
57
- b[index] = _[0][index]
58
- sb[index] = _[1][index]
59
- blank_corrected[i * 2:2 + i * 2] = calc.corr.blank(
60
- *sample.CorrectedValues[i * 2:2 + i * 2], b, sb)
42
+ b, sb = np.array(sample.BlankIntercept[i * 2: i * 2 + 2])
43
+ u, su = np.array(sample.SampleIntercept[i * 2: i * 2 + 2])
44
+ f, sf = np.array(sample.TotalParam[126 + i * 2: 128 + i * 2]) # gain factors
45
+ sf = f * sf / 100 # to absolute errors
46
+ u, su = np.array(calc.corr.gain(u, su, f, sf)) # unknown intercepts gain corrected
47
+ _b, _sb = np.array(calc.corr.gain(b, sb, f, sf)) # balnk intercepts gain corrected
48
+ apply_gain_to_blank = np.array(sample.TotalParam[111], dtype=bool)
49
+ b[~apply_gain_to_blank] = _b[~apply_gain_to_blank]
50
+ sb[~apply_gain_to_blank] = _sb[~apply_gain_to_blank]
51
+ blank_corrected[i * 2:2 + i * 2] = calc.corr.blank(u, su, b, sb)
61
52
  except Exception as e:
62
53
  print(traceback.format_exc())
63
- raise ValueError('Blank correction error')
54
+ raise ValueError(f'Blank correction error: {str(e)}')
64
55
  for i in range(0, 10, 2):
65
- blank_corrected[i] = [blank_corrected[i][index] if sample.TotalParam[102][index] else j for index, j in enumerate(sample.CorrectedValues[i])]
66
- blank_corrected[i + 1] = [blank_corrected[i + 1][index] if sample.TotalParam[102][index] else j for index, j in enumerate(sample.CorrectedValues[i + 1])]
56
+ blank_corrected[i] = [blank_corrected[i][index] if sample.TotalParam[102][index] else j for index, j in enumerate(sample.SampleIntercept[i])]
57
+ blank_corrected[i + 1] = [blank_corrected[i + 1][index] if sample.TotalParam[102][index] else j for index, j in enumerate(sample.SampleIntercept[i + 1])]
67
58
  blank_corrected[i] = [0 if j < 0 and sample.TotalParam[101][index] else j for index, j in enumerate(blank_corrected[i])]
68
59
  sample.BlankCorrected = blank_corrected
69
- sample.CorrectedValues = copy.deepcopy(sample.BlankCorrected)
70
60
 
71
61
 
72
62
  # =======================
@@ -74,13 +64,29 @@ def corr_blank(sample: Sample):
74
64
  # =======================
75
65
  def corr_massdiscr(sample: Sample):
76
66
  """Mass Discrimination Correction"""
67
+ try:
68
+ params_to_check = {
69
+ 'blank corrected': {'data': sample.BlankCorrected[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
70
+ 'masses': [
71
+ {'data': sample.TotalParam[71:81:2], 'dtype': float, 'func': lambda x: x > 0, 'class': 'k2', },
72
+ {'data': sample.TotalParam[72:81:2], 'dtype': float, 'class': 'k2', },
73
+ ],
74
+ 'MDF values': {'data': sample.TotalParam[69:71], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
75
+ 'mass discrimination correction method': {
76
+ 'data': sample.TotalParam[100], 'dtype': str, 'func': lambda x: str(x).lower()[0] in ['l', 'e', 'p'], 'class': 'k4',
77
+ },
78
+ }
79
+ except (IndexError, AttributeError) as e:
80
+ raise
81
+ if not validate_params(**params_to_check):
82
+ return
83
+
77
84
  corrMassdiscr = sample.TotalParam[103][0]
78
85
  if not corrMassdiscr:
79
86
  sample.MassDiscrCorrected = copy.deepcopy(sample.BlankCorrected)
80
- sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
81
87
  return
82
88
  MASS = sample.TotalParam[71:81]
83
- mdf_corrected = np.zeros([10, len(sample.SequenceName)])
89
+ mdf_corrected = np.zeros([10, sample.Info.experiment.step_num])
84
90
  try:
85
91
  for i in range(5):
86
92
  if len(sample.BlankCorrected[i * 2:2 + i * 2]) == 0:
@@ -88,12 +94,11 @@ def corr_massdiscr(sample: Sample):
88
94
  mdf_corrected[i * 2:2 + i * 2] = calc.corr.discr(
89
95
  *sample.BlankCorrected[i * 2:2 + i * 2],
90
96
  *sample.TotalParam[69:71], m=MASS[i * 2], m40=MASS[8], isRelative=True,
91
- method=sample.TotalParam[100][0])
97
+ method=sample.TotalParam[100])
92
98
  except Exception as e:
93
99
  print(traceback.format_exc())
94
- raise ValueError(f'Mass discrimination correction error: {e}')
95
- sample.MassDiscrCorrected = mdf_corrected
96
- sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
100
+ raise ValueError(f'Mass discrimination correction error: {str(e)}')
101
+ sample.MassDiscrCorrected = copy.deepcopy(mdf_corrected)
97
102
 
98
103
 
99
104
  # =======================
@@ -109,14 +114,35 @@ def corr_decay(sample: Sample):
109
114
  -------
110
115
 
111
116
  """
112
- decay_corrected = np.zeros([10, len(sample.SequenceName)])
117
+ try:
118
+ params_to_check = {
119
+ 'Ar37': {'data': sample.MassDiscrCorrected[2:4], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
120
+ 'λAr37': {'data': sample.TotalParam[44:46], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
121
+ 'Ar39': {'data': sample.MassDiscrCorrected[6:8], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
122
+ 'λAr39': {'data': sample.TotalParam[42:44], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
123
+ 'irradiation cycles': [
124
+ {'data': sample.TotalParam[27], 'dtype': str, 'func': lambda x: all(
125
+ [len(re.findall(r"\d+", item)) >= 5 for item in list(filter(None, re.split(r'[DS]', x)))[::2]]), 'class': 'k5', },
126
+ {'data': sample.TotalParam[27], 'dtype': str, 'func': lambda x: all(
127
+ [isinstance(float(item), float) for item in list(filter(None, re.split(r'[DS]', x)))[1::2]]), 'class': 'k5', },
128
+ ],
129
+ 'experiment datetime': {'data': sample.TotalParam[31], 'dtype': str, 'func': lambda x: len(re.findall(r"\d+", x)) >= 5, 'class': 'k6', },
130
+ # 'apply Ar37 decay': {'data': sample.TotalParam[104], 'dtype': bool},
131
+ # 'apply Ar39 decay': {'data': sample.TotalParam[105], 'dtype': bool},
132
+ }
133
+ except (IndexError, AttributeError) as e:
134
+ raise
135
+ if not validate_params(**params_to_check):
136
+ return
137
+
138
+ decay_corrected = np.zeros([10, sample.Info.experiment.step_num])
113
139
  try:
114
140
  irradiation_cycles = [list(filter(None, re.split(r'[DS]', each_step))) for each_step in sample.TotalParam[27]]
115
- t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experimental times
116
- t2, t3 = [], [] # t2: irradiation times, t3: irradiation durations
141
+ t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experiment time
142
+ t2, t3 = [], [] # t2: irradiation time, t3: irradiation duration
117
143
  for each_step in irradiation_cycles:
118
- t2.append([re.findall(r"\d+", item) for i, item in enumerate(each_step) if i % 2 == 0])
119
- t3.append([item for i, item in enumerate(each_step) if i % 2 == 1])
144
+ t2.append([re.findall(r"\d+", item) for item in each_step[::2]])
145
+ t3.append([item for item in each_step[1::2]])
120
146
  decay_corrected[2:4] = calc.corr.decay(
121
147
  *sample.MassDiscrCorrected[2:4], t1, t2, t3, *sample.TotalParam[44:46], isRelative=True)
122
148
  decay_corrected[6:8] = calc.corr.decay(
@@ -126,10 +152,11 @@ def corr_decay(sample: Sample):
126
152
  decay_corrected[6] = [0 if i < 0 else i for i in decay_corrected[6]]
127
153
  except Exception as e:
128
154
  print(traceback.format_exc())
129
- raise ValueError('Decay correction correction error')
155
+ raise ValueError(f'Decay correction error: {str(e)}')
130
156
 
131
157
  corrDecay37 = sample.TotalParam[104]
132
158
  corrDecay39 = sample.TotalParam[105]
159
+ sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
133
160
  sample.CorrectedValues[2] = [val if corrDecay37[idx] else 0 for idx, val in enumerate(decay_corrected[2])]
134
161
  sample.CorrectedValues[3] = [val if corrDecay37[idx] else 0 for idx, val in enumerate(decay_corrected[3])]
135
162
  sample.CorrectedValues[6] = [val if corrDecay39[idx] else 0 for idx, val in enumerate(decay_corrected[6])]
@@ -149,20 +176,32 @@ def calc_degas_ca(sample: Sample):
149
176
  -------
150
177
 
151
178
  """
152
- corrDecasCa = sample.TotalParam[106]
153
- # n = len(sample.CorrectedValues[2])
179
+ try:
180
+ params_to_check = {
181
+ 'Ar37Ca': {'data': sample.TotalParam[106], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
182
+ '36/37Ca': {'data': sample.TotalParam[12:14], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
183
+ '38/37Ca': {'data': sample.TotalParam[10:12], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
184
+ '39/37Ca': {'data': sample.TotalParam[8:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
185
+ # 'apply Ca degas': {'data': sample.TotalParam[106], 'dtype': bool},
186
+ }
187
+ except (IndexError, AttributeError) as e:
188
+ raise
189
+ if not validate_params(**params_to_check):
190
+ return
191
+
192
+ corrDegasCa = sample.TotalParam[106]
154
193
  ar37ca = sample.CorrectedValues[2:4]
155
194
  ar39ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[8:10], isRelative=True)
156
195
  ar38ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[10:12], isRelative=True)
157
196
  ar36ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[12:14], isRelative=True)
158
197
  sample.DegasValues[8:10] = copy.deepcopy(ar37ca) # 37Ca
159
- sample.DegasValues[ 4] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[0])] # 36Ca
160
- sample.DegasValues[ 5] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[1])]
161
- sample.DegasValues[18] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[0])] # 38Ca
162
- sample.DegasValues[19] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[1])]
163
- sample.DegasValues[22] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[0])] # 39Ca
164
- sample.DegasValues[23] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[1])]
165
- sample.PublishValues[1] = copy.deepcopy(ar37ca[0])
198
+ sample.DegasValues[ 4] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar36ca[0])] # 36Ca
199
+ sample.DegasValues[ 5] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar36ca[1])]
200
+ sample.DegasValues[18] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar38ca[0])] # 38Ca
201
+ sample.DegasValues[19] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar38ca[1])]
202
+ sample.DegasValues[22] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar39ca[0])] # 39Ca
203
+ sample.DegasValues[23] = [val if corrDegasCa[idx] else 0 for idx, val in enumerate(ar39ca[1])]
204
+ sample.PublishValues[1] = copy.deepcopy(sample.DegasValues[8])
166
205
 
167
206
 
168
207
  # =======================
@@ -178,22 +217,32 @@ def calc_degas_k(sample: Sample):
178
217
  -------
179
218
 
180
219
  """
220
+ try:
221
+ params_to_check = {
222
+ 'Ar39': {'data': sample.CorrectedValues[6:8], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
223
+ 'Ar39Ca': {'data': sample.DegasValues[22:24], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
224
+ '38/39K': {'data': sample.TotalParam[16:18], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
225
+ '40/39K': {'data': sample.TotalParam[14:16], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
226
+ # 'apply K degas': {'data': sample.TotalParam[107], 'dtype': bool},
227
+ }
228
+ except (IndexError, AttributeError) as e:
229
+ raise
230
+ if not validate_params(**params_to_check):
231
+ return
232
+
181
233
  corrDecasK = sample.TotalParam[107]
182
234
  set_negative_zero = sample.TotalParam[101]
183
- # n = len(sample.CorrectedValues[6])
184
235
  ar39k = calc.arr.sub(sample.CorrectedValues[6:8], sample.DegasValues[22:24])
185
236
  ar39k[0] = [0 if val < 0 and set_negative_zero[idx] else val for idx, val in enumerate(ar39k[0])]
186
237
  ar40k = calc.arr.mul_factor(ar39k, sample.TotalParam[14:16], isRelative=True)
187
238
  ar38k = calc.arr.mul_factor(ar39k, sample.TotalParam[16:18], isRelative=True)
188
239
 
189
- sample.PublishValues[3] = copy.deepcopy(ar39k[0])
190
240
  sample.DegasValues[20:22] = copy.deepcopy(ar39k)
191
- # sample.DegasValues[30:32] = ar40k if corrDecasK else [[0] * n, [0] * n]
192
- # sample.DegasValues[16:18] = ar38k if corrDecasK else [[0] * n, [0] * n]
193
241
  sample.DegasValues[16] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar38k[0])]
194
242
  sample.DegasValues[17] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar38k[1])]
195
243
  sample.DegasValues[30] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar40k[0])]
196
244
  sample.DegasValues[31] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar40k[1])]
245
+ sample.PublishValues[3] = copy.deepcopy(sample.DegasValues[20])
197
246
 
198
247
 
199
248
  # =======================
@@ -209,6 +258,28 @@ def calc_degas_cl(sample: Sample):
209
258
  -------
210
259
 
211
260
  """
261
+ try:
262
+ params_to_check = {
263
+ 'Ar36': [
264
+ {'data': sample.CorrectedValues[0:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
265
+ {'data': sample.CorrectedValues[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
266
+ {'data': sample.DegasValues[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
267
+ ],
268
+ 'Ar38': [
269
+ {'data': sample.DegasValues[16:18], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
270
+ {'data': sample.DegasValues[18:20], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
271
+ ],
272
+ '38/36t': {'data': sample.TotalParam[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
273
+ '36/38Cl productivity': {'data': sample.TotalParam[56:58], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
274
+ 'λCl36': {'data': sample.TotalParam[46:48], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k5', },
275
+ 'standing time': {'data': sample.TotalParam[32], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k6', },
276
+ }
277
+ except (IndexError, AttributeError) as e:
278
+ raise
279
+ if not validate_params(**params_to_check):
280
+ return
281
+
282
+ n = sample.Info.experiment.step_num
212
283
  corrDecasCl = sample.TotalParam[108]
213
284
  decay_const = sample.TotalParam[46:48]
214
285
  cl36_cl38_p = sample.TotalParam[56:58]
@@ -220,8 +291,7 @@ def calc_degas_cl(sample: Sample):
220
291
  range(len(decay_const[0]))] # convert to absolute error
221
292
  cl36_cl38_p[1] = [cl36_cl38_p[0][i] * cl36_cl38_p[1][i] / 100 for i in
222
293
  range(len(cl36_cl38_p[0]))] # convert to absolute error
223
- # convert to absolute error
224
- ar38ar36[1] = [ar38ar36[0][i] * ar38ar36[1][i] / 100 for i in range(len(ar38ar36[0]))]
294
+ ar38ar36[1] = [ar38ar36[0][i] * ar38ar36[1][i] / 100 for i in range(len(ar38ar36[0]))] # convert to absolute error
225
295
  # ============
226
296
  # 36Ar deduct Ca, that is sum of 36Ara and 36ArCl
227
297
  ar36acl = calc.arr.sub(sample.CorrectedValues[0:2], sample.DegasValues[4:6])
@@ -234,28 +304,29 @@ def calc_degas_cl(sample: Sample):
234
304
  ar36acl[0][index] = 0
235
305
  if ar38acl[0][index] < 0:
236
306
  ar38acl[0][index] = 0
237
- try:
238
- if not corrDecasCl:
239
- raise ValueError("Do not apply degas chlorine")
240
- vDecay = [cl36_cl38_p[0][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i])) for i in
241
- range(len(stand_time_year))]
242
- sDecay = [pow((cl36_cl38_p[1][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i]))) ** 2 +
243
- (cl36_cl38_p[0][i] * stand_time_year[i] * (np.exp(-1 * decay_const[0][i] * stand_time_year[i])) *
244
- decay_const[1][i]) ** 2, 0.5) for i in range(len(stand_time_year))]
245
- sDecay = [calc.err.div((1, 0), (vDecay[i], sDecay[i])) for i in range(len(sDecay))]
246
- vDecay = [1 / vDecay[i] for i in range(len(vDecay))]
247
-
248
- # 36ArCl
249
- ar36cl = [[], []]
250
- # 38ArCl
251
- ar38cl = [[], []]
252
- for i in range(len(vDecay)):
307
+ # 36ArCl
308
+ ar36cl = [[], []]
309
+ # 38ArCl
310
+ ar38cl = [[], []]
311
+ for i in range(n):
312
+
313
+ if not corrDecasCl[i]:
314
+ v1 = s1 = v2 = s2 = 0
315
+ else:
316
+ vDecay = cl36_cl38_p[0][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i]))
317
+ sDecay = pow(
318
+ (cl36_cl38_p[1][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i]))) ** 2 +
319
+ (cl36_cl38_p[0][i] * stand_time_year[i] * (np.exp(-1 * decay_const[0][i] * stand_time_year[i])) *
320
+ decay_const[1][i]) ** 2, 0.5)
321
+ sDecay = calc.err.div((1, 0), (vDecay, sDecay))
322
+ vDecay = 1 / vDecay
323
+
253
324
  a1 = sample.CorrectedValues[0][i]; s1 = sample.CorrectedValues[1][i]
254
325
  a2 = sample.DegasValues[4][i]; s2 = sample.DegasValues[5][i];
255
326
  a3 = sample.DegasValues[16][i]; s3 = sample.DegasValues[17][i]
256
327
  a4 = sample.DegasValues[18][i]; s4 = sample.DegasValues[19][i]
257
328
  a5 = sample.CorrectedValues[4][i]; s5 = sample.CorrectedValues[5][i]
258
- a6 = vDecay[i]; s6 = sDecay[i]
329
+ a6 = vDecay; s6 = sDecay
259
330
  a7 = ar38ar36[0][i]; s7 = ar38ar36[1][i]
260
331
 
261
332
  d1 = 1 / (1 - a6 / a7)
@@ -266,30 +337,21 @@ def calc_degas_cl(sample: Sample):
266
337
  d6 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / a7 / (1 - a6 / a7) ** 2
267
338
  d7 = -(a1 - a2) * (a6) / (a7 - a6) ** 2 - (a3 + a4 - a5) / (a7 - a6) ** 2
268
339
 
269
- v1 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / (1 - a6 / a7)
340
+ v1 = (a1 - a2 + (a3 + a4 - a5) / a7) / (1 - a6 / a7)
270
341
  s1 = (d1**2*s1**2 + d2**2*s2**2 + d3**2*s3**2 + d4**2*s4**2+ d5**2*s5**2 + d6**2*s6**2 + d7**2*s7**2) ** .5
271
- s2 = calc.err.mul((v1, s1), (vDecay[i], sDecay[i]))
342
+ s2 = calc.err.mul((v1, s1), (a6, s6))
272
343
  v1 = 0 if (ar36acl[0][i] - v1 < 0 or v1 < 0) and set_negative_zero[i] else v1
273
- v2 = v1 * vDecay[i]
274
-
275
- # Note: Ar36Cl uncertainty is differen with ArArCALC. All calculation was conducted separately considering they are independent
276
- # s1 = calc.err.div((a1 - a2 + (a3 + a4) / a7 - a5 / a7, calc.err.add(s1, s2, calc.err.div((a3 + a4, calc.err.add(s3, s4)), (a7, s7)), calc.err.div((a5, s5), (a7, s7)))), (1 - a6 / a7, calc.err.div((a6, s6), (a7, s7))))
344
+ v2 = v1 * a6
277
345
 
278
- ar36cl[0].append(v1); ar36cl[1].append(s1)
279
- ar38cl[0].append(v2); ar38cl[1].append(s2)
346
+ # Note: Ar36Cl uncertainty is differen with ArArCALC. All calculation was conducted separately considering they are independent
347
+ # s1 = calc.err.div((a1 - a2 + (a3 + a4) / a7 - a5 / a7, calc.err.add(s1, s2, calc.err.div((a3 + a4, calc.err.add(s3, s4)), (a7, s7)), calc.err.div((a5, s5), (a7, s7)))), (1 - a6 / a7, calc.err.div((a6, s6), (a7, s7))))
280
348
 
281
- except Exception as e:
282
- print('Error in corr Cl: {}, lines: {}'.format(e, e.__traceback__.tb_lineno))
283
- ar36cl = np.zeros([2, len(ar36acl[0])])
284
- ar38cl = np.zeros([2, len(ar36acl[0])])
349
+ ar36cl[0].append(v1); ar36cl[1].append(s1)
350
+ ar38cl[0].append(v2); ar38cl[1].append(s2)
285
351
 
286
- # sample.DegasValues[6:8] = ar36cl
287
- # sample.DegasValues[10:12] = ar38cl
288
- sample.PublishValues[2] = copy.deepcopy(ar38cl[0])
289
- sample.DegasValues[ 6] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar36cl[0])]
290
- sample.DegasValues[ 7] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar36cl[1])]
291
- sample.DegasValues[10] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar38cl[0])]
292
- sample.DegasValues[11] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar38cl[1])]
352
+ sample.DegasValues[6:8] = copy.deepcopy(ar36cl)
353
+ sample.DegasValues[10:12] = copy.deepcopy(ar38cl)
354
+ sample.PublishValues[2] = copy.deepcopy(sample.DegasValues[10])
293
355
 
294
356
 
295
357
  # =======================
@@ -305,37 +367,48 @@ def calc_degas_atm(sample: Sample):
305
367
  -------
306
368
 
307
369
  """
370
+ try:
371
+ params_to_check = {
372
+ 'Ar36': [
373
+ {'data': sample.CorrectedValues[0:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
374
+ {'data': sample.DegasValues[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
375
+ {'data': sample.DegasValues[6:8], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
376
+ ],
377
+ '38/36t': {'data': sample.TotalParam[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
378
+ '40/36t': {'data': sample.TotalParam[0:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
379
+ # 'apply atm degas': {'data': sample.TotalParam[109], 'dtype': bool},
380
+ }
381
+ except (IndexError, AttributeError) as e:
382
+ raise
383
+ if not validate_params(**params_to_check):
384
+ return
385
+
308
386
  corrDecasAtm = sample.TotalParam[109]
309
387
  set_negative_zero = sample.TotalParam[101]
310
- # n = len(sample.CorrectedValues[0])
311
388
  # 36Ar deduct Ca, that is sum of 36Ara and 36ArCl
312
389
  ar36acl = calc.arr.sub(sample.CorrectedValues[0:2], sample.DegasValues[4:6])
313
390
  ar36acl[0] = [0 if val < 0 and set_negative_zero[idx] else val for idx, val in enumerate(ar36acl[0])]
314
- # 38Ar deduct K and Ca, that is sum of 38Ara and 38ArCl
315
- # ar38acl = calc.arr.sub()(
316
- # calc.arr.sub()(sample.CorrectedValues[2:4], sample.DegasValues[16:18]), sample.DegasValues[18:20])
317
391
  # 36ArAir
318
392
  ar36a = calc.arr.sub(ar36acl, sample.DegasValues[6:8])
319
393
  # If ar36acl - ar36cl < 0, let ar36a = ar36 - ar36ca
320
394
  ar36a[0] = [ar36acl[index] if item < 0 and set_negative_zero[index] else item for index, item in enumerate(ar36a[0])]
321
395
  if sample.Info.sample.type == "Air":
396
+ # Air shot: no chlorine related Ar38
322
397
  ar38a = copy.deepcopy(sample.CorrectedValues[4:6])
323
398
  ar40a = copy.deepcopy(sample.CorrectedValues[8:10])
324
399
  else:
325
- # 38ArAir
400
+ # 38ArAir, Ar36a × factor
326
401
  ar38a = calc.arr.mul_factor(ar36a, sample.TotalParam[4:6], isRelative=True)
327
- # 40ArAir
402
+ # 40ArAir, Ar36a × factor
328
403
  ar40a = calc.arr.mul_factor(ar36a, sample.TotalParam[0:2], isRelative=True)
329
404
 
330
- sample.PublishValues[0] = copy.deepcopy(ar36a[0])
331
- # sample.DegasValues[12:14] = ar38a if corrDecasAtm else [[0] * n, [0] * n]
332
- # sample.DegasValues[26:28] = ar40a if corrDecasAtm else [[0] * n, [0] * n]
333
- sample.DegasValues[ 0] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar36a[0])]
405
+ sample.DegasValues[ 0] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar36a[0])] # Ar36a
334
406
  sample.DegasValues[ 1] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar36a[1])]
335
- sample.DegasValues[12] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar38a[0])]
407
+ sample.DegasValues[12] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar38a[0])] # Ar38a
336
408
  sample.DegasValues[13] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar38a[1])]
337
- sample.DegasValues[26] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar40a[0])]
409
+ sample.DegasValues[26] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar40a[0])] # Ar40a
338
410
  sample.DegasValues[27] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar40a[1])]
411
+ sample.PublishValues[0] = copy.deepcopy(sample.DegasValues[ 0])
339
412
 
340
413
 
341
414
  # =======================
@@ -351,57 +424,87 @@ def calc_degas_r(sample: Sample):
351
424
  -------
352
425
 
353
426
  """
427
+ try:
428
+ params_to_check = {
429
+ 'Ar40': {'data': sample.CorrectedValues[8:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
430
+ 'Ar40K': {'data': sample.DegasValues[30:32], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
431
+ 'Ar40a': {'data': sample.DegasValues[26:28], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
432
+ }
433
+ except (IndexError, AttributeError) as e:
434
+ raise
435
+ if not validate_params(**params_to_check):
436
+ return
437
+
354
438
  ar40ar = calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32])
355
439
  ar40r = calc.arr.sub(ar40ar, sample.DegasValues[26:28])
356
440
  ar40r[0] = [0 if item < 0 and sample.TotalParam[101][index] else item for index, item in enumerate(ar40r[0])]
357
441
  sample.DegasValues[24:26] = copy.deepcopy(ar40r)
358
- sample.PublishValues[4] = copy.deepcopy(ar40r[0])
442
+ sample.PublishValues[4] = copy.deepcopy(sample.DegasValues[24])
443
+
444
+
445
+ def calc_degas_c(sample: Sample):
446
+ """ Degas for residuals
447
+ Parameters
448
+ ----------
449
+ sample
450
+
451
+ Returns
452
+ -------
453
+
454
+ """
455
+ n = sample.Info.experiment.step_num
456
+ sample.DegasValues[ 2] = [0 for i in range(n)] # 36Arc
457
+ sample.DegasValues[ 3] = [0 for i in range(n)]
458
+ sample.DegasValues[14] = [0 for i in range(n)] # 38Arc
459
+ sample.DegasValues[15] = [0 for i in range(n)]
460
+ sample.DegasValues[28] = [0 for i in range(n)] # 40Arc
461
+ sample.DegasValues[29] = [0 for i in range(n)]
359
462
 
360
463
 
361
464
  # =======================
362
465
  # Calc ratio
363
466
  # =======================
364
467
  def calc_nor_inv_isochrons(sample: Sample):
365
- n = len(sample.SequenceName)
468
+ n = sample.Info.experiment.step_num
366
469
  try:
367
470
  isochron_1 = calc.isochron.get_data(
368
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
471
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
369
472
  *calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]),
370
473
  *sample.DegasValues[0:2]
371
474
  )
372
475
  isochron_2 = calc.isochron.get_data(
373
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
476
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
374
477
  *sample.DegasValues[0:2],
375
478
  *calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]))
376
479
  except (BaseException, Exception):
377
- return np.zeros([5, n]), np.zeros([5, n])
480
+ return np.empty([5, n]), np.empty([5, n])
378
481
  else:
379
482
  return isochron_1, isochron_2
380
483
 
381
484
 
382
485
  def calc_cl_isochrons(sample: Sample):
383
- n = len(sample.SequenceName)
486
+ n = sample.Info.experiment.step_num
384
487
  try:
385
488
  isochron_3 = calc.isochron.get_data(
386
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
489
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
387
490
  *sample.DegasValues[24:26],
388
- *calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor))
491
+ *calc.arr.mul(sample.DegasValues[10:12], sample.TotalParam[136:138]))
389
492
  isochron_4 = calc.isochron.get_data(
390
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
391
- *calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor),
493
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
494
+ *calc.arr.mul(sample.DegasValues[10:12], sample.TotalParam[136:138]),
392
495
  *sample.DegasValues[24:26])
393
496
  isochron_5 = calc.isochron.get_data(
394
- *calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor),
497
+ *calc.arr.mul(sample.DegasValues[10:12], sample.TotalParam[136:138]),
395
498
  *sample.DegasValues[24:26],
396
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor))
499
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]))
397
500
  except (BaseException, Exception):
398
- return np.zeros([5, n]), np.zeros([5, n]), np.zeros([5, n])
501
+ return np.empty([5, n]), np.empty([5, n]), np.empty([5, n])
399
502
  else:
400
503
  return isochron_3, isochron_4, isochron_5
401
504
 
402
505
 
403
506
  def calc_3D_isochrons(sample: Sample):
404
- n = len(sample.SequenceName)
507
+ n = sample.Info.experiment.step_num
405
508
  try:
406
509
  # === Ar values ===
407
510
  # 3D ratio, 36Ar(a+cl)/40Ar(a+r), 38Ar(a+cl)/40Ar(a+r), 39Ar(k)/40Ar(a+r),
@@ -418,32 +521,50 @@ def calc_3D_isochrons(sample: Sample):
418
521
  # isochron_6 = calc.isochron.get_3d_data(*ar36acl, *ar38acl, *ar40ar, *ar39k)
419
522
  isochron_6 = calc.isochron.get_3d_data(*ar36acl, *ar38acl, *ar39k, *ar40ar) # Points on the plot will be more disperse than the above
420
523
  except:
421
- return np.zeros([9, n])
524
+ return np.empty([9, n])
422
525
  else:
423
526
  return isochron_6
424
527
 
425
528
 
426
- def calc_ratio(sample: Sample, monte_carlo: bool = False):
529
+ def calc_ratio(sample: Sample):
427
530
  """ Calculate isochron ratio data, 40Arr/39ArK, Ar40r percentage,
428
531
  Ar39K released percentage, Ca/K
429
532
  Parameters
430
533
  ----------
431
534
  sample : Sample instance
432
- monte_carlo : whether conduct monte carlo simulation for calculating 40Arr/39ArK
433
535
 
434
536
  Returns
435
537
  -------
436
538
  None
437
539
  """
438
- ar40r_percent = [item / sample.CorrectedValues[8][index] * 100 if sample.CorrectedValues[8][index] != 0 else 0
439
- for index, item in enumerate(sample.DegasValues[24])]
440
- sum_ar36a = sum(sample.DegasValues[ 0])
441
- CaK = calc.arr.mul_factor(calc.arr.mul_factor(
442
- sample.DegasValues[8:10], calc.arr.rec_factor(sample.DegasValues[20:22], isRelative=False)),
443
- calc.arr.rec_factor(sample.TotalParam[20:22], isRelative=True))
540
+
541
+ try:
542
+ if sample.Info.sample.type == "Air":
543
+ params_to_check = {
544
+ 'corrected values': {'data': sample.CorrectedValues[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
545
+ 'degas values': {'data': sample.DegasValues[0:32], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
546
+ }
547
+ else:
548
+ params_to_check = {
549
+ 'corrected values': {'data': sample.CorrectedValues[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
550
+ 'degas values': {'data': sample.DegasValues[0:32], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k2', },
551
+ 'K/Ca factor': {'data': sample.TotalParam[20:22], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k3', },
552
+ 'normalizing factor': [
553
+ {'data': sample.TotalParam[136], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k4', },
554
+ {'data': sample.TotalParam[137], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
555
+ ],
556
+ # 'apply monte carlo': {'data': sample.TotalParam[112][0], 'dtype': bool, },
557
+ }
558
+ except (IndexError, AttributeError) as e:
559
+ raise
560
+ if not validate_params(**params_to_check):
561
+ return
562
+
563
+ n = sample.Info.experiment.step_num
444
564
 
445
565
  # assignation
446
566
  if sample.Info.sample.type == "Air":
567
+ sum_ar36a = sum(sample.DegasValues[ 0])
447
568
  ar40aar36a = calc.arr.mul_factor(
448
569
  sample.DegasValues[26:28], calc.arr.rec_factor(sample.DegasValues[0:2], isRelative=False),
449
570
  isRelative=False)
@@ -451,7 +572,7 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
451
572
  sample.ApparentAgeValues[0:2] = ar40aar36a
452
573
  sample.ApparentAgeValues[7] = ar36a_percent
453
574
  else:
454
- ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor)
575
+ ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138])
455
576
  sum_ar39k = sum(ar39k)
456
577
  ar39k_percent = [item / sum_ar39k * 100 if sum_ar39k != 0 else 0 for item in ar39k]
457
578
  ar40rar39k = calc.arr.mul_factor(
@@ -460,12 +581,23 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
460
581
  sample.ApparentAgeValues[0:2] = ar40rar39k
461
582
  sample.ApparentAgeValues[7] = ar39k_percent
462
583
 
584
+ ar40r_percent = [item / sample.CorrectedValues[8][index] * 100 if sample.CorrectedValues[8][index] != 0 else 0
585
+ for index, item in enumerate(sample.DegasValues[24])]
586
+ CaK = calc.arr.mul_factor(calc.arr.mul_factor(
587
+ sample.DegasValues[8:10], calc.arr.rec_factor(sample.DegasValues[20:22], isRelative=False)),
588
+ calc.arr.rec_factor(sample.TotalParam[20:22], isRelative=True))
589
+
463
590
  sample.ApparentAgeValues[6] = ar40r_percent
464
591
  sample.PublishValues[7:11] = copy.deepcopy([*sample.ApparentAgeValues[6:8], *CaK])
465
592
 
466
593
  sample.IsochronValues[0:5], sample.IsochronValues[6:11] = calc_nor_inv_isochrons(sample)
467
594
  sample.IsochronValues[12:17], sample.IsochronValues[18:23], sample.IsochronValues[24:29] = \
468
595
  calc_cl_isochrons(sample)
596
+ sample.IsochronValues[5] = [np.nan] * n
597
+ sample.IsochronValues[11] = [np.nan] * n
598
+ sample.IsochronValues[17] = [np.nan] * n
599
+ sample.IsochronValues[23] = [np.nan] * n
600
+ sample.IsochronValues[29] = [np.nan] * n
469
601
 
470
602
  # === Cl-Atm-Correlation Plot ===
471
603
  sample.IsochronValues[30:39] = calc_3D_isochrons(sample)
@@ -478,18 +610,32 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
478
610
 
479
611
  # Note that the difference between Turner 3D plots and our 3D plots.
480
612
 
481
- if monte_carlo:
482
- res = monte_carlo_f(sample=sample)
483
- # where to display simulation results
484
- res = calc.arr.transpose(list(res)) # res is a generator for [age, sage, ...]
485
- age, sage = res[:2]
486
- sample.ApparentAgeValues[1] = sage
487
613
 
614
+ def calc_ratio_monte_carlo(sample: Sample):
615
+ monte_carlo = sample.TotalParam[112][0]
616
+ if monte_carlo and sample.Info.sample.type != "Air":
617
+ res = monte_carlo_f(sample=sample)
618
+ # ages
619
+ res = np.array(list(res)).T # res is a generator for [*F, *age, iso, ...]
620
+ sample.ApparentAgeValues[0:2] = res[0:2]
621
+ sample.ApparentAgeValues[2] = [np.nan] * sample.Info.experiment.step_num
622
+ sample.ApparentAgeValues[3] = [np.nan] * sample.Info.experiment.step_num
623
+ sample.ApparentAgeValues[4] = [np.nan] * sample.Info.experiment.step_num
624
+ sample.ApparentAgeValues[5] = [np.nan] * sample.Info.experiment.step_num
625
+ # degas
626
+ sample.DegasValues = res[2:2 + 32]
488
627
  # isochron data
489
- isochron_1 = res[2:7]
490
- isochron_2 = res[7:12]
491
- sample.IsochronValues[0:5] = isochron_1
492
- sample.IsochronValues[6:11] = isochron_2
628
+ sample.IsochronValues = res[2 + 32:2 + 32 + 39]
629
+ # corrected
630
+ sample.CorrectedValues = res[2 + 32 + 39:2 + 32 + 39 + 10]
631
+ # publish
632
+ sample.PublishValues[0] = copy.deepcopy(sample.DegasValues[ 0])
633
+ sample.PublishValues[1] = copy.deepcopy(sample.DegasValues[ 8])
634
+ sample.PublishValues[2] = copy.deepcopy(sample.DegasValues[10])
635
+ sample.PublishValues[3] = copy.deepcopy(sample.DegasValues[20])
636
+ sample.PublishValues[4] = copy.deepcopy(sample.DegasValues[24])
637
+ sample.PublishValues[5:7] = copy.deepcopy(sample.ApparentAgeValues[2:4])
638
+ sample.PublishValues[7:9] = copy.deepcopy(sample.ApparentAgeValues[6:8])
493
639
 
494
640
 
495
641
  def monte_carlo_f(sample: Sample):
@@ -502,8 +648,49 @@ def monte_carlo_f(sample: Sample):
502
648
  -------
503
649
 
504
650
  """
651
+ try:
652
+ params_to_check = {
653
+ 'unknows': {'data': sample.SampleIntercept[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k5', },
654
+ 'blanks': {'data': sample.BlankIntercept[0:10], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k6', },
655
+ 'mass': [
656
+ {'data': sample.TotalParam[71:81:2], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k7', },
657
+ {'data': sample.TotalParam[72:81:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k7', },
658
+ ],
659
+ 'gain': [
660
+ {'data': sample.TotalParam[126:136:2], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k8', },
661
+ {'data': sample.TotalParam[126:136:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k8', },
662
+ ],
663
+ 'mdf': [
664
+ {'data': sample.TotalParam[69], 'dtype': float, 'func': lambda x: np.isfinite(x) and x != 0, 'class': 'k9', },
665
+ {'data': sample.TotalParam[70], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k9', },
666
+ ],
667
+ 'decay consts': [
668
+ {'data': sample.TotalParam[42:48:2], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k10', },
669
+ {'data': sample.TotalParam[43:48:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k10', },
670
+ ],
671
+ 'normalization factor': [
672
+ {'data': sample.TotalParam[136], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k4', },
673
+ {'data': sample.TotalParam[137], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k4', },
674
+ ],
675
+ 'interference params': [
676
+ {'data': sample.TotalParam[8:18], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k11', },
677
+ {'data': sample.TotalParam[0:2], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k11', },
678
+ {'data': sample.TotalParam[4:6], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k11', },
679
+ {'data': sample.TotalParam[56:58], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k11', },
680
+ {'data': sample.TotalParam[32], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k11', },
681
+ {'data': sample.TotalParam[27], 'dtype': str, 'func': lambda x: all(
682
+ [len(re.findall(r"\d+", item)) >= 5 for item in list(filter(None, re.split(r'[DS]', x)))[::2]]), 'class': 'k11', },
683
+ {'data': sample.TotalParam[27], 'dtype': str, 'func': lambda x: all(
684
+ [isinstance(float(item), float) for item in list(filter(None, re.split(r'[DS]', x)))[1::2]]), 'class': 'k11', },
685
+ ],
686
+ 'experiment datetime': {'data': sample.TotalParam[31], 'dtype': str, 'func': lambda x: len(re.findall(r"\d+", x)) >= 5, 'class': 'k12', },
687
+ }
688
+ except (IndexError, AttributeError) as e:
689
+ raise
690
+ if not validate_params(**params_to_check):
691
+ return
505
692
 
506
- sequence_num = sample.sequence().size
693
+ sequence_num = sample.Info.experiment.step_num
507
694
 
508
695
  ar40m = np.transpose(sample.SampleIntercept[8:10])
509
696
  ar39m = np.transpose(sample.SampleIntercept[6:8])
@@ -544,16 +731,15 @@ def monte_carlo_f(sample: Sample):
544
731
  R38v36a = np.transpose(sample.TotalParam[4:6])
545
732
  R36v38clp = np.transpose(sample.TotalParam[56:58])
546
733
 
547
- JNFactor = np.transpose(sample.NormalizeFactor)
548
-
549
734
  stand_time_year = np.transpose(sample.TotalParam[32])
735
+ JNFactor = np.transpose(sample.TotalParam[136:138])
550
736
 
551
737
  irradiation_cycles = [list(filter(None, re.split(r'[DS]', each_step))) for each_step in sample.TotalParam[27]]
552
738
  t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experimental times
553
739
  t2, t3 = [], [] # t2: irradiation times, t3: irradiation durations
554
740
  for each_step in irradiation_cycles:
555
741
  t2.append([re.findall(r"\d+", item) for i, item in enumerate(each_step) if i % 2 == 0])
556
- t3.append([item for i, item in enumerate(each_step) if i % 2 == 1])
742
+ t3.append([float(item) for i, item in enumerate(each_step) if i % 2 == 1])
557
743
 
558
744
  # for i in range(sequence_num):
559
745
  # P37Decay = calc.corr.get_decay_factor(t1[i], t2[i], t3[i], L37ar[i][0], L37ar[i][0] * L37ar[i][1] / 100)
@@ -565,8 +751,6 @@ def monte_carlo_f(sample: Sample):
565
751
 
566
752
  for i in range(sequence_num):
567
753
 
568
- print(f"Monte Carlo Simulation For sequence {i + 1}")
569
-
570
754
  res = calc.corr.Monte_Carlo_F(
571
755
  ar40m=ar40m[i], ar39m=ar39m[i], ar38m=ar38m[i], ar37m=ar37m[i], ar36m=ar36m[i],
572
756
  ar40b=ar40b[i], ar39b=ar39b[i], ar38b=ar38b[i], ar37b=ar37b[i], ar36b=ar36b[i],
@@ -578,10 +762,12 @@ def monte_carlo_f(sample: Sample):
578
762
  R40v39k=R40v39k[i], R38v39k=R38v39k[i],
579
763
  R36v38clp=R36v38clp[i],
580
764
  L37ar=L37ar[i], L39ar=L39ar[i], L36cl=L36cl[i],
581
- MDFunc=None,
582
765
  MDF=MDF[i], stand_time_year=stand_time_year[i],
583
- JNFactor=JNFactor,
584
- blank_gain_corr=sample.TotalParam[111][i]
766
+ JNFactor=JNFactor[i],
767
+ blank_gain_corr=sample.TotalParam[111][i],
768
+ MDF_method=sample.TotalParam[100][i],
769
+ force_to_zero=sample.TotalParam[101][i],
770
+ monte_carlo_size=1000,
585
771
  )
586
772
 
587
773
  yield res