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/basic.py
CHANGED
|
@@ -20,7 +20,7 @@ from typing import Optional, Union, List
|
|
|
20
20
|
from .. import calc
|
|
21
21
|
from ..files.basic import (read as read_params)
|
|
22
22
|
from .sample import Sample, Table, Plot, ArArData, ArArBasic, Sequence, RawData
|
|
23
|
-
from .initial import
|
|
23
|
+
from .initial import PREFERENCE_RES
|
|
24
24
|
|
|
25
25
|
Set = Plot.Set
|
|
26
26
|
Label = Plot.Label
|
|
@@ -30,6 +30,62 @@ Text = Plot.Text
|
|
|
30
30
|
pd.options.mode.chained_assignment = None # default='warn'
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
# =======================
|
|
34
|
+
# Params validate
|
|
35
|
+
# =======================
|
|
36
|
+
class ParamsInvalid(Exception):
|
|
37
|
+
""" """
|
|
38
|
+
def __init__(self, code, message, context=None):
|
|
39
|
+
self.code = code
|
|
40
|
+
self.message = message
|
|
41
|
+
self.context = context or {}
|
|
42
|
+
# 调用父类构造函数,确保异常能正常抛出
|
|
43
|
+
super().__init__(f"{self.message}")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def validate_params(**kwargs):
|
|
47
|
+
|
|
48
|
+
def check(data, dtype, **kwargs):
|
|
49
|
+
k = np.array(data, dtype=dtype)
|
|
50
|
+
# if dtype != str:
|
|
51
|
+
# if np.isnan(k).any():
|
|
52
|
+
# raise ValueError("Array contains NaN value(s)")
|
|
53
|
+
# if np.isinf(k).any():
|
|
54
|
+
# raise ValueError("Array contains Inf value(s)")
|
|
55
|
+
if dtype == bool:
|
|
56
|
+
if not all([isinstance(i, bool) or i in [0, 1] for i in np.array(data).flatten()]):
|
|
57
|
+
raise ValueError("array contains non-bool value(s)")
|
|
58
|
+
elif dtype == int:
|
|
59
|
+
for each in k.flatten():
|
|
60
|
+
if isinstance(each, dtype):
|
|
61
|
+
raise ValueError(f"type error, {type(each)} is given")
|
|
62
|
+
if kwargs.keys().__contains__('func'):
|
|
63
|
+
for each in k.ravel():
|
|
64
|
+
try:
|
|
65
|
+
if not kwargs.get('func')(each):
|
|
66
|
+
raise ValueError
|
|
67
|
+
except (Exception, BaseException) as e:
|
|
68
|
+
raise ValueError(f"{type(e).__name__}: invalid value, {each}")
|
|
69
|
+
|
|
70
|
+
context = {'names': [], 'classnames': [], 'messages': []}
|
|
71
|
+
for index, (name, content) in enumerate(kwargs.items(), 1):
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
if isinstance(content, dict):
|
|
75
|
+
check(**content)
|
|
76
|
+
elif isinstance(content, list):
|
|
77
|
+
for each in content:
|
|
78
|
+
check(**each)
|
|
79
|
+
except (Exception, BaseException) as e:
|
|
80
|
+
context['names'].append(name)
|
|
81
|
+
context['classnames'].append(f"k{index}")
|
|
82
|
+
context['messages'].append(f"{name} {str(e)}")
|
|
83
|
+
if not context['names']:
|
|
84
|
+
return True
|
|
85
|
+
else:
|
|
86
|
+
raise ParamsInvalid(400, '. '.join(context['messages']), context)
|
|
87
|
+
|
|
88
|
+
|
|
33
89
|
# =======================
|
|
34
90
|
# Calculate ages
|
|
35
91
|
# =======================
|
|
@@ -44,39 +100,104 @@ def calc_apparent_ages(smp: Sample):
|
|
|
44
100
|
-------
|
|
45
101
|
|
|
46
102
|
"""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
103
|
+
try:
|
|
104
|
+
params_to_check = {
|
|
105
|
+
'sample type': {'data': smp.Info.sample.type, 'dtype': str, 'func': lambda x: str(x).lower() in ['unknown', 'standard', 'air'],},
|
|
106
|
+
}
|
|
107
|
+
except (IndexError, AttributeError) as e:
|
|
108
|
+
raise
|
|
109
|
+
if not validate_params(**params_to_check):
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
if str(smp.Info.sample.type).lower() == "unknown":
|
|
113
|
+
v = calc_age(smp=smp)
|
|
114
|
+
elif str(smp.Info.sample.type).lower() == "standard":
|
|
115
|
+
v = calc_j(smp=smp)
|
|
116
|
+
elif str(smp.Info.sample.type).lower() == "air":
|
|
117
|
+
v = calc_mdf(smp=smp)
|
|
118
|
+
else:
|
|
119
|
+
raise TypeError(f"Sample type is not supported: {smp.Info.sample.type}")
|
|
120
|
+
|
|
121
|
+
smp.ApparentAgeValues[2:6] = v[0:4]
|
|
122
|
+
smp.PublishValues[5:7] = copy.deepcopy(v[0:2])
|
|
59
123
|
|
|
60
124
|
|
|
61
125
|
def calc_j(ar40ar39=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
126
|
+
params_index_dict = {
|
|
127
|
+
34: 'L', 35: 'rsL', 59: 'Age', 60: 'sAge'
|
|
128
|
+
}
|
|
129
|
+
if ar40ar39 is None and smp is not None:
|
|
130
|
+
ar40ar39 = smp.ApparentAgeValues[0:2] # ar40ar39 air, error
|
|
131
|
+
if len(np.shape(ar40ar39)) == 1:
|
|
132
|
+
ar40ar39 = np.reshape(ar40ar39, (2, 1))
|
|
133
|
+
if index is None:
|
|
134
|
+
index = list(range(np.shape(ar40ar39)[-1]))
|
|
135
|
+
if smp is None and params is None:
|
|
136
|
+
raise ValueError(f"Parameters are required for calculating mdf, or it is empty.")
|
|
137
|
+
if params is not None:
|
|
138
|
+
for key, val in params.items():
|
|
139
|
+
if not isinstance(val, list):
|
|
140
|
+
params[key] = list(val)
|
|
141
|
+
if smp is not None:
|
|
142
|
+
try:
|
|
143
|
+
params_from_smp = dict(zip(
|
|
144
|
+
list(params_index_dict.values()),
|
|
145
|
+
[[smp.TotalParam[i][j] for j in index] for i in params_index_dict.keys()]
|
|
146
|
+
))
|
|
147
|
+
except Exception:
|
|
148
|
+
print(traceback.format_exc())
|
|
149
|
+
raise ValueError(f"Parameters cannot be found in the given sample object")
|
|
150
|
+
if params is not None:
|
|
151
|
+
params_from_smp.update(params)
|
|
152
|
+
params = params_from_smp
|
|
153
|
+
|
|
154
|
+
j = calc.jvalue.j_value(params['Age'], params['sAge'], *ar40ar39, params['L'], params['rsL'])
|
|
155
|
+
|
|
156
|
+
if len(index) == 1:
|
|
157
|
+
return np.array(j).squeeze().tolist()
|
|
158
|
+
else:
|
|
159
|
+
return np.array(j).tolist()
|
|
67
160
|
|
|
68
161
|
|
|
69
162
|
def calc_mdf(ar40ar36=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
163
|
+
params_index_dict = {
|
|
164
|
+
71: 'M36', 72: 'sM36', 79: 'M40', 80: 'sM40', 93: 'Air', 94: 'rsAir', 100: 'Discr'
|
|
165
|
+
}
|
|
166
|
+
if ar40ar36 is None and smp is not None:
|
|
167
|
+
ar40ar36 = smp.ApparentAgeValues[0:2] # ar40ar36 air, error
|
|
168
|
+
if len(np.shape(ar40ar36)) == 1:
|
|
169
|
+
ar40ar36 = np.reshape(ar40ar36, (2, 1))
|
|
170
|
+
if index is None:
|
|
171
|
+
index = list(range(np.shape(ar40ar36)[-1]))
|
|
172
|
+
if smp is None and params is None:
|
|
173
|
+
raise ValueError(f"Parameters are required for calculating mdf, or it is empty.")
|
|
174
|
+
if params is not None:
|
|
175
|
+
for key, val in params.items():
|
|
176
|
+
if not isinstance(val, list):
|
|
177
|
+
params[key] = list(val)
|
|
178
|
+
if smp is not None:
|
|
179
|
+
try:
|
|
180
|
+
params_from_smp = dict(zip(
|
|
181
|
+
list(params_index_dict.values()),
|
|
182
|
+
[[smp.TotalParam[i][j] for j in index] for i in params_index_dict.keys()]
|
|
183
|
+
))
|
|
184
|
+
except Exception:
|
|
185
|
+
print(traceback.format_exc())
|
|
186
|
+
raise ValueError(f"Parameters cannot be found in the given sample object")
|
|
187
|
+
if params is not None:
|
|
188
|
+
params_from_smp.update(params)
|
|
189
|
+
params = params_from_smp
|
|
190
|
+
|
|
75
191
|
mdf = []
|
|
76
|
-
for i in range(len(
|
|
77
|
-
k = calc.corr.mdf(
|
|
78
|
-
|
|
79
|
-
|
|
192
|
+
for i in range(len(index)):
|
|
193
|
+
k = calc.corr.mdf(ar40ar36[0][i], ar40ar36[1][i], params['M36'][i], params['M40'][i],
|
|
194
|
+
params['Air'][i], params['rsAir'][i]) # linear, exp, pow
|
|
195
|
+
mdf.append({"linear": k[0:4], "exp": k[4:8], "pow": k[8:12]}[params['Discr'][i].lower()])
|
|
196
|
+
|
|
197
|
+
if len(index) == 1:
|
|
198
|
+
return np.transpose(mdf).squeeze().tolist()
|
|
199
|
+
else:
|
|
200
|
+
return np.transpose(mdf).tolist()
|
|
80
201
|
|
|
81
202
|
|
|
82
203
|
def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
@@ -95,7 +216,8 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
|
|
|
95
216
|
"""
|
|
96
217
|
params_index_dict = {
|
|
97
218
|
34: 'L', 35: 'sL', 36: 'Le', 37: 'sLe', 38: 'Lb', 39: 'sLb', 48: 'A', 49: 'sA',
|
|
98
|
-
50: 'Ae', 51: 'sAe', 52: 'Ab', 53: 'sAb',
|
|
219
|
+
50: 'Ae', 51: 'sAe', 52: 'Ab', 53: 'sAb', 54: 'Abp', 55: 'sAbp', 59: 't', 60: 'st',
|
|
220
|
+
61: 'Ap', 62: 'sAp', 63: 'Kp', 64: 'sKp', 67: 'J', 68: 'sJ',
|
|
99
221
|
81: 'W', 82: 'sW', 83: 'No', 84: 'sNo', 85: 'Y', 86: 'sY', 87: 'f', 88: 'sf', 110: 'Min'
|
|
100
222
|
}
|
|
101
223
|
|
|
@@ -131,7 +253,7 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
|
|
|
131
253
|
|
|
132
254
|
u = 'Ma'
|
|
133
255
|
try:
|
|
134
|
-
u = smp.Info.preference
|
|
256
|
+
u = smp.Info.preference.age_unit
|
|
135
257
|
except:
|
|
136
258
|
print(traceback.format_exc())
|
|
137
259
|
pass
|
|
@@ -369,21 +491,22 @@ def get_merged_smp(a: Sample, b: (Sample, dict)):
|
|
|
369
491
|
symbol_size = 10, line_type = 'solid'))
|
|
370
492
|
"""
|
|
371
493
|
|
|
372
|
-
def get_similar_name(
|
|
494
|
+
def get_similar_name(name: str):
|
|
373
495
|
res = []
|
|
374
|
-
for
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
for i in range(len(_name)):
|
|
379
|
-
str_list = [i for i in _name]
|
|
380
|
-
str_list[i] = str_list[i].capitalize()
|
|
381
|
-
res.append(''.join(str_list))
|
|
382
|
-
for i in range(len(_name)):
|
|
383
|
-
str_list = [i for i in _name]
|
|
384
|
-
if _name[i] in '-_':
|
|
385
|
-
str_list.pop(i)
|
|
496
|
+
for _name in set([name, name.lower(), name.upper()]):
|
|
497
|
+
for i in range(len(_name) + 1):
|
|
498
|
+
str_list = [i for i in _name]
|
|
499
|
+
str_list.insert(i, '_')
|
|
386
500
|
res.append(''.join(str_list))
|
|
501
|
+
for i in range(len(_name)):
|
|
502
|
+
str_list = [i for i in _name]
|
|
503
|
+
str_list[i] = str_list[i].capitalize()
|
|
504
|
+
res.append(''.join(str_list))
|
|
505
|
+
for i in range(len(_name)):
|
|
506
|
+
str_list = [i for i in _name]
|
|
507
|
+
if _name[i] in '-_':
|
|
508
|
+
str_list.pop(i)
|
|
509
|
+
res.append(''.join(str_list))
|
|
387
510
|
return res
|
|
388
511
|
|
|
389
512
|
if not isinstance(b, dict):
|
|
@@ -555,13 +678,13 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
555
678
|
smp.TotalParam[100:114] = remove_none(
|
|
556
679
|
smp.TotalParam[100:114],
|
|
557
680
|
[['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
|
|
558
|
-
|
|
559
|
-
|
|
681
|
+
for index, (key, val) in enumerate(PREFERENCE_RES.items()):
|
|
682
|
+
setattr(smp.Info.preference, key, type(val)(params[31:35][index]))
|
|
560
683
|
for key, comp in get_components(smp).items():
|
|
561
684
|
if isinstance(comp, Table):
|
|
562
|
-
comp.decimal_places =
|
|
685
|
+
comp.decimal_places = smp.Info.preference.decimal_places
|
|
563
686
|
comp.set_coltypes()
|
|
564
|
-
smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(
|
|
687
|
+
smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(smp.Info.preference.age_unit).capitalize()})"
|
|
565
688
|
|
|
566
689
|
else:
|
|
567
690
|
raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
|
|
@@ -603,3 +726,36 @@ def get_results(smp: Sample):
|
|
|
603
726
|
for (key, value) in smp.Info.results.age_plateau.items()))
|
|
604
727
|
)
|
|
605
728
|
|
|
729
|
+
|
|
730
|
+
def set_selection(smp: Sample, index: int, mark: int):
|
|
731
|
+
"""
|
|
732
|
+
Parameters
|
|
733
|
+
----------
|
|
734
|
+
smp : sample instance
|
|
735
|
+
index : int, data point index
|
|
736
|
+
mark : int, 0 for unselected, 1 for set1, 2 for set2
|
|
737
|
+
|
|
738
|
+
Returns
|
|
739
|
+
-------
|
|
740
|
+
|
|
741
|
+
"""
|
|
742
|
+
if mark not in [1, 2, '1', '2']:
|
|
743
|
+
raise ValueError(f"invalid mark value: {mark}, must be 1 or 2.")
|
|
744
|
+
|
|
745
|
+
def seq(_i): return [smp.UnselectedSequence, smp.SelectedSequence1, smp.SelectedSequence2][_i]
|
|
746
|
+
|
|
747
|
+
if index in seq(mark):
|
|
748
|
+
seq(mark).remove(index)
|
|
749
|
+
smp.UnselectedSequence.append(index)
|
|
750
|
+
else:
|
|
751
|
+
for i in [0, [0, 2, 1][mark]]:
|
|
752
|
+
if index in seq(i):
|
|
753
|
+
seq(i).remove(index)
|
|
754
|
+
seq(mark).append(index)
|
|
755
|
+
smp.IsochronMark = [
|
|
756
|
+
'1' if i in smp.SelectedSequence1 else '2' if i in smp.SelectedSequence2 else '' for i in
|
|
757
|
+
range(len(smp.IsochronValues[2]))]
|
|
758
|
+
#
|
|
759
|
+
smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
|
|
760
|
+
smp.Info.results.selection[1]['data'] = smp.SelectedSequence2
|
|
761
|
+
smp.Info.results.selection[2]['data'] = smp.UnselectedSequence
|
ararpy/smp/calculation.py
CHANGED
|
@@ -22,7 +22,8 @@ def recalculate(
|
|
|
22
22
|
re_corr_blank: bool = False, re_corr_massdiscr: bool = False,
|
|
23
23
|
re_corr_decay: bool = False, re_degas_ca: bool = False, re_degas_k: bool = False,
|
|
24
24
|
re_degas_cl: bool = False, re_degas_atm: bool = False, re_degas_r: bool = False,
|
|
25
|
-
re_calc_ratio: bool = False, re_calc_apparent_age: bool = False,
|
|
25
|
+
re_calc_ratio: bool = False, re_calc_apparent_age: bool = False,
|
|
26
|
+
# monte_carlo: bool = False,
|
|
26
27
|
re_plot: bool = False, re_plot_style: bool = False, re_set_table: bool = False,
|
|
27
28
|
re_table_style: bool = False, **kwargs
|
|
28
29
|
):
|
|
@@ -42,7 +43,6 @@ def recalculate(
|
|
|
42
43
|
re_degas_r
|
|
43
44
|
re_calc_ratio
|
|
44
45
|
re_calc_apparent_age
|
|
45
|
-
monte_carlo
|
|
46
46
|
re_plot
|
|
47
47
|
re_plot_style
|
|
48
48
|
re_set_table
|
|
@@ -59,13 +59,11 @@ def recalculate(
|
|
|
59
59
|
# print(f"{sample.UnselectedSequence = }")
|
|
60
60
|
# print(f"{sample.SelectedSequence1 = }")
|
|
61
61
|
# print(f"{sample.SelectedSequence2 = }")
|
|
62
|
+
|
|
62
63
|
# --- initializing ---
|
|
63
|
-
re_corr_gain = re_corr_blank
|
|
64
64
|
if re_initial: # 1
|
|
65
65
|
initial.re_set_smp(sample)
|
|
66
66
|
# --- calculating ---
|
|
67
|
-
if re_corr_gain: # 2 2024-10-04 add
|
|
68
|
-
corr.corr_gain(sample)
|
|
69
67
|
if re_corr_blank: # 2
|
|
70
68
|
corr.corr_blank(sample)
|
|
71
69
|
if re_corr_massdiscr: # 3
|
|
@@ -82,8 +80,10 @@ def recalculate(
|
|
|
82
80
|
corr.calc_degas_atm(sample)
|
|
83
81
|
if re_degas_r: # 9
|
|
84
82
|
corr.calc_degas_r(sample)
|
|
83
|
+
corr.calc_degas_c(sample)
|
|
85
84
|
if re_calc_ratio: # 10
|
|
86
|
-
corr.calc_ratio(sample
|
|
85
|
+
corr.calc_ratio(sample)
|
|
86
|
+
corr.calc_ratio_monte_carlo(sample)
|
|
87
87
|
if re_calc_apparent_age: # 11
|
|
88
88
|
basic.calc_apparent_ages(sample)
|
|
89
89
|
# --- plot and table ---
|