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.
- ararpy/Example - Check arr.py +52 -0
- ararpy/Example - Granite Cooling History.py +411 -0
- ararpy/Example - Plot temperature calibration.py +291 -0
- ararpy/Example - Show MDD results.py +561 -0
- ararpy/Example - Show all Kfs age spectra.py +344 -0
- ararpy/Example - Show random walk results.py +363 -0
- ararpy/Example - Tc calculation.py +437 -0
- ararpy/__init__.py +3 -4
- ararpy/calc/age.py +34 -36
- ararpy/calc/arr.py +5 -24
- ararpy/calc/basic.py +26 -3
- ararpy/calc/corr.py +135 -89
- ararpy/calc/jvalue.py +1 -1
- ararpy/calc/plot.py +6 -4
- ararpy/calc/raw_funcs.py +41 -2
- ararpy/calc/regression.py +224 -132
- ararpy/files/arr_file.py +2 -1
- ararpy/files/basic.py +0 -22
- ararpy/files/calc_file.py +107 -84
- ararpy/files/raw_file.py +242 -229
- ararpy/smp/basic.py +202 -46
- ararpy/smp/calculation.py +6 -6
- ararpy/smp/corr.py +339 -154
- ararpy/smp/diffusion_funcs.py +345 -36
- ararpy/smp/export.py +247 -129
- ararpy/smp/info.py +2 -2
- ararpy/smp/initial.py +105 -48
- ararpy/smp/json.py +2 -2
- ararpy/smp/plots.py +225 -218
- ararpy/smp/raw.py +11 -15
- ararpy/smp/sample.py +257 -183
- ararpy/smp/style.py +48 -22
- ararpy/smp/table.py +42 -33
- ararpy/thermo/atomic_level_random_walk.py +56 -48
- ararpy/thermo/basic.py +2 -2
- {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/METADATA +1 -1
- ararpy-0.2.1.dist-info/RECORD +73 -0
- {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/WHEEL +1 -1
- ararpy-0.1.198.dist-info/RECORD +0 -66
- {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/top_level.txt +0 -0
ararpy/smp/plots.py
CHANGED
|
@@ -58,117 +58,126 @@ def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
|
|
|
58
58
|
|
|
59
59
|
# Initialization, apply age spectra data and isochron plot data
|
|
60
60
|
if isInit:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
initial_plot_data(sample)
|
|
62
|
+
# try:
|
|
63
|
+
# initial_plot_data(sample)
|
|
64
|
+
# except (Exception, BaseException):
|
|
65
|
+
# print("initial_plot_data(sample) error:\n", traceback.format_exc())
|
|
66
|
+
# pass
|
|
66
67
|
|
|
67
68
|
# Recalculate isochron lines
|
|
68
69
|
if isIsochron:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
recalc_isochrons(sample, **kwargs)
|
|
71
|
+
reset_isochron_line_data(sample)
|
|
72
|
+
# try:
|
|
73
|
+
# recalc_isochrons(sample, **kwargs)
|
|
74
|
+
# except (Exception, BaseException):
|
|
75
|
+
# print("recalc_isochrons(sample, **kwargs) error:\n", traceback.format_exc())
|
|
76
|
+
# pass
|
|
77
|
+
# try:
|
|
78
|
+
# reset_isochron_line_data(sample)
|
|
79
|
+
# except (Exception, BaseException):
|
|
80
|
+
# print("reset_isochron_line_data(sample):\n", traceback.format_exc())
|
|
81
|
+
# pass
|
|
79
82
|
|
|
80
83
|
# Recalculate plateaus
|
|
81
84
|
if isPlateau:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
recalc_plateaus(sample)
|
|
86
|
+
# try:
|
|
87
|
+
# recalc_plateaus(sample)
|
|
88
|
+
# except (Exception, BaseException):
|
|
89
|
+
# print("recalc_plateaus(sample) error:\n", traceback.format_exc())
|
|
90
|
+
# pass
|
|
87
91
|
|
|
88
92
|
|
|
89
93
|
# =======================
|
|
90
94
|
# Initialize plot data
|
|
91
95
|
# =======================
|
|
92
|
-
def initial_plot_data(
|
|
96
|
+
def initial_plot_data(smp: Sample):
|
|
93
97
|
"""
|
|
94
98
|
Assign initial data for plots
|
|
95
99
|
Parameters
|
|
96
100
|
----------
|
|
97
|
-
|
|
101
|
+
smp : Sample instance
|
|
98
102
|
|
|
99
103
|
Returns
|
|
100
104
|
-------
|
|
101
105
|
None
|
|
102
106
|
"""
|
|
107
|
+
try:
|
|
108
|
+
params_to_check = {
|
|
109
|
+
'normal': {'data': smp.IsochronValues[0:5], 'dtype': float, 'class': 'k1', },
|
|
110
|
+
'inverse': {'data': smp.IsochronValues[6:11], 'dtype': float, 'class': 'k2', },
|
|
111
|
+
'K-Cl-Ar 1': {'data': smp.IsochronValues[12:17], 'dtype': float, 'class': 'k3', },
|
|
112
|
+
'K-Cl-Ar 2': {'data': smp.IsochronValues[18:23], 'dtype': float, 'class': 'k4', },
|
|
113
|
+
'K-Cl-Ar 3': {'data': smp.IsochronValues[24:29], 'dtype': float, 'class': 'k5', },
|
|
114
|
+
'3D': {'data': smp.IsochronValues[30:39], 'dtype': float, 'class': 'k6', },
|
|
115
|
+
'age spectra': [
|
|
116
|
+
{'data': smp.ApparentAgeValues[2:4], 'dtype': float, 'class': 'k7', },
|
|
117
|
+
{'data': smp.ApparentAgeValues[7], 'dtype': float, 'class': 'k7', },
|
|
118
|
+
],
|
|
119
|
+
'degas pattern': {'data': smp.IsochronValues[30:39], 'dtype': float, 'class': 'k8', },
|
|
120
|
+
'age distribution': {'data': smp.IsochronValues[30:39], 'dtype': float, 'class': 'k9', },
|
|
121
|
+
}
|
|
122
|
+
except (IndexError, AttributeError) as e:
|
|
123
|
+
raise
|
|
124
|
+
if not basic.validate_params(**params_to_check):
|
|
125
|
+
return
|
|
126
|
+
|
|
127
|
+
# Isochron plots
|
|
103
128
|
for key, val in ISOCHRON_INDEX_DICT.items():
|
|
104
|
-
figure = basic.get_component_byid(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if '' not in point and None not in point:
|
|
119
|
-
ellipse_data.append(calc.isochron.get_ellipse(*point))
|
|
120
|
-
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
121
|
-
|
|
122
|
-
# Set age spectra lines
|
|
129
|
+
figure = basic.get_component_byid(smp, key)
|
|
130
|
+
figure.data = [
|
|
131
|
+
*smp.IsochronValues[val['data_index'][0]:val['data_index'][1]],
|
|
132
|
+
list(range(smp.Info.experiment.step_num))
|
|
133
|
+
]
|
|
134
|
+
# Ellipse
|
|
135
|
+
if key != 'figure_7':
|
|
136
|
+
ellipse_data = []
|
|
137
|
+
for point in calc.arr.transpose(figure.data[:5]):
|
|
138
|
+
if '' not in point and None not in point:
|
|
139
|
+
ellipse_data.append(calc.isochron.get_ellipse(*point))
|
|
140
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
141
|
+
|
|
142
|
+
# Age spectra plot
|
|
123
143
|
# Try to calculate total gas age
|
|
124
144
|
try:
|
|
125
|
-
|
|
126
|
-
|
|
145
|
+
if str(smp.Info.sample.type).lower() == "unknown":
|
|
146
|
+
a0, e0 = sum(smp.DegasValues[24]), pow(sum([i ** 2 for i in smp.DegasValues[25]]), 0.5)
|
|
147
|
+
a1, e1 = sum(smp.DegasValues[20]), pow(sum([i ** 2 for i in smp.DegasValues[21]]), 0.5)
|
|
148
|
+
handle = basic.calc_age
|
|
149
|
+
elif str(smp.Info.sample.type).lower() == "standard":
|
|
150
|
+
a0, e0 = sum(smp.DegasValues[24]), pow(sum([i ** 2 for i in smp.DegasValues[25]]), 0.5)
|
|
151
|
+
a1, e1 = sum(smp.DegasValues[20]), pow(sum([i ** 2 for i in smp.DegasValues[21]]), 0.5)
|
|
152
|
+
handle = basic.calc_j
|
|
153
|
+
elif str(smp.Info.sample.type).lower() == "air":
|
|
154
|
+
a0, e0 = sum(smp.DegasValues[26]), pow(sum([i ** 2 for i in smp.DegasValues[27]]), 0.5)
|
|
155
|
+
a1, e1 = sum(smp.DegasValues[ 0]), pow(sum([i ** 2 for i in smp.DegasValues[ 1]]), 0.5)
|
|
156
|
+
handle = basic.calc_mdf
|
|
157
|
+
else:
|
|
158
|
+
raise TypeError(f"Sample type is not supported: {smp.Info.sample.type}")
|
|
127
159
|
total_f = [a0 / a1, calc.err.div((a0, e0), (a1, e1))]
|
|
128
|
-
total_age =
|
|
160
|
+
total_age = handle(total_f[:2], smp=smp)
|
|
129
161
|
except (Exception, BaseException):
|
|
130
162
|
print(traceback.format_exc())
|
|
131
163
|
total_f = [np.nan] * 2
|
|
132
164
|
total_age = [np.nan] * 4
|
|
133
|
-
|
|
165
|
+
smp.Info.results.age_spectra['TGA'].update(
|
|
134
166
|
{'Ar39': 100, 'F': total_f[0], 'sF': total_f[1], 'age': total_age[0],
|
|
135
|
-
's1': total_age[1], 's2': total_age[2], 's3': total_age[3], 'Num': len(
|
|
167
|
+
's1': total_age[1], 's2': total_age[2], 's3': total_age[3], 'Num': len(smp.DegasValues[24])}
|
|
136
168
|
)
|
|
137
169
|
try:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
sample.AgeSpectraPlot.data = calc.arr.transpose(sample.AgeSpectraPlot.data)
|
|
170
|
+
smp.AgeSpectraPlot.data = calc.spectra.get_data(*smp.ApparentAgeValues[2:4], smp.ApparentAgeValues[7])
|
|
171
|
+
smp.AgeSpectraPlot.data = calc.arr.transpose(smp.AgeSpectraPlot.data)
|
|
141
172
|
except (Exception, BaseException):
|
|
142
173
|
print(traceback.format_exc())
|
|
143
|
-
|
|
174
|
+
smp.AgeSpectraPlot.data = []
|
|
144
175
|
|
|
145
176
|
# Degassing plot
|
|
146
|
-
|
|
147
|
-
if not hasattr(sample, 'DegasPatternPlot'):
|
|
148
|
-
setattr(sample, 'DegasPatternPlot', Plot(id='figure_8', name='Degas Pattern Plot'))
|
|
149
|
-
isotope_percentage = lambda l: [e / sum(l) * 100 if sum(l) != 0 else 0 for e in l]
|
|
150
|
-
sample.DegasPatternPlot.data = [
|
|
151
|
-
isotope_percentage(sample.DegasValues[0]), # Ar36a
|
|
152
|
-
isotope_percentage(sample.DegasValues[8]), # Ar37Ca
|
|
153
|
-
isotope_percentage(sample.DegasValues[10]), # Ar38Cl
|
|
154
|
-
isotope_percentage(sample.DegasValues[20]), # Ar39K
|
|
155
|
-
isotope_percentage(sample.DegasValues[24]), # Ar40r
|
|
156
|
-
isotope_percentage(sample.CorrectedValues[0]), # Ar36
|
|
157
|
-
isotope_percentage(sample.CorrectedValues[2]), # Ar37
|
|
158
|
-
isotope_percentage(sample.CorrectedValues[4]), # Ar38
|
|
159
|
-
isotope_percentage(sample.CorrectedValues[6]), # Ar39
|
|
160
|
-
isotope_percentage(sample.CorrectedValues[8]), # Ar40
|
|
161
|
-
]
|
|
162
|
-
sample.DegasPatternPlot.info = [True] * 10
|
|
163
|
-
except Exception as e:
|
|
164
|
-
print(traceback.format_exc())
|
|
165
|
-
pass
|
|
177
|
+
recalc_degassing_plot(smp)
|
|
166
178
|
|
|
167
|
-
#
|
|
168
|
-
|
|
169
|
-
recalc_agedistribution(sample)
|
|
170
|
-
except Exception as e:
|
|
171
|
-
print(traceback.format_exc())
|
|
179
|
+
# Age distribution plot
|
|
180
|
+
recalc_agedistribution(smp)
|
|
172
181
|
|
|
173
182
|
|
|
174
183
|
# =======================
|
|
@@ -236,13 +245,14 @@ def get_isochron_results(data: list, smp: Sample, sequence, figure_type: int = 0
|
|
|
236
245
|
|
|
237
246
|
if len(sequence) < 3:
|
|
238
247
|
return iso_res
|
|
239
|
-
regression_method = {
|
|
240
|
-
"york-2": calc.regression.york2, "olst": calc.regression.olst
|
|
241
|
-
}.get(smp.TotalParam[97][min(sequence)].lower(), calc.regression.york2)
|
|
242
248
|
try:
|
|
249
|
+
regression_method = {
|
|
250
|
+
"york-2": calc.regression.york2, "olst": calc.regression.olst
|
|
251
|
+
}.get(smp.TotalParam[97][min(sequence)].lower(), calc.regression.york2)
|
|
243
252
|
regression_res = regression_method(*data[:5])
|
|
244
253
|
except (Exception, BaseException):
|
|
245
|
-
# print(f"
|
|
254
|
+
# print(f"{data[:5] = }")
|
|
255
|
+
# print(f"Warning Isochron Regression: {traceback.format_exc()}")
|
|
246
256
|
return iso_res
|
|
247
257
|
else:
|
|
248
258
|
iso_res.update(dict(zip(reg_res_index, regression_res)))
|
|
@@ -335,50 +345,14 @@ def reset_isochron_line_data(smp: Sample):
|
|
|
335
345
|
for k, v in basic.get_components(smp).items():
|
|
336
346
|
if not isinstance(v, Plot):
|
|
337
347
|
continue
|
|
348
|
+
if k not in ['figure_2', 'figure_3', 'figure_4', 'figure_5', 'figure_6', ]:
|
|
349
|
+
continue
|
|
338
350
|
for index in [0, 1]:
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
setattr(getattr(v, ['text1', 'text2'][index]), 'text', "") # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
345
|
-
except Exception:
|
|
346
|
-
# print(traceback.format_exc())
|
|
347
|
-
continue
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
def set_selection(smp: Sample, index: int, mark: int):
|
|
351
|
-
"""
|
|
352
|
-
Parameters
|
|
353
|
-
----------
|
|
354
|
-
smp : sample instance
|
|
355
|
-
index : int, data point index
|
|
356
|
-
mark : int, 0 for unselected, 1 for set1, 2 for set2
|
|
357
|
-
|
|
358
|
-
Returns
|
|
359
|
-
-------
|
|
360
|
-
|
|
361
|
-
"""
|
|
362
|
-
if mark not in [1, 2, '1', '2']:
|
|
363
|
-
raise ValueError(f"{mark = }, mark must be 1 or 2.")
|
|
364
|
-
|
|
365
|
-
def seq(_i): return [smp.UnselectedSequence, smp.SelectedSequence1, smp.SelectedSequence2][_i]
|
|
366
|
-
|
|
367
|
-
if index in seq(mark):
|
|
368
|
-
seq(mark).remove(index)
|
|
369
|
-
smp.UnselectedSequence.append(index)
|
|
370
|
-
else:
|
|
371
|
-
for i in [0, [0, 2, 1][mark]]:
|
|
372
|
-
if index in seq(i):
|
|
373
|
-
seq(i).remove(index)
|
|
374
|
-
seq(mark).append(index)
|
|
375
|
-
smp.IsochronMark = [
|
|
376
|
-
'1' if i in smp.SelectedSequence1 else '2' if i in smp.SelectedSequence2 else '' for i in
|
|
377
|
-
range(len(smp.IsochronValues[2]))]
|
|
378
|
-
#
|
|
379
|
-
smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
|
|
380
|
-
smp.Info.results.selection[1]['data'] = smp.SelectedSequence2
|
|
381
|
-
smp.Info.results.selection[2]['data'] = smp.UnselectedSequence
|
|
351
|
+
xscale, yscale = [v.xaxis.min, v.xaxis.max], [v.yaxis.min, v.yaxis.max]
|
|
352
|
+
coeffs = [smp.Info.results.isochron[k][index]['k'], smp.Info.results.isochron[k][index]['m1']]
|
|
353
|
+
line_point = calc.isochron.get_line_points(xscale, yscale, coeffs)
|
|
354
|
+
setattr(getattr(v, ['line1', 'line2'][index]), 'data', line_point)
|
|
355
|
+
setattr(getattr(v, ['text1', 'text2'][index]), 'text', "") # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
382
356
|
|
|
383
357
|
|
|
384
358
|
# =======================
|
|
@@ -390,7 +364,7 @@ def recalc_plateaus(sample: Sample, **kwargs):
|
|
|
390
364
|
if sample.Info.sample.type == "Standard":
|
|
391
365
|
return recalc_j_plateaus(sample, **kwargs)
|
|
392
366
|
if sample.Info.sample.type == "Air":
|
|
393
|
-
return
|
|
367
|
+
return recalc_mdf_plateaus(sample, **kwargs)
|
|
394
368
|
|
|
395
369
|
|
|
396
370
|
def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
@@ -405,7 +379,7 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
405
379
|
-------
|
|
406
380
|
None
|
|
407
381
|
"""
|
|
408
|
-
ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.
|
|
382
|
+
ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138])
|
|
409
383
|
ar40r, sar40r = sample.DegasValues[24:26]
|
|
410
384
|
ar40rar39k = calc.arr.div([ar40r, sar40r], [ar39k, sar39k])
|
|
411
385
|
params_initial_ratio = calc.arr.partial(sample.TotalParam, cols=list(range(115, 120)))
|
|
@@ -437,7 +411,7 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
437
411
|
try:
|
|
438
412
|
set1_res, set1_age, set1_data = get_plateau_results(
|
|
439
413
|
sample, sample.SelectedSequence1, calc_ar40ar39(*ratio_set1, smp=sample),
|
|
440
|
-
ar39k_percentage=np.
|
|
414
|
+
ar39k_percentage=np.array(ar39k) / np.sum(ar39k),
|
|
441
415
|
**kwargs)
|
|
442
416
|
except ValueError:
|
|
443
417
|
# print(traceback.format_exc())
|
|
@@ -450,7 +424,7 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
450
424
|
try:
|
|
451
425
|
set2_res, set2_age, set2_data = get_plateau_results(
|
|
452
426
|
sample, sample.SelectedSequence2, calc_ar40ar39(*ratio_set2, smp=sample),
|
|
453
|
-
ar39k_percentage=np.
|
|
427
|
+
ar39k_percentage=np.array(ar39k) / np.sum(ar39k),
|
|
454
428
|
**kwargs)
|
|
455
429
|
except ValueError:
|
|
456
430
|
# print(traceback.format_exc())
|
|
@@ -464,7 +438,7 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
464
438
|
# Weighted mean ages of two sets with 298.56 (defoult air ratio)
|
|
465
439
|
try:
|
|
466
440
|
set1_res = get_wma_results(
|
|
467
|
-
sample, sample.SelectedSequence1, ar40rar39k=ar40rar39k, ar39k_percentage=np.
|
|
441
|
+
sample, sample.SelectedSequence1, ar40rar39k=ar40rar39k, ar39k_percentage=np.array(ar39k) / np.sum(ar39k))
|
|
468
442
|
except ValueError:
|
|
469
443
|
pass
|
|
470
444
|
# raise ValueError(f"Set 1 WMA calculation error.")
|
|
@@ -472,7 +446,7 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
472
446
|
sample.Info.results.age_spectra.update({0: set1_res})
|
|
473
447
|
try:
|
|
474
448
|
set2_res = get_wma_results(
|
|
475
|
-
sample, sample.SelectedSequence2, ar40rar39k=ar40rar39k, ar39k_percentage=np.
|
|
449
|
+
sample, sample.SelectedSequence2, ar40rar39k=ar40rar39k, ar39k_percentage=np.array(ar39k) / np.sum(ar39k))
|
|
476
450
|
except ValueError:
|
|
477
451
|
pass
|
|
478
452
|
# raise ValueError(f"Set 2 WMA calculation error.")
|
|
@@ -552,6 +526,41 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
552
526
|
# # """end"""
|
|
553
527
|
|
|
554
528
|
|
|
529
|
+
def recalc_mdf_plateaus(sample: Sample, **kwargs):
|
|
530
|
+
"""
|
|
531
|
+
Calculate age plateaus results
|
|
532
|
+
Parameters
|
|
533
|
+
----------
|
|
534
|
+
sample : sample instance
|
|
535
|
+
kwargs : optional args, keys in [r1, sr1, r2, sr2]
|
|
536
|
+
|
|
537
|
+
Returns
|
|
538
|
+
-------
|
|
539
|
+
None
|
|
540
|
+
"""
|
|
541
|
+
ar36a, sar36a = calc.arr.mul(sample.DegasValues[0:2], sample.TotalParam[136:138])
|
|
542
|
+
ar40aar36a = sample.ApparentAgeValues[0:2]
|
|
543
|
+
mdf = sample.ApparentAgeValues[2:4]
|
|
544
|
+
|
|
545
|
+
try:
|
|
546
|
+
set1_res, _, set1_data = get_plateau_results(sample, sample.SelectedSequence1, ar40rar39k=ar40aar36a)
|
|
547
|
+
except ValueError:
|
|
548
|
+
pass
|
|
549
|
+
else:
|
|
550
|
+
sample.Info.results.age_plateau.update({0: set1_res})
|
|
551
|
+
sample.AgeSpectraPlot.set1.data = calc.arr.transpose(set1_data)
|
|
552
|
+
sample.AgeSpectraPlot.text1.text = ""
|
|
553
|
+
|
|
554
|
+
try:
|
|
555
|
+
set2_res, _, set2_data = get_plateau_results(sample, sample.SelectedSequence2, ar40rar39k=ar40aar36a)
|
|
556
|
+
except ValueError:
|
|
557
|
+
pass
|
|
558
|
+
else:
|
|
559
|
+
sample.Info.results.age_plateau.update({1: set2_res})
|
|
560
|
+
sample.AgeSpectraPlot.set2.data = calc.arr.transpose(set2_data)
|
|
561
|
+
sample.AgeSpectraPlot.text2.text = ""
|
|
562
|
+
|
|
563
|
+
|
|
555
564
|
def calc_ar40ar39(r, sr, smp):
|
|
556
565
|
"""
|
|
557
566
|
Calculate Ar40r / Ar39K based on passed initial ratio.
|
|
@@ -567,7 +576,7 @@ def calc_ar40ar39(r, sr, smp):
|
|
|
567
576
|
"""
|
|
568
577
|
try:
|
|
569
578
|
ar36a = np.array(smp.DegasValues[0:2])
|
|
570
|
-
ar39k = calc.arr.mul(smp.DegasValues[20:22], smp.
|
|
579
|
+
ar39k = calc.arr.mul(smp.DegasValues[20:22], smp.TotalParam[136:138])
|
|
571
580
|
ar40 = smp.CorrectedValues[8:10]
|
|
572
581
|
ar40k = smp.DegasValues[30:32]
|
|
573
582
|
size = ar36a.shape[-1]
|
|
@@ -586,20 +595,20 @@ def calc_ar40ar39(r, sr, smp):
|
|
|
586
595
|
return ar40rar39k
|
|
587
596
|
|
|
588
597
|
|
|
589
|
-
def get_plateau_results(
|
|
598
|
+
def get_plateau_results(smp: Sample, sequence: list, ar40rar39k: list = None,
|
|
590
599
|
ar39k_percentage: list = None, **kwargs):
|
|
591
600
|
"""
|
|
592
601
|
Get initial ratio re-corrected plateau results
|
|
593
602
|
Parameters
|
|
594
603
|
----------
|
|
595
|
-
|
|
604
|
+
smp : sample instance
|
|
596
605
|
sequence : data slice index
|
|
597
606
|
ar40rar39k :
|
|
598
607
|
ar39k_percentage : Ar39K released
|
|
599
608
|
|
|
600
609
|
Returns
|
|
601
610
|
-------
|
|
602
|
-
three
|
|
611
|
+
three items tuple, result dict, age, and plot data, results keys = [
|
|
603
612
|
'F', 'sF', 'Num', 'MSWD', 'Chisq', 'Pvalue',
|
|
604
613
|
'age', 's1', 's2', 's3', 'Ar39', 'rs'
|
|
605
614
|
]
|
|
@@ -616,21 +625,28 @@ def get_plateau_results(sample: Sample, sequence: list, ar40rar39k: list = None,
|
|
|
616
625
|
if len(sequence) == 0:
|
|
617
626
|
return plateau_res, [], []
|
|
618
627
|
if ar40rar39k is None:
|
|
619
|
-
ar40rar39k =
|
|
628
|
+
ar40rar39k = smp.ApparentAgeValues[0:2]
|
|
620
629
|
if ar39k_percentage is None:
|
|
621
|
-
ar39k_percentage =
|
|
630
|
+
ar39k_percentage = smp.ApparentAgeValues[7]
|
|
631
|
+
|
|
632
|
+
if str(smp.Info.sample.type).lower() == "unknown":
|
|
633
|
+
handle = basic.calc_age
|
|
634
|
+
elif str(smp.Info.sample.type).lower() == "standard":
|
|
635
|
+
handle = basic.calc_j
|
|
636
|
+
elif str(smp.Info.sample.type).lower() == "air":
|
|
637
|
+
handle = basic.calc_mdf
|
|
638
|
+
else:
|
|
639
|
+
raise TypeError(f"Sample type is not supported: {smp.Info.sample.type}")
|
|
622
640
|
|
|
623
|
-
age =
|
|
641
|
+
age = handle(ar40rar39k, smp=smp)[0:2]
|
|
624
642
|
plot_data = calc.spectra.get_data(*age, ar39k_percentage, indices=sequence, **kwargs)
|
|
625
643
|
f_values = _get_partial(sequence, *ar40rar39k)
|
|
626
644
|
age = _get_partial(sequence, *age)
|
|
627
645
|
sum_ar39k = sum(_get_partial(sequence, ar39k_percentage)[0])
|
|
628
646
|
wmf = calc.arr.wtd_mean(*f_values)
|
|
629
|
-
wmage =
|
|
647
|
+
wmage = handle(wmf[0:2], smp=smp)
|
|
630
648
|
|
|
631
|
-
plateau_res.update(dict(zip(
|
|
632
|
-
plateau_res_keys, [*wmf, *wmage, sum_ar39k, np.nan]
|
|
633
|
-
)))
|
|
649
|
+
plateau_res.update(dict(zip(plateau_res_keys, [*wmf, *wmage, sum_ar39k, np.nan])))
|
|
634
650
|
return plateau_res, age, plot_data
|
|
635
651
|
|
|
636
652
|
|
|
@@ -679,13 +695,11 @@ def get_wma_results(sample: Sample, sequence: list, ar40rar39k: list = None, ar3
|
|
|
679
695
|
|
|
680
696
|
def recalc_j_plateaus(sample: Sample, **kwargs):
|
|
681
697
|
|
|
682
|
-
|
|
683
|
-
|
|
698
|
+
ar40rar39k = sample.ApparentAgeValues[0:2]
|
|
684
699
|
j = sample.ApparentAgeValues[2:4]
|
|
685
700
|
|
|
686
701
|
try:
|
|
687
|
-
set1_res, _, set1_data =
|
|
688
|
-
get_j_plateau_results(sample, sample.SelectedSequence1, j)
|
|
702
|
+
set1_res, _, set1_data = get_plateau_results(sample, sample.SelectedSequence1, ar40rar39k=ar40rar39k)
|
|
689
703
|
except ValueError:
|
|
690
704
|
pass
|
|
691
705
|
else:
|
|
@@ -694,8 +708,7 @@ def recalc_j_plateaus(sample: Sample, **kwargs):
|
|
|
694
708
|
sample.AgeSpectraPlot.text1.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
695
709
|
|
|
696
710
|
try:
|
|
697
|
-
set2_res, _, set2_data =
|
|
698
|
-
get_j_plateau_results(sample, sample.SelectedSequence2, j)
|
|
711
|
+
set2_res, _, set2_data = get_plateau_results(sample, sample.SelectedSequence2, ar40rar39k=ar40rar39k)
|
|
699
712
|
except ValueError:
|
|
700
713
|
pass
|
|
701
714
|
else:
|
|
@@ -704,81 +717,75 @@ def recalc_j_plateaus(sample: Sample, **kwargs):
|
|
|
704
717
|
sample.AgeSpectraPlot.text2.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
705
718
|
|
|
706
719
|
|
|
707
|
-
def get_j_plateau_results(sample: Sample, sequence: list, j: list, ar39k_percentage: list = None):
|
|
708
|
-
|
|
709
|
-
def _get_partial(points, *args):
|
|
710
|
-
# return [arg[min(points): max(points) + 1] for arg in args]
|
|
711
|
-
return [[arg[i] for i in points] for arg in args]
|
|
712
|
-
|
|
713
|
-
if ar39k_percentage is None:
|
|
714
|
-
ar39k_percentage = sample.ApparentAgeValues[7]
|
|
715
|
-
sum_ar39k = sum(_get_partial(sequence, ar39k_percentage)[0])
|
|
716
|
-
|
|
717
|
-
j_values = _get_partial(sequence, *j)
|
|
718
|
-
wmj = calc.arr.wtd_mean(*j_values)
|
|
719
|
-
plot_data = [[sum(ar39k_percentage[:min(sequence)]), sum(ar39k_percentage[:max(sequence) + 1])],
|
|
720
|
-
[wmj[0], wmj[0]]]
|
|
721
|
-
|
|
722
|
-
plateau_res_keys = [
|
|
723
|
-
'F', 'sF', 'Num', 'MSWD', 'Chisq', 'Pvalue', 'age', 's1', 's2', 's3', 'Ar39',
|
|
724
|
-
'rs', # 'rs' means relative error of the total sum
|
|
725
|
-
]
|
|
726
|
-
plateau_res = dict(zip(plateau_res_keys, [np.nan for i in plateau_res_keys]))
|
|
727
|
-
plateau_res.update(dict(zip(plateau_res_keys, [*wmj, np.nan, np.nan, np.nan, np.nan, sum_ar39k, np.nan])))
|
|
728
|
-
|
|
729
|
-
return plateau_res, 0, plot_data
|
|
730
|
-
|
|
731
|
-
|
|
732
720
|
# =======================
|
|
733
721
|
# Age Distribution Plot
|
|
734
722
|
# =======================
|
|
735
|
-
def recalc_agedistribution(
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
)
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
break
|
|
723
|
+
def recalc_agedistribution(smp: Sample, **kwargs):
|
|
724
|
+
try:
|
|
725
|
+
ages = smp.ApparentAgeValues[2]
|
|
726
|
+
plot = smp.AgeDistributionPlot
|
|
727
|
+
# Set3: Age bars
|
|
728
|
+
plot.set3.data = calc.arr.remove(smp.ApparentAgeValues[2:4], (None, np.nan))
|
|
729
|
+
|
|
730
|
+
# Set1: Histogram data
|
|
731
|
+
s = getattr(plot.set1, 'bin_start', None)
|
|
732
|
+
w = getattr(plot.set1, 'bin_width', None)
|
|
733
|
+
c = getattr(plot.set1, 'bin_count', None)
|
|
734
|
+
r = getattr(plot.set1, 'bin_rule', None)
|
|
735
|
+
# print(f's = {s}, r = {r}, w = {w}, c = {c}')
|
|
736
|
+
histogram_data = calc.histogram.get_data(ages, s=s, r=r, w=w, c=c)
|
|
737
|
+
plot.set1.data = [histogram_data[1], histogram_data[0], histogram_data[2]] # [half_bins, counts]
|
|
738
|
+
setattr(plot.set1, 'bin_start', histogram_data[3])
|
|
739
|
+
setattr(plot.set1, 'bin_rule', histogram_data[4])
|
|
740
|
+
setattr(plot.set1, 'bin_width', histogram_data[5])
|
|
741
|
+
setattr(plot.set1, 'bin_count', histogram_data[6])
|
|
742
|
+
h = getattr(plot.set2, 'band_width', None)
|
|
743
|
+
k = getattr(plot.set2, 'band_kernel', 'normal')
|
|
744
|
+
t = getattr(plot.set2, 'band_extend', False)
|
|
745
|
+
a = getattr(plot.set2, 'auto_width', 'Scott')
|
|
746
|
+
n = getattr(plot.set2, 'band_points', 1000)
|
|
747
|
+
# print(f'h = {h}, k = {k}, a = {a}, n = {n}, extend = {t}')
|
|
748
|
+
kda_data = calc.histogram.get_kde(
|
|
749
|
+
ages, h=h, k=k, n=n, a=a,
|
|
750
|
+
s=float(getattr(plot.xaxis, 'min')) if t else histogram_data[3],
|
|
751
|
+
e=float(getattr(plot.xaxis, 'max')) if t else histogram_data[7],
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
# Set2: KDA data
|
|
755
|
+
plot.set2.data = kda_data[0] # [values, kda]
|
|
756
|
+
setattr(plot.set2, 'band_width', kda_data[1])
|
|
757
|
+
setattr(plot.set2, 'band_kernel', kda_data[2])
|
|
758
|
+
setattr(plot.set2, 'auto_width', kda_data[3])
|
|
759
|
+
# sorted_data = [i[0] for i in sorted(zipped_data, key=lambda x: x[1])]
|
|
760
|
+
text = f'n = {len(ages)}'
|
|
761
|
+
peaks = find_peaks(kda_data[0][1])
|
|
762
|
+
for index, peak in enumerate(peaks[0].tolist()):
|
|
763
|
+
text = text + f'\nPeak {index}: {kda_data[0][0][peak]:.2f}'
|
|
764
|
+
setattr(plot.text1, 'text', text)
|
|
765
|
+
except (Exception, BaseException):
|
|
766
|
+
print(traceback.format_exc())
|
|
767
|
+
plot.data = [[], []]
|
|
768
|
+
plot.set1.data = [[], []]
|
|
769
|
+
plot.set2.data = [[], []]
|
|
783
770
|
|
|
784
771
|
|
|
772
|
+
# =======================
|
|
773
|
+
# Age Distribution Plot
|
|
774
|
+
# =======================
|
|
775
|
+
def recalc_degassing_plot(smp: Sample, **kwargs):
|
|
776
|
+
if not hasattr(smp, 'DegasPatternPlot'):
|
|
777
|
+
setattr(smp, 'DegasPatternPlot', Plot(id='figure_8', name='Degas Pattern Plot'))
|
|
778
|
+
isotope_percentage = lambda l: [e / sum(l) * 100 if sum(l) != 0 else 0 for e in l]
|
|
779
|
+
smp.DegasPatternPlot.data = [
|
|
780
|
+
isotope_percentage(smp.DegasValues[0]), # Ar36a
|
|
781
|
+
isotope_percentage(smp.DegasValues[8]), # Ar37Ca
|
|
782
|
+
isotope_percentage(smp.DegasValues[10]), # Ar38Cl
|
|
783
|
+
isotope_percentage(smp.DegasValues[20]), # Ar39K
|
|
784
|
+
isotope_percentage(smp.DegasValues[24]), # Ar40r
|
|
785
|
+
isotope_percentage(smp.CorrectedValues[0]), # Ar36
|
|
786
|
+
isotope_percentage(smp.CorrectedValues[2]), # Ar37
|
|
787
|
+
isotope_percentage(smp.CorrectedValues[4]), # Ar38
|
|
788
|
+
isotope_percentage(smp.CorrectedValues[6]), # Ar39
|
|
789
|
+
isotope_percentage(smp.CorrectedValues[8]), # Ar40
|
|
790
|
+
]
|
|
791
|
+
smp.DegasPatternPlot.info = [True] * 10
|