ararpy 0.1.198__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 (41) 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 +5 -24
  11. ararpy/calc/basic.py +26 -3
  12. ararpy/calc/corr.py +135 -89
  13. ararpy/calc/jvalue.py +1 -1
  14. ararpy/calc/plot.py +6 -4
  15. ararpy/calc/raw_funcs.py +41 -2
  16. ararpy/calc/regression.py +224 -132
  17. ararpy/files/arr_file.py +2 -1
  18. ararpy/files/basic.py +0 -22
  19. ararpy/files/calc_file.py +107 -84
  20. ararpy/files/raw_file.py +242 -229
  21. ararpy/smp/basic.py +202 -46
  22. ararpy/smp/calculation.py +6 -6
  23. ararpy/smp/corr.py +339 -154
  24. ararpy/smp/diffusion_funcs.py +345 -36
  25. ararpy/smp/export.py +247 -129
  26. ararpy/smp/info.py +2 -2
  27. ararpy/smp/initial.py +105 -48
  28. ararpy/smp/json.py +2 -2
  29. ararpy/smp/plots.py +225 -218
  30. ararpy/smp/raw.py +11 -15
  31. ararpy/smp/sample.py +257 -183
  32. ararpy/smp/style.py +48 -22
  33. ararpy/smp/table.py +42 -33
  34. ararpy/thermo/atomic_level_random_walk.py +56 -48
  35. ararpy/thermo/basic.py +2 -2
  36. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/METADATA +1 -1
  37. ararpy-0.2.1.dist-info/RECORD +73 -0
  38. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/WHEEL +1 -1
  39. ararpy-0.1.198.dist-info/RECORD +0 -66
  40. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/licenses/LICENSE +0 -0
  41. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/top_level.txt +0 -0
ararpy/smp/corr.py CHANGED
@@ -17,57 +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, len(sample.SequenceName)])
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 as e:
35
- print(f"Gain correction failed")
36
- print(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:
35
+ raise
36
+ if not validate_params(**params_to_check):
37
37
  return
38
- for i in range(0, 10, 2):
39
- gain_corrected[i] = [gain_corrected[i][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i])]
40
- gain_corrected[i + 1] = [gain_corrected[i + 1][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i + 1])]
41
- sample.CorrectedValues = copy.deepcopy(gain_corrected)
42
-
43
38
 
44
- # =======================
45
- # Corr Blank
46
- # =======================
47
- def corr_blank(sample: Sample):
48
- """Blank Correction"""
49
- blank_corrected = np.zeros([10, len(sample.SequenceName)])
39
+ blank_corrected = np.zeros([10, sample.Info.experiment.step_num])
50
40
  try:
51
41
  for i in range(5):
52
- b, sb = copy.deepcopy(sample.BlankIntercept[i * 2: i * 2 + 2])
53
- f, sf = np.array(sample.TotalParam[126 + i * 2:128 + i * 2])
54
- sf = f * sf / 100
55
- _ = calc.corr.gain(*sample.BlankIntercept[i * 2:2 + i * 2], f, sf)
56
- for index in range(len(sample.BlankIntercept[i * 2])):
57
- if sample.TotalParam[111][index]: # use same parameters to correct blank intercepts
58
- b[index] = _[0][index]
59
- sb[index] = _[1][index]
60
- blank_corrected[i * 2:2 + i * 2] = calc.corr.blank(
61
- *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)
62
52
  except Exception as e:
63
53
  print(traceback.format_exc())
64
- raise ValueError('Blank correction error')
54
+ raise ValueError(f'Blank correction error: {str(e)}')
65
55
  for i in range(0, 10, 2):
66
- blank_corrected[i] = [blank_corrected[i][index] if sample.TotalParam[102][index] else j for index, j in enumerate(sample.CorrectedValues[i])]
67
- 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])]
68
58
  blank_corrected[i] = [0 if j < 0 and sample.TotalParam[101][index] else j for index, j in enumerate(blank_corrected[i])]
69
59
  sample.BlankCorrected = blank_corrected
70
- sample.CorrectedValues = copy.deepcopy(sample.BlankCorrected)
71
60
 
72
61
 
73
62
  # =======================
@@ -75,13 +64,29 @@ def corr_blank(sample: Sample):
75
64
  # =======================
76
65
  def corr_massdiscr(sample: Sample):
77
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
+
78
84
  corrMassdiscr = sample.TotalParam[103][0]
79
85
  if not corrMassdiscr:
80
86
  sample.MassDiscrCorrected = copy.deepcopy(sample.BlankCorrected)
81
- sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
82
87
  return
83
88
  MASS = sample.TotalParam[71:81]
84
- mdf_corrected = np.zeros([10, len(sample.SequenceName)])
89
+ mdf_corrected = np.zeros([10, sample.Info.experiment.step_num])
85
90
  try:
86
91
  for i in range(5):
87
92
  if len(sample.BlankCorrected[i * 2:2 + i * 2]) == 0:
@@ -89,12 +94,11 @@ def corr_massdiscr(sample: Sample):
89
94
  mdf_corrected[i * 2:2 + i * 2] = calc.corr.discr(
90
95
  *sample.BlankCorrected[i * 2:2 + i * 2],
91
96
  *sample.TotalParam[69:71], m=MASS[i * 2], m40=MASS[8], isRelative=True,
92
- method=sample.TotalParam[100][0])
97
+ method=sample.TotalParam[100])
93
98
  except Exception as e:
94
99
  print(traceback.format_exc())
95
- raise ValueError(f'Mass discrimination correction error: {e}')
96
- sample.MassDiscrCorrected = mdf_corrected
97
- sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
100
+ raise ValueError(f'Mass discrimination correction error: {str(e)}')
101
+ sample.MassDiscrCorrected = copy.deepcopy(mdf_corrected)
98
102
 
99
103
 
100
104
  # =======================
@@ -110,14 +114,35 @@ def corr_decay(sample: Sample):
110
114
  -------
111
115
 
112
116
  """
113
- 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])
114
139
  try:
115
140
  irradiation_cycles = [list(filter(None, re.split(r'[DS]', each_step))) for each_step in sample.TotalParam[27]]
116
- t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experimental times
117
- 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
118
143
  for each_step in irradiation_cycles:
119
- t2.append([re.findall(r"\d+", item) for i, item in enumerate(each_step) if i % 2 == 0])
120
- 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]])
121
146
  decay_corrected[2:4] = calc.corr.decay(
122
147
  *sample.MassDiscrCorrected[2:4], t1, t2, t3, *sample.TotalParam[44:46], isRelative=True)
123
148
  decay_corrected[6:8] = calc.corr.decay(
@@ -127,10 +152,11 @@ def corr_decay(sample: Sample):
127
152
  decay_corrected[6] = [0 if i < 0 else i for i in decay_corrected[6]]
128
153
  except Exception as e:
129
154
  print(traceback.format_exc())
130
- raise ValueError('Decay correction correction error')
155
+ raise ValueError(f'Decay correction error: {str(e)}')
131
156
 
132
157
  corrDecay37 = sample.TotalParam[104]
133
158
  corrDecay39 = sample.TotalParam[105]
159
+ sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
134
160
  sample.CorrectedValues[2] = [val if corrDecay37[idx] else 0 for idx, val in enumerate(decay_corrected[2])]
135
161
  sample.CorrectedValues[3] = [val if corrDecay37[idx] else 0 for idx, val in enumerate(decay_corrected[3])]
136
162
  sample.CorrectedValues[6] = [val if corrDecay39[idx] else 0 for idx, val in enumerate(decay_corrected[6])]
@@ -150,20 +176,32 @@ def calc_degas_ca(sample: Sample):
150
176
  -------
151
177
 
152
178
  """
153
- corrDecasCa = sample.TotalParam[106]
154
- # 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]
155
193
  ar37ca = sample.CorrectedValues[2:4]
156
194
  ar39ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[8:10], isRelative=True)
157
195
  ar38ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[10:12], isRelative=True)
158
196
  ar36ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[12:14], isRelative=True)
159
197
  sample.DegasValues[8:10] = copy.deepcopy(ar37ca) # 37Ca
160
- sample.DegasValues[ 4] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[0])] # 36Ca
161
- sample.DegasValues[ 5] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[1])]
162
- sample.DegasValues[18] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[0])] # 38Ca
163
- sample.DegasValues[19] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[1])]
164
- sample.DegasValues[22] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[0])] # 39Ca
165
- sample.DegasValues[23] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[1])]
166
- 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])
167
205
 
168
206
 
169
207
  # =======================
@@ -179,22 +217,32 @@ def calc_degas_k(sample: Sample):
179
217
  -------
180
218
 
181
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
+
182
233
  corrDecasK = sample.TotalParam[107]
183
234
  set_negative_zero = sample.TotalParam[101]
184
- # n = len(sample.CorrectedValues[6])
185
235
  ar39k = calc.arr.sub(sample.CorrectedValues[6:8], sample.DegasValues[22:24])
186
236
  ar39k[0] = [0 if val < 0 and set_negative_zero[idx] else val for idx, val in enumerate(ar39k[0])]
187
237
  ar40k = calc.arr.mul_factor(ar39k, sample.TotalParam[14:16], isRelative=True)
188
238
  ar38k = calc.arr.mul_factor(ar39k, sample.TotalParam[16:18], isRelative=True)
189
239
 
190
- sample.PublishValues[3] = copy.deepcopy(ar39k[0])
191
240
  sample.DegasValues[20:22] = copy.deepcopy(ar39k)
192
- # sample.DegasValues[30:32] = ar40k if corrDecasK else [[0] * n, [0] * n]
193
- # sample.DegasValues[16:18] = ar38k if corrDecasK else [[0] * n, [0] * n]
194
241
  sample.DegasValues[16] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar38k[0])]
195
242
  sample.DegasValues[17] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar38k[1])]
196
243
  sample.DegasValues[30] = [val if corrDecasK[idx] else 0 for idx, val in enumerate(ar40k[0])]
197
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])
198
246
 
199
247
 
200
248
  # =======================
@@ -210,6 +258,28 @@ def calc_degas_cl(sample: Sample):
210
258
  -------
211
259
 
212
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
213
283
  corrDecasCl = sample.TotalParam[108]
214
284
  decay_const = sample.TotalParam[46:48]
215
285
  cl36_cl38_p = sample.TotalParam[56:58]
@@ -221,8 +291,7 @@ def calc_degas_cl(sample: Sample):
221
291
  range(len(decay_const[0]))] # convert to absolute error
222
292
  cl36_cl38_p[1] = [cl36_cl38_p[0][i] * cl36_cl38_p[1][i] / 100 for i in
223
293
  range(len(cl36_cl38_p[0]))] # convert to absolute error
224
- # convert to absolute error
225
- 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
226
295
  # ============
227
296
  # 36Ar deduct Ca, that is sum of 36Ara and 36ArCl
228
297
  ar36acl = calc.arr.sub(sample.CorrectedValues[0:2], sample.DegasValues[4:6])
@@ -235,28 +304,29 @@ def calc_degas_cl(sample: Sample):
235
304
  ar36acl[0][index] = 0
236
305
  if ar38acl[0][index] < 0:
237
306
  ar38acl[0][index] = 0
238
- try:
239
- if not corrDecasCl:
240
- raise ValueError("Do not apply degas chlorine")
241
- vDecay = [cl36_cl38_p[0][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i])) for i in
242
- range(len(stand_time_year))]
243
- sDecay = [pow((cl36_cl38_p[1][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i]))) ** 2 +
244
- (cl36_cl38_p[0][i] * stand_time_year[i] * (np.exp(-1 * decay_const[0][i] * stand_time_year[i])) *
245
- decay_const[1][i]) ** 2, 0.5) for i in range(len(stand_time_year))]
246
- sDecay = [calc.err.div((1, 0), (vDecay[i], sDecay[i])) for i in range(len(sDecay))]
247
- vDecay = [1 / vDecay[i] for i in range(len(vDecay))]
248
-
249
- # 36ArCl
250
- ar36cl = [[], []]
251
- # 38ArCl
252
- ar38cl = [[], []]
253
- 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
+
254
324
  a1 = sample.CorrectedValues[0][i]; s1 = sample.CorrectedValues[1][i]
255
325
  a2 = sample.DegasValues[4][i]; s2 = sample.DegasValues[5][i];
256
326
  a3 = sample.DegasValues[16][i]; s3 = sample.DegasValues[17][i]
257
327
  a4 = sample.DegasValues[18][i]; s4 = sample.DegasValues[19][i]
258
328
  a5 = sample.CorrectedValues[4][i]; s5 = sample.CorrectedValues[5][i]
259
- a6 = vDecay[i]; s6 = sDecay[i]
329
+ a6 = vDecay; s6 = sDecay
260
330
  a7 = ar38ar36[0][i]; s7 = ar38ar36[1][i]
261
331
 
262
332
  d1 = 1 / (1 - a6 / a7)
@@ -267,30 +337,21 @@ def calc_degas_cl(sample: Sample):
267
337
  d6 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / a7 / (1 - a6 / a7) ** 2
268
338
  d7 = -(a1 - a2) * (a6) / (a7 - a6) ** 2 - (a3 + a4 - a5) / (a7 - a6) ** 2
269
339
 
270
- v1 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / (1 - a6 / a7)
340
+ v1 = (a1 - a2 + (a3 + a4 - a5) / a7) / (1 - a6 / a7)
271
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
272
- s2 = calc.err.mul((v1, s1), (vDecay[i], sDecay[i]))
342
+ s2 = calc.err.mul((v1, s1), (a6, s6))
273
343
  v1 = 0 if (ar36acl[0][i] - v1 < 0 or v1 < 0) and set_negative_zero[i] else v1
274
- v2 = v1 * vDecay[i]
344
+ v2 = v1 * a6
275
345
 
276
- # Note: Ar36Cl uncertainty is differen with ArArCALC. All calculation was conducted separately considering they are independent
277
- # 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))))
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))))
278
348
 
279
- ar36cl[0].append(v1); ar36cl[1].append(s1)
280
- ar38cl[0].append(v2); ar38cl[1].append(s2)
349
+ ar36cl[0].append(v1); ar36cl[1].append(s1)
350
+ ar38cl[0].append(v2); ar38cl[1].append(s2)
281
351
 
282
- except Exception as e:
283
- print('Error in corr Cl: {}, lines: {}'.format(e, e.__traceback__.tb_lineno))
284
- ar36cl = np.zeros([2, len(ar36acl[0])])
285
- ar38cl = np.zeros([2, len(ar36acl[0])])
286
-
287
- # sample.DegasValues[6:8] = ar36cl
288
- # sample.DegasValues[10:12] = ar38cl
289
- sample.PublishValues[2] = copy.deepcopy(ar38cl[0])
290
- sample.DegasValues[ 6] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar36cl[0])]
291
- sample.DegasValues[ 7] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar36cl[1])]
292
- sample.DegasValues[10] = [val if corrDecasCl[idx] else 0 for idx, val in enumerate(ar38cl[0])]
293
- 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])
294
355
 
295
356
 
296
357
  # =======================
@@ -306,37 +367,48 @@ def calc_degas_atm(sample: Sample):
306
367
  -------
307
368
 
308
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
+
309
386
  corrDecasAtm = sample.TotalParam[109]
310
387
  set_negative_zero = sample.TotalParam[101]
311
- # n = len(sample.CorrectedValues[0])
312
388
  # 36Ar deduct Ca, that is sum of 36Ara and 36ArCl
313
389
  ar36acl = calc.arr.sub(sample.CorrectedValues[0:2], sample.DegasValues[4:6])
314
390
  ar36acl[0] = [0 if val < 0 and set_negative_zero[idx] else val for idx, val in enumerate(ar36acl[0])]
315
- # 38Ar deduct K and Ca, that is sum of 38Ara and 38ArCl
316
- # ar38acl = calc.arr.sub()(
317
- # calc.arr.sub()(sample.CorrectedValues[2:4], sample.DegasValues[16:18]), sample.DegasValues[18:20])
318
391
  # 36ArAir
319
392
  ar36a = calc.arr.sub(ar36acl, sample.DegasValues[6:8])
320
393
  # If ar36acl - ar36cl < 0, let ar36a = ar36 - ar36ca
321
394
  ar36a[0] = [ar36acl[index] if item < 0 and set_negative_zero[index] else item for index, item in enumerate(ar36a[0])]
322
395
  if sample.Info.sample.type == "Air":
396
+ # Air shot: no chlorine related Ar38
323
397
  ar38a = copy.deepcopy(sample.CorrectedValues[4:6])
324
398
  ar40a = copy.deepcopy(sample.CorrectedValues[8:10])
325
399
  else:
326
- # 38ArAir
400
+ # 38ArAir, Ar36a × factor
327
401
  ar38a = calc.arr.mul_factor(ar36a, sample.TotalParam[4:6], isRelative=True)
328
- # 40ArAir
402
+ # 40ArAir, Ar36a × factor
329
403
  ar40a = calc.arr.mul_factor(ar36a, sample.TotalParam[0:2], isRelative=True)
330
404
 
331
- sample.PublishValues[0] = copy.deepcopy(ar36a[0])
332
- # sample.DegasValues[12:14] = ar38a if corrDecasAtm else [[0] * n, [0] * n]
333
- # sample.DegasValues[26:28] = ar40a if corrDecasAtm else [[0] * n, [0] * n]
334
- 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
335
406
  sample.DegasValues[ 1] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar36a[1])]
336
- 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
337
408
  sample.DegasValues[13] = [val if corrDecasAtm[idx] else 0 for idx, val in enumerate(ar38a[1])]
338
- 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
339
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])
340
412
 
341
413
 
342
414
  # =======================
@@ -352,57 +424,87 @@ def calc_degas_r(sample: Sample):
352
424
  -------
353
425
 
354
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
+
355
438
  ar40ar = calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32])
356
439
  ar40r = calc.arr.sub(ar40ar, sample.DegasValues[26:28])
357
440
  ar40r[0] = [0 if item < 0 and sample.TotalParam[101][index] else item for index, item in enumerate(ar40r[0])]
358
441
  sample.DegasValues[24:26] = copy.deepcopy(ar40r)
359
- 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)]
360
462
 
361
463
 
362
464
  # =======================
363
465
  # Calc ratio
364
466
  # =======================
365
467
  def calc_nor_inv_isochrons(sample: Sample):
366
- n = len(sample.SequenceName)
468
+ n = sample.Info.experiment.step_num
367
469
  try:
368
470
  isochron_1 = calc.isochron.get_data(
369
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
471
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
370
472
  *calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]),
371
473
  *sample.DegasValues[0:2]
372
474
  )
373
475
  isochron_2 = calc.isochron.get_data(
374
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
476
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
375
477
  *sample.DegasValues[0:2],
376
478
  *calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]))
377
479
  except (BaseException, Exception):
378
- return np.zeros([5, n]), np.zeros([5, n])
480
+ return np.empty([5, n]), np.empty([5, n])
379
481
  else:
380
482
  return isochron_1, isochron_2
381
483
 
382
484
 
383
485
  def calc_cl_isochrons(sample: Sample):
384
- n = len(sample.SequenceName)
486
+ n = sample.Info.experiment.step_num
385
487
  try:
386
488
  isochron_3 = calc.isochron.get_data(
387
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
489
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]),
388
490
  *sample.DegasValues[24:26],
389
- *calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor))
491
+ *calc.arr.mul(sample.DegasValues[10:12], sample.TotalParam[136:138]))
390
492
  isochron_4 = calc.isochron.get_data(
391
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
392
- *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]),
393
495
  *sample.DegasValues[24:26])
394
496
  isochron_5 = calc.isochron.get_data(
395
- *calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor),
497
+ *calc.arr.mul(sample.DegasValues[10:12], sample.TotalParam[136:138]),
396
498
  *sample.DegasValues[24:26],
397
- *calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor))
499
+ *calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138]))
398
500
  except (BaseException, Exception):
399
- 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])
400
502
  else:
401
503
  return isochron_3, isochron_4, isochron_5
402
504
 
403
505
 
404
506
  def calc_3D_isochrons(sample: Sample):
405
- n = len(sample.SequenceName)
507
+ n = sample.Info.experiment.step_num
406
508
  try:
407
509
  # === Ar values ===
408
510
  # 3D ratio, 36Ar(a+cl)/40Ar(a+r), 38Ar(a+cl)/40Ar(a+r), 39Ar(k)/40Ar(a+r),
@@ -419,32 +521,50 @@ def calc_3D_isochrons(sample: Sample):
419
521
  # isochron_6 = calc.isochron.get_3d_data(*ar36acl, *ar38acl, *ar40ar, *ar39k)
420
522
  isochron_6 = calc.isochron.get_3d_data(*ar36acl, *ar38acl, *ar39k, *ar40ar) # Points on the plot will be more disperse than the above
421
523
  except:
422
- return np.zeros([9, n])
524
+ return np.empty([9, n])
423
525
  else:
424
526
  return isochron_6
425
527
 
426
528
 
427
- def calc_ratio(sample: Sample, monte_carlo: bool = False):
529
+ def calc_ratio(sample: Sample):
428
530
  """ Calculate isochron ratio data, 40Arr/39ArK, Ar40r percentage,
429
531
  Ar39K released percentage, Ca/K
430
532
  Parameters
431
533
  ----------
432
534
  sample : Sample instance
433
- monte_carlo : whether conduct monte carlo simulation for calculating 40Arr/39ArK
434
535
 
435
536
  Returns
436
537
  -------
437
538
  None
438
539
  """
439
- ar40r_percent = [item / sample.CorrectedValues[8][index] * 100 if sample.CorrectedValues[8][index] != 0 else 0
440
- for index, item in enumerate(sample.DegasValues[24])]
441
- sum_ar36a = sum(sample.DegasValues[ 0])
442
- CaK = calc.arr.mul_factor(calc.arr.mul_factor(
443
- sample.DegasValues[8:10], calc.arr.rec_factor(sample.DegasValues[20:22], isRelative=False)),
444
- 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
445
564
 
446
565
  # assignation
447
566
  if sample.Info.sample.type == "Air":
567
+ sum_ar36a = sum(sample.DegasValues[ 0])
448
568
  ar40aar36a = calc.arr.mul_factor(
449
569
  sample.DegasValues[26:28], calc.arr.rec_factor(sample.DegasValues[0:2], isRelative=False),
450
570
  isRelative=False)
@@ -452,7 +572,7 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
452
572
  sample.ApparentAgeValues[0:2] = ar40aar36a
453
573
  sample.ApparentAgeValues[7] = ar36a_percent
454
574
  else:
455
- 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])
456
576
  sum_ar39k = sum(ar39k)
457
577
  ar39k_percent = [item / sum_ar39k * 100 if sum_ar39k != 0 else 0 for item in ar39k]
458
578
  ar40rar39k = calc.arr.mul_factor(
@@ -461,12 +581,23 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
461
581
  sample.ApparentAgeValues[0:2] = ar40rar39k
462
582
  sample.ApparentAgeValues[7] = ar39k_percent
463
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
+
464
590
  sample.ApparentAgeValues[6] = ar40r_percent
465
591
  sample.PublishValues[7:11] = copy.deepcopy([*sample.ApparentAgeValues[6:8], *CaK])
466
592
 
467
593
  sample.IsochronValues[0:5], sample.IsochronValues[6:11] = calc_nor_inv_isochrons(sample)
468
594
  sample.IsochronValues[12:17], sample.IsochronValues[18:23], sample.IsochronValues[24:29] = \
469
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
470
601
 
471
602
  # === Cl-Atm-Correlation Plot ===
472
603
  sample.IsochronValues[30:39] = calc_3D_isochrons(sample)
@@ -479,18 +610,32 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
479
610
 
480
611
  # Note that the difference between Turner 3D plots and our 3D plots.
481
612
 
482
- if monte_carlo:
483
- res = monte_carlo_f(sample=sample)
484
- # where to display simulation results
485
- res = calc.arr.transpose(list(res)) # res is a generator for [age, sage, ...]
486
- age, sage = res[:2]
487
- sample.ApparentAgeValues[1] = sage
488
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]
489
627
  # isochron data
490
- isochron_1 = res[2:7]
491
- isochron_2 = res[7:12]
492
- sample.IsochronValues[0:5] = isochron_1
493
- 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])
494
639
 
495
640
 
496
641
  def monte_carlo_f(sample: Sample):
@@ -503,8 +648,49 @@ def monte_carlo_f(sample: Sample):
503
648
  -------
504
649
 
505
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
506
692
 
507
- sequence_num = sample.sequence().size
693
+ sequence_num = sample.Info.experiment.step_num
508
694
 
509
695
  ar40m = np.transpose(sample.SampleIntercept[8:10])
510
696
  ar39m = np.transpose(sample.SampleIntercept[6:8])
@@ -545,16 +731,15 @@ def monte_carlo_f(sample: Sample):
545
731
  R38v36a = np.transpose(sample.TotalParam[4:6])
546
732
  R36v38clp = np.transpose(sample.TotalParam[56:58])
547
733
 
548
- JNFactor = np.transpose(sample.NormalizeFactor)
549
-
550
734
  stand_time_year = np.transpose(sample.TotalParam[32])
735
+ JNFactor = np.transpose(sample.TotalParam[136:138])
551
736
 
552
737
  irradiation_cycles = [list(filter(None, re.split(r'[DS]', each_step))) for each_step in sample.TotalParam[27]]
553
738
  t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experimental times
554
739
  t2, t3 = [], [] # t2: irradiation times, t3: irradiation durations
555
740
  for each_step in irradiation_cycles:
556
741
  t2.append([re.findall(r"\d+", item) for i, item in enumerate(each_step) if i % 2 == 0])
557
- 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])
558
743
 
559
744
  # for i in range(sequence_num):
560
745
  # P37Decay = calc.corr.get_decay_factor(t1[i], t2[i], t3[i], L37ar[i][0], L37ar[i][0] * L37ar[i][1] / 100)
@@ -566,8 +751,6 @@ def monte_carlo_f(sample: Sample):
566
751
 
567
752
  for i in range(sequence_num):
568
753
 
569
- print(f"Monte Carlo Simulation For sequence {i + 1}")
570
-
571
754
  res = calc.corr.Monte_Carlo_F(
572
755
  ar40m=ar40m[i], ar39m=ar39m[i], ar38m=ar38m[i], ar37m=ar37m[i], ar36m=ar36m[i],
573
756
  ar40b=ar40b[i], ar39b=ar39b[i], ar38b=ar38b[i], ar37b=ar37b[i], ar36b=ar36b[i],
@@ -579,10 +762,12 @@ def monte_carlo_f(sample: Sample):
579
762
  R40v39k=R40v39k[i], R38v39k=R38v39k[i],
580
763
  R36v38clp=R36v38clp[i],
581
764
  L37ar=L37ar[i], L39ar=L39ar[i], L36cl=L36cl[i],
582
- MDFunc=None,
583
765
  MDF=MDF[i], stand_time_year=stand_time_year[i],
584
- JNFactor=JNFactor,
585
- 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,
586
771
  )
587
772
 
588
773
  yield res