ararpy 0.0.1a1__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/__init__.py +178 -0
- ararpy/calc/__init__.py +11 -0
- ararpy/calc/age.py +161 -0
- ararpy/calc/arr.py +490 -0
- ararpy/calc/basic.py +57 -0
- ararpy/calc/corr.py +240 -0
- ararpy/calc/err.py +117 -0
- ararpy/calc/histogram.py +166 -0
- ararpy/calc/isochron.py +194 -0
- ararpy/calc/jvalue.py +38 -0
- ararpy/calc/plot.py +68 -0
- ararpy/calc/raw_funcs.py +118 -0
- ararpy/calc/regression.py +961 -0
- ararpy/calc/spectra.py +63 -0
- ararpy/files/__init__.py +2 -0
- ararpy/files/arr_file.py +86 -0
- ararpy/files/basic.py +100 -0
- ararpy/files/calc_file.py +683 -0
- ararpy/files/export.py +1181 -0
- ararpy/files/json.py +49 -0
- ararpy/files/new_file.py +31 -0
- ararpy/files/raw.py +115 -0
- ararpy/files/raw_file.py +14 -0
- ararpy/files/xls.py +27 -0
- ararpy/smp/__init__.py +17 -0
- ararpy/smp/basic.py +371 -0
- ararpy/smp/calculation.py +94 -0
- ararpy/smp/consts.py +20 -0
- ararpy/smp/corr.py +376 -0
- ararpy/smp/initial.py +232 -0
- ararpy/smp/plots.py +636 -0
- ararpy/smp/sample.py +911 -0
- ararpy/smp/style.py +191 -0
- ararpy/smp/table.py +131 -0
- ararpy-0.0.1a1.dist-info/LICENSE +21 -0
- ararpy-0.0.1a1.dist-info/METADATA +269 -0
- ararpy-0.0.1a1.dist-info/RECORD +39 -0
- ararpy-0.0.1a1.dist-info/WHEEL +5 -0
- ararpy-0.0.1a1.dist-info/top_level.txt +1 -0
ararpy/smp/plots.py
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# ==========================================
|
|
5
|
+
# Copyright 2023 Yang
|
|
6
|
+
# ararpy - smp - plots
|
|
7
|
+
# ==========================================
|
|
8
|
+
#
|
|
9
|
+
#
|
|
10
|
+
#
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import traceback
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
from scipy.signal import find_peaks
|
|
17
|
+
import time
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
from .. import calc
|
|
21
|
+
from .sample import Sample, Info, Table, Plot
|
|
22
|
+
from . import basic, initial
|
|
23
|
+
|
|
24
|
+
Set = Plot.Set
|
|
25
|
+
Label = Plot.Label
|
|
26
|
+
Axis = Plot.Axis
|
|
27
|
+
Text = Plot.Text
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
ISOCHRON_INDEX_DICT = {
|
|
31
|
+
'figure_2': {'data_index': [0, 5], 'name': 'Normal Isochron', 'figure_type': 1},
|
|
32
|
+
'figure_3': {'data_index': [6, 11], 'name': 'Inverse Isochron', 'figure_type': 2},
|
|
33
|
+
'figure_4': {'data_index': [12, 17], 'name': 'Cl Correlation 1', 'figure_type': 1},
|
|
34
|
+
'figure_5': {'data_index': [18, 23], 'name': 'Cl Correlation 2', 'figure_type': 2},
|
|
35
|
+
'figure_6': {'data_index': [24, 29], 'name': 'Cl Correlation 3', 'figure_type': 3},
|
|
36
|
+
'figure_7': {'data_index': [30, 39], 'name': 'Cl Correlation 3D', 'figure_type': 0},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# =======================
|
|
41
|
+
# Reset plot data
|
|
42
|
+
# =======================
|
|
43
|
+
def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
|
|
44
|
+
isPlateau: bool = True, **kwargs):
|
|
45
|
+
"""
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
sample
|
|
49
|
+
isInit
|
|
50
|
+
isIsochron
|
|
51
|
+
isPlateau
|
|
52
|
+
kwargs
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
print(f"isInit: {isInit}, isIsochron: {isIsochron}, isPlateau: {isPlateau}")
|
|
59
|
+
|
|
60
|
+
# Initialization, apply age spectra data and isochron plot data
|
|
61
|
+
if isInit:
|
|
62
|
+
try:
|
|
63
|
+
initial_plot_data(sample)
|
|
64
|
+
except (Exception, BaseException):
|
|
65
|
+
print(traceback.format_exc())
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
# Recalculate isochron lines
|
|
69
|
+
if isIsochron:
|
|
70
|
+
try:
|
|
71
|
+
t1 = time.time()
|
|
72
|
+
recalc_isochrons(sample)
|
|
73
|
+
reset_isochron_line_data(sample)
|
|
74
|
+
print(f"recalc_isochrons time = {time.time() - t1}")
|
|
75
|
+
except (Exception, BaseException):
|
|
76
|
+
print(traceback.format_exc())
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
# Recalculate plateaus
|
|
80
|
+
if isPlateau:
|
|
81
|
+
try:
|
|
82
|
+
t1 = time.time()
|
|
83
|
+
recalc_plateaus(sample)
|
|
84
|
+
print(f"recalc_plateaus time = {time.time() - t1}")
|
|
85
|
+
except (Exception, BaseException):
|
|
86
|
+
print(traceback.format_exc())
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# =======================
|
|
91
|
+
# Initialize plot data
|
|
92
|
+
# =======================
|
|
93
|
+
def initial_plot_data(sample: Sample):
|
|
94
|
+
"""
|
|
95
|
+
Assign initial data for plots
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
sample : Sample instance
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
None
|
|
103
|
+
"""
|
|
104
|
+
for key, val in ISOCHRON_INDEX_DICT.items():
|
|
105
|
+
figure = basic.get_component_byid(sample, key)
|
|
106
|
+
try:
|
|
107
|
+
# data = [x, sx, y, sy, (z, sz,) r1, (r2, r3,), index from 1]
|
|
108
|
+
figure.data = sample.IsochronValues[val['data_index'][0]:val['data_index'][1]] + \
|
|
109
|
+
[[i + 1 for i in range(len(sample.SequenceName))]]
|
|
110
|
+
except (Exception, BaseException):
|
|
111
|
+
print(traceback.format_exc())
|
|
112
|
+
figure.data = [[]] * (val['data_index'][1] - val['data_index'][0]) + \
|
|
113
|
+
[[i + 1 for i in range(len(sample.SequenceName))]]
|
|
114
|
+
finally:
|
|
115
|
+
# Ellipse
|
|
116
|
+
if key != 'figure_7':
|
|
117
|
+
ellipse_data = []
|
|
118
|
+
for point in calc.arr.transpose(figure.data[:5]):
|
|
119
|
+
if '' not in point and None not in point:
|
|
120
|
+
ellipse_data.append(calc.isochron.get_ellipse(*point))
|
|
121
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
122
|
+
|
|
123
|
+
# Set age spectra lines
|
|
124
|
+
# Try to calculate total gas age
|
|
125
|
+
try:
|
|
126
|
+
a0, e0 = sum(sample.DegasValues[24]), pow(sum([i ** 2 for i in sample.DegasValues[25]]), 0.5)
|
|
127
|
+
a1, e1 = sum(sample.DegasValues[20]), pow(sum([i ** 2 for i in sample.DegasValues[21]]), 0.5)
|
|
128
|
+
total_f = [a0 / a1, calc.err.div((a0, e0), (a1, e1))]
|
|
129
|
+
total_age = basic.calc_age(total_f[:2], smp=sample)
|
|
130
|
+
except (Exception, BaseException):
|
|
131
|
+
print(traceback.format_exc())
|
|
132
|
+
total_age = [np.nan] * 4
|
|
133
|
+
sample.Info.results.age_spectra.update(dict(zip(['age', 's1', 's2', 's3'], total_age)))
|
|
134
|
+
try:
|
|
135
|
+
sample.AgeSpectraPlot.data = calc.spectra.get_data(
|
|
136
|
+
*sample.ApparentAgeValues[2:4], sample.ApparentAgeValues[7])
|
|
137
|
+
sample.AgeSpectraPlot.data = calc.arr.transpose(sample.AgeSpectraPlot.data)
|
|
138
|
+
except (Exception, BaseException):
|
|
139
|
+
print(traceback.format_exc())
|
|
140
|
+
sample.AgeSpectraPlot.data = []
|
|
141
|
+
|
|
142
|
+
# Degassing plot
|
|
143
|
+
try:
|
|
144
|
+
if not hasattr(sample, 'DegasPatternPlot'):
|
|
145
|
+
setattr(sample, 'DegasPatternPlot', Plot(id='figure_8', name='Degas Pattern Plot'))
|
|
146
|
+
isotope_percentage = lambda l: [e / sum(l) * 100 if sum(l) != 0 else 0 for e in l]
|
|
147
|
+
sample.DegasPatternPlot.data = [
|
|
148
|
+
isotope_percentage(sample.DegasValues[0]), # Ar36a
|
|
149
|
+
isotope_percentage(sample.DegasValues[8]), # Ar37Ca
|
|
150
|
+
isotope_percentage(sample.DegasValues[10]), # Ar38Cl
|
|
151
|
+
isotope_percentage(sample.DegasValues[20]), # Ar39K
|
|
152
|
+
isotope_percentage(sample.DegasValues[24]), # Ar40r
|
|
153
|
+
isotope_percentage(sample.CorrectedValues[0]), # Ar36
|
|
154
|
+
isotope_percentage(sample.CorrectedValues[2]), # Ar37
|
|
155
|
+
isotope_percentage(sample.CorrectedValues[4]), # Ar38
|
|
156
|
+
isotope_percentage(sample.CorrectedValues[6]), # Ar39
|
|
157
|
+
isotope_percentage(sample.CorrectedValues[8]), # Ar40
|
|
158
|
+
]
|
|
159
|
+
sample.DegasPatternPlot.info = [True] * 10
|
|
160
|
+
except Exception as e:
|
|
161
|
+
print(traceback.format_exc())
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
# Set age distribution plot data
|
|
165
|
+
try:
|
|
166
|
+
recalc_agedistribution(sample)
|
|
167
|
+
except Exception as e:
|
|
168
|
+
print(traceback.format_exc())
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# =======================
|
|
172
|
+
# Isochron results
|
|
173
|
+
# =======================
|
|
174
|
+
def recalc_isochrons(sample: Sample, **kwargs):
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
sample
|
|
180
|
+
kwargs
|
|
181
|
+
|
|
182
|
+
Returns
|
|
183
|
+
-------
|
|
184
|
+
|
|
185
|
+
"""
|
|
186
|
+
for key, val in ISOCHRON_INDEX_DICT.items():
|
|
187
|
+
figure = basic.get_component_byid(sample, key)
|
|
188
|
+
figure.set3.data, figure.set1.data, figure.set2.data = \
|
|
189
|
+
sample.UnselectedSequence, sample.SelectedSequence1, sample.SelectedSequence2
|
|
190
|
+
for index, sequence in enumerate([figure.set1.data, figure.set2.data, figure.set3.data]):
|
|
191
|
+
set_data = calc.arr.partial(
|
|
192
|
+
sample.IsochronValues, rows=sequence, cols=list(range(*val['data_index'])))
|
|
193
|
+
if key != 'figure_7':
|
|
194
|
+
iso_res = get_isochron_results(
|
|
195
|
+
set_data, figure_type=val["figure_type"], sample=sample, sequence=sequence)
|
|
196
|
+
sample.Info.results.isochron[figure.id].update({index: iso_res})
|
|
197
|
+
else:
|
|
198
|
+
iso_res = get_3D_results(data=set_data, sequence=sequence, sample=sample)
|
|
199
|
+
sample.Info.results.isochron[figure.id].update({index: iso_res})
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def get_isochron_results(data: list, sample, sequence, figure_type: int = 0):
|
|
203
|
+
"""
|
|
204
|
+
Get isochron figure results based on figure type.
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
data : isochron figure data, 5 columns list
|
|
208
|
+
sample : sample instance
|
|
209
|
+
sequence : data section index
|
|
210
|
+
figure_type : int, 0 for normal isochron, 1 for inverse isochron, 2 for K-Cl-Ar plot 3
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
dict, isochron regression results, keys are [
|
|
215
|
+
'k', 'sk', 'm1', 'sm1', 'MSWD', 'abs_conv', 'iter', 'mag', 'R2', 'Chisq', 'Pvalue',
|
|
216
|
+
'rs', 'age', 's1', 's2', 's3', 'conv', 'initial', 'sinitial', 'F', 'sF'
|
|
217
|
+
]
|
|
218
|
+
"""
|
|
219
|
+
reg_res_index = [
|
|
220
|
+
'k', 'sk', 'm1', 'sm1',
|
|
221
|
+
'MSWD', 'abs_conv', 'iter', 'mag', 'R2', 'Chisq', 'Pvalue',
|
|
222
|
+
'rs', # 'rs' means relative error of the total sum
|
|
223
|
+
]
|
|
224
|
+
age_res_index = ['age', 's1', 's2', 's3', ]
|
|
225
|
+
iso_res = dict(zip(
|
|
226
|
+
[*reg_res_index, *age_res_index, 'conv', 'initial', 'sinitial', 'F', 'sF'],
|
|
227
|
+
[np.nan] * (len(reg_res_index + age_res_index) + 5)
|
|
228
|
+
))
|
|
229
|
+
|
|
230
|
+
if len(sequence) < 3:
|
|
231
|
+
return iso_res
|
|
232
|
+
|
|
233
|
+
try:
|
|
234
|
+
york_res = calc.regression.york2(*data[0:5])
|
|
235
|
+
except (Exception, BaseException):
|
|
236
|
+
print(traceback.format_exc())
|
|
237
|
+
return iso_res
|
|
238
|
+
else:
|
|
239
|
+
iso_res.update(dict(zip(reg_res_index, calc.regression.york2(*data[0:5]))))
|
|
240
|
+
if figure_type == 1:
|
|
241
|
+
iso_res.update(zip(['initial', 'sinitial'], york_res[0:2]))
|
|
242
|
+
iso_res.update(zip(['F', 'sF'], york_res[2:4]))
|
|
243
|
+
elif figure_type == 2:
|
|
244
|
+
iso_res.update(zip(['initial', 'sinitial'], calc.arr.rec(york_res[0:2])))
|
|
245
|
+
k = calc.regression.york2(*data[2:4], *data[0:2], data[4])
|
|
246
|
+
iso_res.update(zip(['F', 'sF'], calc.arr.rec(k[0:2])))
|
|
247
|
+
elif figure_type == 3:
|
|
248
|
+
iso_res.update(zip(['initial', 'sinitial'], york_res[2:4]))
|
|
249
|
+
iso_res.update(zip(['F', 'sF'], york_res[0:2]))
|
|
250
|
+
# age, analytical err, internal err, full external err
|
|
251
|
+
age = basic.calc_age([iso_res['F'], iso_res['sF']], smp=sample)
|
|
252
|
+
iso_res.update(dict(zip(age_res_index, age)))
|
|
253
|
+
return iso_res
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_3D_results(data: list, sequence: list, sample: Sample):
|
|
257
|
+
"""
|
|
258
|
+
Get 3D regression results.
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
data : 3D regression data with 9 columns.
|
|
262
|
+
sequence : list, data section index
|
|
263
|
+
sample : sample instance
|
|
264
|
+
|
|
265
|
+
Returns
|
|
266
|
+
-------
|
|
267
|
+
dict, isochron regression results, with keys = [
|
|
268
|
+
'k', 'sk', 'm1', 'sm1', 'm2', 'sm2',
|
|
269
|
+
'S', 'MSWD', 'R2', 'abs_conv', 'iter', 'mag', 'Chisq', 'Pvalue',
|
|
270
|
+
'rs', 'age', 's1', 's2', 's3', 'conv', 'initial', 'sinitial', 'p_Cl', 'F', 'sF'
|
|
271
|
+
]
|
|
272
|
+
"""
|
|
273
|
+
reg_res_index = [
|
|
274
|
+
'k', 'sk', 'm1', 'sm1', 'm2', 'sm2',
|
|
275
|
+
'S', 'MSWD', 'R2', 'abs_conv', 'iter', 'mag', 'Chisq', 'Pvalue',
|
|
276
|
+
'rs', # 'rs' means relative error of the total sum
|
|
277
|
+
]
|
|
278
|
+
age_res_index = ['age', 's1', 's2', 's3', ]
|
|
279
|
+
iso_res = dict(zip(
|
|
280
|
+
[*reg_res_index, *age_res_index,
|
|
281
|
+
'conv', 'initial', 'sinitial', 'p_Cl', 'F', 'sF'],
|
|
282
|
+
[np.nan] * (len(reg_res_index + age_res_index) + 8)
|
|
283
|
+
))
|
|
284
|
+
try:
|
|
285
|
+
if len(sequence) < 4:
|
|
286
|
+
raise ValueError(f"Data points not enough.")
|
|
287
|
+
k = calc.regression.wtd_3D_regression(*data[:9])
|
|
288
|
+
ar38ar36 = sample.TotalParam[4][0]
|
|
289
|
+
sar38ar36 = sample.TotalParam[5][0] * sample.TotalParam[4][0] / 100
|
|
290
|
+
ar40ar36 = (k[2] + k[4] * ar38ar36) * -1 / k[0]
|
|
291
|
+
sar40ar36 = calc.err.div(
|
|
292
|
+
((k[2] + k[4] * ar38ar36) * -1,
|
|
293
|
+
calc.err.add(k[3], calc.err.mul((k[4], k[5]), (ar38ar36, sar38ar36)))), (k[0], k[1]))
|
|
294
|
+
f = 1 / k[0]
|
|
295
|
+
sf = calc.err.div((1, 0), (k[0], k[1]))
|
|
296
|
+
try:
|
|
297
|
+
PQ = -1 * k[4] / k[2]
|
|
298
|
+
Q = 1 - np.exp(-1 * sample.TotalParam[46][0] * sum(sample.TotalParam[32]) / len(sample.TotalParam[32]))
|
|
299
|
+
P = PQ / Q
|
|
300
|
+
except:
|
|
301
|
+
print(traceback.format_exc())
|
|
302
|
+
P = 0
|
|
303
|
+
age = basic.calc_age([f, sf], smp=sample)
|
|
304
|
+
except:
|
|
305
|
+
print(traceback.format_exc())
|
|
306
|
+
k = [0] * 15
|
|
307
|
+
age = [0] * 4
|
|
308
|
+
ar40ar36, sar40ar36, P = 0, 0, 0
|
|
309
|
+
f, sf = 0, 0
|
|
310
|
+
iso_res.update(dict(zip(iso_res, [*k, *age, np.nan, ar40ar36, sar40ar36, P, f, sf])))
|
|
311
|
+
return iso_res
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def reset_isochron_line_data(smp: Sample):
|
|
315
|
+
"""
|
|
316
|
+
Set isochron regression lines
|
|
317
|
+
Parameters
|
|
318
|
+
----------
|
|
319
|
+
smp : sample instance
|
|
320
|
+
|
|
321
|
+
Returns
|
|
322
|
+
-------
|
|
323
|
+
None, set regression lines data to sample instance.
|
|
324
|
+
"""
|
|
325
|
+
for k, v in basic.get_components(smp).items():
|
|
326
|
+
if not isinstance(v, Plot):
|
|
327
|
+
continue
|
|
328
|
+
for index in [0, 1]:
|
|
329
|
+
try:
|
|
330
|
+
xscale, yscale = [v.xaxis.min, v.xaxis.max], [v.yaxis.min, v.yaxis.max]
|
|
331
|
+
coeffs = [smp.Info.results.isochron[k][index]['k'], smp.Info.results.isochron[k][index]['m1']]
|
|
332
|
+
line_point = calc.isochron.get_line_points(xscale, yscale, coeffs)
|
|
333
|
+
setattr(getattr(v, ['line1', 'line2'][index]), 'data', line_point)
|
|
334
|
+
except Exception:
|
|
335
|
+
# print(traceback.format_exc())
|
|
336
|
+
continue
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def set_selection(smp: Sample, index: int, mark: int):
|
|
340
|
+
"""
|
|
341
|
+
Parameters
|
|
342
|
+
----------
|
|
343
|
+
smp : sample instance
|
|
344
|
+
index : int, data point index
|
|
345
|
+
mark : int, 0 for unselected, 1 for set1, 2 for set2
|
|
346
|
+
|
|
347
|
+
Returns
|
|
348
|
+
-------
|
|
349
|
+
|
|
350
|
+
"""
|
|
351
|
+
if mark not in [1, 2]:
|
|
352
|
+
raise ValueError(f"{mark = }, mark must be 1 or 2.")
|
|
353
|
+
|
|
354
|
+
def seq(_i): return [smp.UnselectedSequence, smp.SelectedSequence1, smp.SelectedSequence2][_i]
|
|
355
|
+
|
|
356
|
+
if index in seq(mark):
|
|
357
|
+
seq(mark).remove(index)
|
|
358
|
+
smp.UnselectedSequence.append(index)
|
|
359
|
+
else:
|
|
360
|
+
for i in [0, [0, 2, 1][mark]]:
|
|
361
|
+
if index in seq(i):
|
|
362
|
+
seq(i).remove(index)
|
|
363
|
+
seq(mark).append(index)
|
|
364
|
+
smp.IsochronMark = [
|
|
365
|
+
1 if i in smp.SelectedSequence1 else 2 if i in smp.SelectedSequence2 else '' for i in
|
|
366
|
+
range(len(smp.IsochronValues[2]))]
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
# =======================
|
|
370
|
+
# Age spectra results
|
|
371
|
+
# =======================
|
|
372
|
+
def recalc_plateaus(sample: Sample, **kwargs):
|
|
373
|
+
"""
|
|
374
|
+
Calculate age plateaus results
|
|
375
|
+
Parameters
|
|
376
|
+
----------
|
|
377
|
+
sample : sample instance
|
|
378
|
+
kwargs : optional args, keys in [r1, sr1, r2, sr2]
|
|
379
|
+
|
|
380
|
+
Returns
|
|
381
|
+
-------
|
|
382
|
+
None
|
|
383
|
+
"""
|
|
384
|
+
params_initial_ratio = calc.arr.partial(sample.TotalParam, cols=list(range(115, 120)))
|
|
385
|
+
ratio_set1 = [[], []]
|
|
386
|
+
ratio_set2 = [[], []]
|
|
387
|
+
for row, item in enumerate(params_initial_ratio[0]):
|
|
388
|
+
if str(item) == '0':
|
|
389
|
+
ratio_set1[0].append(sample.Info.results.isochron['figure_3'][0]['initial'])
|
|
390
|
+
ratio_set1[1].append(sample.Info.results.isochron['figure_3'][0]['sinitial'])
|
|
391
|
+
ratio_set2[0].append(sample.Info.results.isochron['figure_3'][1]['initial'])
|
|
392
|
+
ratio_set2[1].append(sample.Info.results.isochron['figure_3'][1]['sinitial'])
|
|
393
|
+
elif str(item) == '1':
|
|
394
|
+
ratio_set1[0].append(sample.Info.results.isochron['figure_2'][0]['initial'])
|
|
395
|
+
ratio_set1[1].append(sample.Info.results.isochron['figure_2'][0]['sinitial'])
|
|
396
|
+
ratio_set2[0].append(sample.Info.results.isochron['figure_2'][1]['initial'])
|
|
397
|
+
ratio_set2[1].append(sample.Info.results.isochron['figure_2'][1]['sinitial'])
|
|
398
|
+
elif str(item) == '2':
|
|
399
|
+
ratio_set1[0].append(params_initial_ratio[1][row])
|
|
400
|
+
ratio_set1[1].append(params_initial_ratio[2][row])
|
|
401
|
+
ratio_set2[0].append(params_initial_ratio[3][row])
|
|
402
|
+
ratio_set2[1].append(params_initial_ratio[4][row])
|
|
403
|
+
else:
|
|
404
|
+
ratio_set1[0].append(298.56)
|
|
405
|
+
ratio_set1[1].append(0.31)
|
|
406
|
+
ratio_set2[0].append(298.56)
|
|
407
|
+
ratio_set2[1].append(0.31)
|
|
408
|
+
|
|
409
|
+
# Get ages and line data points for each set
|
|
410
|
+
try:
|
|
411
|
+
set1_res, set1_age, set1_data = \
|
|
412
|
+
get_plateau_results(sample, sample.SelectedSequence1, calc_ar40ar39(*ratio_set1, smp=sample))
|
|
413
|
+
except ValueError:
|
|
414
|
+
raise ValueError(f"Set 1 Plateau results calculation error.")
|
|
415
|
+
else:
|
|
416
|
+
sample.Info.results.age_plateau.update({0: set1_res})
|
|
417
|
+
sample.AgeSpectraPlot.set1.data = calc.arr.transpose(set1_data)
|
|
418
|
+
try:
|
|
419
|
+
set2_res, set2_age, set2_data = \
|
|
420
|
+
get_plateau_results(sample, sample.SelectedSequence2, calc_ar40ar39(*ratio_set2, smp=sample))
|
|
421
|
+
except ValueError:
|
|
422
|
+
raise ValueError(f"Set 2 Plateau results calculation error.")
|
|
423
|
+
else:
|
|
424
|
+
sample.Info.results.age_plateau.update({1: set2_res})
|
|
425
|
+
sample.AgeSpectraPlot.set2.data = calc.arr.transpose(set2_data)
|
|
426
|
+
|
|
427
|
+
# # """3D corrected plateaus"""
|
|
428
|
+
# # 3D ratio, 36Ar(a+cl)/40Ar(a+r), 38Ar(a+cl)/40Ar(a+r), 39Ar(k)/40Ar(a+r),
|
|
429
|
+
# ar40ar = calc_funcs.list_sub(*sample.CorrectedValues[8:10], *sample.DegasValues[30:32])
|
|
430
|
+
# # 36Ar deduct Ca, that is sum of 36Ara and 36ArCl
|
|
431
|
+
# ar36acl = calc_funcs.list_sub(*sample.CorrectedValues[0:2], *sample.DegasValues[4:6])
|
|
432
|
+
# # 38Ar deduct K and Ca, that is sum of 38Ara and 38ArCl
|
|
433
|
+
# ar38acl = calc_funcs.list_sub(*calc_funcs.list_sub(*sample.CorrectedValues[4:6], *sample.DegasValues[16:18]),
|
|
434
|
+
# *sample.DegasValues[18:20])
|
|
435
|
+
# # 39ArK
|
|
436
|
+
# ar39k = sample.DegasValues[20:22]
|
|
437
|
+
#
|
|
438
|
+
# # 40Arr
|
|
439
|
+
# def get_modified_f(c, sc, a, sa, b, sb):
|
|
440
|
+
# ar40r = list(map(lambda zi, xi, yi: zi - a * xi - b * yi, ar40ar[0], ar36acl[0], ar38acl[0]))
|
|
441
|
+
# sar40r = list(map(lambda zi, szi, xi, sxi, yi, syi:
|
|
442
|
+
# calc.err.add(szi, calc_funcs.error_mul((xi, sxi), (a, sa)),
|
|
443
|
+
# calc_funcs.error_mul((yi, syi), (b, sb))),
|
|
444
|
+
# *ar40ar, *ar36acl, *ar38acl))
|
|
445
|
+
# f = list(map(lambda ar40ri, ar39ki: ar40ri / ar39ki, ar40r, ar39k[0]))
|
|
446
|
+
# sf = list(map(lambda ar40ri, sar40ri, ar39ki, sar39ki:
|
|
447
|
+
# calc.err.div((ar40ri, sar40ri), (ar39ki, sar39ki)),
|
|
448
|
+
# ar40r, sar40r, *ar39k))
|
|
449
|
+
# return [f, sf]
|
|
450
|
+
#
|
|
451
|
+
# isochron_7 = calc_funcs.get_3D_isochron(*ar36acl, *ar38acl, *ar40ar, *ar39k)
|
|
452
|
+
# [set1_data, set2_data, set3_data] = basic_funcs.getIsochronSetData(
|
|
453
|
+
# isochron_7, sample.SelectedSequence1, sample.SelectedSequence2, sample.UnselectedSequence)
|
|
454
|
+
#
|
|
455
|
+
# __isochron_7 = calc_funcs.get_3D_isochron(*ar36acl, *ar38acl, *ar39k, *ar40ar)
|
|
456
|
+
# [__set1_data, __set2_data, __set3_data] = basic_funcs.getIsochronSetData(
|
|
457
|
+
# __isochron_7, sample.SelectedSequence1, sample.SelectedSequence2, sample.UnselectedSequence)
|
|
458
|
+
#
|
|
459
|
+
# def __get_modified_f(c, sc, a, sa, b, sb):
|
|
460
|
+
# f = list(
|
|
461
|
+
# map(lambda zi, xi, yi: 1 / (zi - a * xi - b * yi), __isochron_7[4], __isochron_7[0], __isochron_7[2]))
|
|
462
|
+
# sf = [0] * len(f)
|
|
463
|
+
# return [f, sf]
|
|
464
|
+
#
|
|
465
|
+
# # set 1:
|
|
466
|
+
# try:
|
|
467
|
+
# k = calc_funcs.wtd_3D_regression(*set1_data[:9])
|
|
468
|
+
# set1_ar40rar39k = get_modified_f(*k[:6])
|
|
469
|
+
#
|
|
470
|
+
# # __k = calc_funcs.wtd_3D_regression(*__set1_data[:9])
|
|
471
|
+
# # __set1_ar40rar39k = __get_modified_f(*__k[:6])
|
|
472
|
+
# #
|
|
473
|
+
# # for i in range(len(set1_ar40rar39k[0])):
|
|
474
|
+
# # print(f"{set1_ar40rar39k[0][i]} == {__set1_ar40rar39k[0][i]}")
|
|
475
|
+
# #
|
|
476
|
+
# # k = calc_funcs.wtd_3D_regression(*__set1_data[:9])
|
|
477
|
+
# # set1_ar40rar39k = __get_modified_f(*k[:6])
|
|
478
|
+
#
|
|
479
|
+
# except:
|
|
480
|
+
# print(traceback.format_exc())
|
|
481
|
+
# set1_ar40rar39k = [[0] * len(ar39k[0]), [0] * len(ar39k[0])]
|
|
482
|
+
# # set 2:
|
|
483
|
+
# try:
|
|
484
|
+
# k = calc_funcs.wtd_3D_regression(*set2_data[:9])
|
|
485
|
+
# set2_ar40rar39k = get_modified_f(*k[:6])
|
|
486
|
+
# except:
|
|
487
|
+
# set2_ar40rar39k = [[0] * len(ar39k[0]), [0] * len(ar39k[0])]
|
|
488
|
+
# set4_age, set4_data, set4_wmf, set4_wmage, set4_text = \
|
|
489
|
+
# get_plateau_results(sample, sample.SelectedSequence1, set1_ar40rar39k)
|
|
490
|
+
# set5_age, set5_data, set5_wmf, set5_wmage, set5_text = \
|
|
491
|
+
# get_plateau_results(sample, sample.SelectedSequence2, set2_ar40rar39k)
|
|
492
|
+
# # Set set4 and set5
|
|
493
|
+
# sample.AgeSpectraPlot.set4.data = calc.arr.transpose(set4_data)
|
|
494
|
+
# sample.AgeSpectraPlot.set5.data = calc.arr.transpose(set5_data)
|
|
495
|
+
# sample.AgeSpectraPlot.set4.info = [*set4_wmf, *set4_wmage] # Info = weighted mean f, sf, np, mswd, age, s, s, s
|
|
496
|
+
# sample.AgeSpectraPlot.set5.info = [*set5_wmf, *set5_wmage] # Info = weighted mean f, sf, np, mswd, age, s, s, s
|
|
497
|
+
# # """end"""
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def calc_ar40ar39(r, sr, smp):
|
|
501
|
+
"""
|
|
502
|
+
Calculate Ar40r / Ar39K based on passed initial ratio.
|
|
503
|
+
Parameters
|
|
504
|
+
----------
|
|
505
|
+
r : ratio value, float or list
|
|
506
|
+
sr : error of the ratio, same type as r
|
|
507
|
+
smp : sample instance
|
|
508
|
+
|
|
509
|
+
Returns
|
|
510
|
+
-------
|
|
511
|
+
Two dimensional list, Ar40r / Ar39K values and errors
|
|
512
|
+
"""
|
|
513
|
+
try:
|
|
514
|
+
ar36a = np.array(smp.DegasValues[0:2])
|
|
515
|
+
ar39k = smp.DegasValues[20:22]
|
|
516
|
+
ar40 = smp.CorrectedValues[8:10]
|
|
517
|
+
ar40k = smp.DegasValues[30:32]
|
|
518
|
+
size = ar36a.shape[-1]
|
|
519
|
+
if isinstance(r, float) and isinstance(sr, float):
|
|
520
|
+
ratio = np.array([[r] * size, [sr] * size])
|
|
521
|
+
elif isinstance(r, list) and isinstance(sr, list):
|
|
522
|
+
ratio = np.array([r, sr])
|
|
523
|
+
else:
|
|
524
|
+
raise ValueError(f"Initial ratio is unsupported.")
|
|
525
|
+
# print(f"{ratio = }")
|
|
526
|
+
# print(f"{ar36a = }")
|
|
527
|
+
ar40a = calc.arr.mul(ar36a, ratio)
|
|
528
|
+
ar40r = calc.arr.sub(ar40, ar40k, ar40a)
|
|
529
|
+
ar40rar39k: list = calc.arr.div(ar40r, ar39k)
|
|
530
|
+
except (IndexError, AttributeError, ValueError):
|
|
531
|
+
raise ValueError(f"Check tables of corrected values and degas values.")
|
|
532
|
+
else:
|
|
533
|
+
return ar40rar39k
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def get_plateau_results(sample: Sample, sequence: list, ar40rar39k: list = None,
|
|
537
|
+
ar39k_percentage: list = None):
|
|
538
|
+
"""
|
|
539
|
+
Get initial ratio re-corrected plateau results
|
|
540
|
+
Parameters
|
|
541
|
+
----------
|
|
542
|
+
sample : sample instance
|
|
543
|
+
sequence : data slice index
|
|
544
|
+
ar40rar39k :
|
|
545
|
+
ar39k_percentage : Ar39K released
|
|
546
|
+
|
|
547
|
+
Returns
|
|
548
|
+
-------
|
|
549
|
+
three itmes tuple, result dict, age, and plot data, results keys = [
|
|
550
|
+
'F', 'sF', 'Num', 'MSWD', 'Chisq', 'Pvalue',
|
|
551
|
+
'age', 's1', 's2', 's3', 'Ar39', 'rs'
|
|
552
|
+
]
|
|
553
|
+
"""
|
|
554
|
+
plateau_res_keys = [
|
|
555
|
+
'F', 'sF', 'Num', 'MSWD', 'Chisq', 'Pvalue', 'age', 's1', 's2', 's3', 'Ar39',
|
|
556
|
+
'rs', # 'rs' means relative error of the total sum
|
|
557
|
+
]
|
|
558
|
+
plateau_res = dict(zip(plateau_res_keys, [np.nan] * len(plateau_res_keys)))
|
|
559
|
+
|
|
560
|
+
def _get_partial(points, *args):
|
|
561
|
+
return [arg[min(points): max(points) + 1] for arg in args]
|
|
562
|
+
|
|
563
|
+
if len(sequence) == 0:
|
|
564
|
+
return plateau_res, [], []
|
|
565
|
+
if ar40rar39k is None:
|
|
566
|
+
ar40rar39k = sample.ApparentAgeValues[0:2]
|
|
567
|
+
if ar39k_percentage is None:
|
|
568
|
+
ar39k_percentage = sample.ApparentAgeValues[7]
|
|
569
|
+
|
|
570
|
+
age = basic.calc_age(ar40ar39=ar40rar39k, smp=sample)[0:2]
|
|
571
|
+
plot_data = calc.spectra.get_data(*age, ar39k_percentage, indices=sequence)
|
|
572
|
+
f_values = _get_partial(sequence, *ar40rar39k)
|
|
573
|
+
age = _get_partial(sequence, *age)
|
|
574
|
+
sum_ar39k = sum(_get_partial(sequence, ar39k_percentage)[0])
|
|
575
|
+
wmf = calc.arr.wtd_mean(*f_values)
|
|
576
|
+
wmage = basic.calc_age(wmf[0:2], smp=sample)
|
|
577
|
+
|
|
578
|
+
plateau_res.update(dict(zip(
|
|
579
|
+
plateau_res_keys, [*wmf, *wmage, sum_ar39k, np.nan]
|
|
580
|
+
)))
|
|
581
|
+
return plateau_res, age, plot_data
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
# =======================
|
|
585
|
+
# Age Distribution Plot
|
|
586
|
+
# =======================
|
|
587
|
+
def recalc_agedistribution(sample: Sample, **kwargs):
|
|
588
|
+
for i in range(2):
|
|
589
|
+
try:
|
|
590
|
+
# Age bars
|
|
591
|
+
sample.AgeDistributionPlot.set3.data = calc.arr.remove(sample.ApparentAgeValues[2:4], (None, np.nan))
|
|
592
|
+
# Set histogram data
|
|
593
|
+
s = getattr(sample.AgeDistributionPlot.set1, 'bin_start', None)
|
|
594
|
+
w = getattr(sample.AgeDistributionPlot.set1, 'bin_width', None)
|
|
595
|
+
c = getattr(sample.AgeDistributionPlot.set1, 'bin_count', None)
|
|
596
|
+
r = getattr(sample.AgeDistributionPlot.set1, 'bin_rule', None)
|
|
597
|
+
# print(f's = {s}, r = {r}, w = {w}, c = {c}')
|
|
598
|
+
histogram_data = calc.histogram.get_data(sample.ApparentAgeValues[2], s=s, r=r, w=w, c=c)
|
|
599
|
+
sample.AgeDistributionPlot.set1.data = [histogram_data[1], histogram_data[0], histogram_data[2]] # [half_bins, counts]
|
|
600
|
+
setattr(sample.AgeDistributionPlot.set1, 'bin_start', histogram_data[3])
|
|
601
|
+
setattr(sample.AgeDistributionPlot.set1, 'bin_rule', histogram_data[4])
|
|
602
|
+
setattr(sample.AgeDistributionPlot.set1, 'bin_width', histogram_data[5])
|
|
603
|
+
setattr(sample.AgeDistributionPlot.set1, 'bin_count', histogram_data[6])
|
|
604
|
+
h = getattr(sample.AgeDistributionPlot.set2, 'band_width', None)
|
|
605
|
+
k = getattr(sample.AgeDistributionPlot.set2, 'band_kernel', 'normal')
|
|
606
|
+
t = getattr(sample.AgeDistributionPlot.set2, 'band_extend', False)
|
|
607
|
+
a = getattr(sample.AgeDistributionPlot.set2, 'auto_width', 'Scott')
|
|
608
|
+
n = getattr(sample.AgeDistributionPlot.set2, 'band_points', 1000)
|
|
609
|
+
# print(f'h = {h}, k = {k}, a = {a}, n = {n}, extend = {t}')
|
|
610
|
+
kda_data = calc.histogram.get_kde(
|
|
611
|
+
sample.ApparentAgeValues[2], h=h, k=k, n=n, a=a,
|
|
612
|
+
s=float(getattr(sample.AgeDistributionPlot.xaxis, 'min')) if t else histogram_data[3],
|
|
613
|
+
e=float(getattr(sample.AgeDistributionPlot.xaxis, 'max')) if t else histogram_data[7],
|
|
614
|
+
)
|
|
615
|
+
sample.AgeDistributionPlot.set2.data = kda_data[0] # [values, kda]
|
|
616
|
+
setattr(sample.AgeDistributionPlot.set2, 'band_width', kda_data[1])
|
|
617
|
+
setattr(sample.AgeDistributionPlot.set2, 'band_kernel', kda_data[2])
|
|
618
|
+
setattr(sample.AgeDistributionPlot.set2, 'auto_width', kda_data[3])
|
|
619
|
+
# sorted_data = [i[0] for i in sorted(zipped_data, key=lambda x: x[1])]
|
|
620
|
+
text = f'n = {len(sample.ApparentAgeValues[2])}'
|
|
621
|
+
peaks = find_peaks(kda_data[0][1])
|
|
622
|
+
for index, peak in enumerate(peaks[0].tolist()):
|
|
623
|
+
text = text + f'\nPeak {index}: {kda_data[0][0][peak]:.2f}'
|
|
624
|
+
setattr(sample.AgeDistributionPlot.text1, 'text', text)
|
|
625
|
+
except AttributeError:
|
|
626
|
+
print(traceback.format_exc())
|
|
627
|
+
initial.re_set_smp(sample)
|
|
628
|
+
continue
|
|
629
|
+
except (Exception, BaseException):
|
|
630
|
+
print(traceback.format_exc())
|
|
631
|
+
sample.AgeDistributionPlot.data = [[], []]
|
|
632
|
+
sample.AgeDistributionPlot.set1.data = [[], []]
|
|
633
|
+
sample.AgeDistributionPlot.set2.data = [[], []]
|
|
634
|
+
break
|
|
635
|
+
|
|
636
|
+
|