ararpy 0.2.3__tar.gz → 0.2.4__tar.gz
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-0.2.3 → ararpy-0.2.4}/PKG-INFO +1 -1
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/__init__.py +2 -20
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/arr.py +5 -2
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/basic.py +11 -5
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/corr.py +8 -5
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/initial.py +19 -4
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/plots.py +248 -203
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/sample.py +2 -1
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/style.py +10 -4
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/table.py +66 -32
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy.egg-info/PKG-INFO +1 -1
- {ararpy-0.2.3 → ararpy-0.2.4}/setup.py +1 -1
- {ararpy-0.2.3 → ararpy-0.2.4}/LICENSE +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/README.md +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Check arr.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Granite Cooling History.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Plot temperature calibration.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Show MDD results.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Show all Kfs age spectra.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Show random walk results.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/Example - Tc calculation.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/__init__.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/age.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/basic.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/corr.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/err.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/histogram.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/isochron.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/jvalue.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/plot.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/raw_funcs.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/regression.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/calc/spectra.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/022_VU124-M11a.ahd +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/20WHA0103.age +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/22WHA0078.xls +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/22WHA0433.age +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/22WHA0433.arr +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/22WHA0433.full.xls +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/24WHN0001-51-592.XLS +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/AHD.input-filter +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/ArAr.calc +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/ArArCALC.age +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/NGX-600 - Copy.TXT +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/NGX-600.TXT +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/NGX-XLS.input-filter +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/Qtegra-exported-xls.input-filter +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/S01-239.csv +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/WH01.irra +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/WHA.pdf +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/raw_example.xls +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/examples/sample-default.smp +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/__init__.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/arr_file.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/basic.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/calc_file.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/new_file.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/raw_file.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/files/xls.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/__init__.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/calculation.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/consts.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/diffusion_funcs.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/export.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/info.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/json.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/smp/raw.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/test.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/thermo/__init__.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/thermo/arrhenius.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/thermo/atomic_level_random_walk.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy/thermo/basic.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy.egg-info/SOURCES.txt +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy.egg-info/dependency_links.txt +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy.egg-info/requires.txt +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/ararpy.egg-info/top_level.txt +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/setup.cfg +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/tests/test.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/tests/test2.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/tests/test_error_correlation.py +0 -0
- {ararpy-0.2.3 → ararpy-0.2.4}/tests/test_regression_methods.py +0 -0
|
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
|
|
|
16
16
|
""" Information """
|
|
17
17
|
|
|
18
18
|
name = 'ararpy'
|
|
19
|
-
version = '0.2.
|
|
19
|
+
version = '0.2.4'
|
|
20
20
|
__version__ = version
|
|
21
21
|
full_version = version
|
|
22
|
-
last_update = '2026-01-
|
|
22
|
+
last_update = '2026-01-07'
|
|
23
23
|
|
|
24
24
|
""" ArArPy Functions """
|
|
25
25
|
|
|
@@ -97,24 +97,6 @@ Sample.set_params = smp.basic.set_params
|
|
|
97
97
|
Sample.set_info = lambda _smp, info: setattr(_smp, 'Info', smp.basic.update_plot_from_dict(_smp.Info, info))
|
|
98
98
|
|
|
99
99
|
Sample.recalculate = lambda _smp, *args, **kwargs: smp.calculation.recalculate(_smp, *args, **kwargs)
|
|
100
|
-
Sample.plot_init = lambda _smp: smp.calculation.recalculate(
|
|
101
|
-
_smp, re_plot=True, isIsochron=False, isInit=True, isPlateau=False)
|
|
102
|
-
Sample.plot_isochron = lambda _smp, **kwargs: smp.calculation.recalculate(
|
|
103
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, **kwargs)
|
|
104
|
-
Sample.plot_age_plateau = lambda _smp: smp.calculation.recalculate(
|
|
105
|
-
_smp, re_plot=True, isIsochron=False, isInit=False, isPlateau=True)
|
|
106
|
-
Sample.plot_normal = lambda _smp: smp.calculation.recalculate(
|
|
107
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_2'])
|
|
108
|
-
Sample.plot_inverse = lambda _smp: smp.calculation.recalculate(
|
|
109
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_3'])
|
|
110
|
-
Sample.plot_cl_1 = lambda _smp: smp.calculation.recalculate(
|
|
111
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_4'])
|
|
112
|
-
Sample.plot_cl_2 = lambda _smp: smp.calculation.recalculate(
|
|
113
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_5'])
|
|
114
|
-
Sample.plot_cl_3 = lambda _smp: smp.calculation.recalculate(
|
|
115
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_6'])
|
|
116
|
-
Sample.plot_3D = lambda _smp: smp.calculation.recalculate(
|
|
117
|
-
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_7'])
|
|
118
100
|
|
|
119
101
|
Sample.to_excel = lambda _smp, file_path, *args, **kwargs: smp.export.to_excel(_smp, file_path=file_path, *args, **kwargs)
|
|
120
102
|
|
|
@@ -311,7 +311,10 @@ def multi_append(a, *args):
|
|
|
311
311
|
|
|
312
312
|
"""
|
|
313
313
|
for arg in args:
|
|
314
|
-
a
|
|
314
|
+
if isinstance(a, list):
|
|
315
|
+
a.append(arg)
|
|
316
|
+
if isinstance(a, np.ndarray):
|
|
317
|
+
a = np.append(a, arg)
|
|
315
318
|
return a
|
|
316
319
|
|
|
317
320
|
|
|
@@ -351,7 +354,7 @@ def create_arr(shape: tuple):
|
|
|
351
354
|
|
|
352
355
|
"""
|
|
353
356
|
if len(shape) == 1:
|
|
354
|
-
return []
|
|
357
|
+
return [0 for i in range(shape[0])]
|
|
355
358
|
return [create_arr(shape[1:]) for i in range(shape[0])]
|
|
356
359
|
|
|
357
360
|
|
|
@@ -35,15 +35,16 @@ pd.options.mode.chained_assignment = None # default='warn'
|
|
|
35
35
|
# =======================
|
|
36
36
|
class ParamsInvalid(Exception):
|
|
37
37
|
""" """
|
|
38
|
-
def __init__(self, code, message, context=None):
|
|
38
|
+
def __init__(self, code=400, message="", context=None, fatal=True):
|
|
39
39
|
self.code = code
|
|
40
40
|
self.message = message
|
|
41
41
|
self.context = context or {}
|
|
42
|
+
self.fatal = fatal
|
|
42
43
|
# 调用父类构造函数,确保异常能正常抛出
|
|
43
44
|
super().__init__(f"{self.message}")
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
def validate_params(**kwargs):
|
|
47
|
+
def validate_params(fatal=True, **kwargs):
|
|
47
48
|
|
|
48
49
|
def check(data, dtype, **kwargs):
|
|
49
50
|
k = np.array(data, dtype=dtype)
|
|
@@ -65,7 +66,7 @@ def validate_params(**kwargs):
|
|
|
65
66
|
if not kwargs.get('func')(each):
|
|
66
67
|
raise ValueError
|
|
67
68
|
except (Exception, BaseException) as e:
|
|
68
|
-
raise ValueError(f"
|
|
69
|
+
raise ValueError(f"invalid value, {each}")
|
|
69
70
|
|
|
70
71
|
context = {'names': [], 'classnames': [], 'messages': []}
|
|
71
72
|
for index, (name, content) in enumerate(kwargs.items(), 1):
|
|
@@ -83,7 +84,7 @@ def validate_params(**kwargs):
|
|
|
83
84
|
if not context['names']:
|
|
84
85
|
return True
|
|
85
86
|
else:
|
|
86
|
-
raise ParamsInvalid(400, '. '.join(context['messages']), context)
|
|
87
|
+
raise ParamsInvalid(400, '. '.join(context['messages']), context, fatal=fatal)
|
|
87
88
|
|
|
88
89
|
|
|
89
90
|
# =======================
|
|
@@ -268,7 +269,7 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
|
|
|
268
269
|
age_unit_factor = 1
|
|
269
270
|
|
|
270
271
|
# check if using Min equation
|
|
271
|
-
params['Min'] = [
|
|
272
|
+
params['Min'] = [bool(i) for i in params['Min']]
|
|
272
273
|
|
|
273
274
|
idx1 = np.flatnonzero(np.where(params['Min'], True, False)) # True, using Min equation
|
|
274
275
|
idx2 = np.flatnonzero(np.where(params['Min'], False, True)) # False
|
|
@@ -668,6 +669,10 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
668
669
|
else:
|
|
669
670
|
smp.TotalParam[32] = [item / (3600 * 24 * 365.242) if index in rows else smp.TotalParam[32][index] for index, item in enumerate(stand_time_second)] # stand year
|
|
670
671
|
|
|
672
|
+
smp.Info.irradiation.label = params[-3]
|
|
673
|
+
smp.Info.irradiation.location = params[-2]
|
|
674
|
+
smp.Info.irradiation.info = params[-1]
|
|
675
|
+
|
|
671
676
|
elif flag == 'smp':
|
|
672
677
|
smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], rows, n)
|
|
673
678
|
smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], rows, n)
|
|
@@ -702,6 +707,7 @@ def get_sequence(smp: Sample):
|
|
|
702
707
|
smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
|
|
703
708
|
smp.Info.results.selection[1]['data'] = smp.SelectedSequence2
|
|
704
709
|
smp.Info.results.selection[2]['data'] = smp.UnselectedSequence
|
|
710
|
+
smp.Info.experiment.step_num = len(smp.SequenceName)
|
|
705
711
|
return ArArBasic(
|
|
706
712
|
size=len(smp.SequenceName), name=smp.SequenceName, value=smp.SequenceValue, unit=smp.SequenceUnit,
|
|
707
713
|
mark=ArArBasic(
|
|
@@ -153,10 +153,13 @@ def corr_decay(sample: Sample):
|
|
|
153
153
|
corrDecay37 = sample.TotalParam[104]
|
|
154
154
|
corrDecay39 = sample.TotalParam[105]
|
|
155
155
|
sample.CorrectedValues = copy.deepcopy(sample.MassDiscrCorrected)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
for idx in range(sample.Info.experiment.step_num):
|
|
157
|
+
if corrDecay37[idx]:
|
|
158
|
+
sample.CorrectedValues[2][idx] = decay_corrected[2][idx]
|
|
159
|
+
sample.CorrectedValues[3][idx] = decay_corrected[3][idx]
|
|
160
|
+
if corrDecay39[idx]:
|
|
161
|
+
sample.CorrectedValues[6][idx] = decay_corrected[6][idx]
|
|
162
|
+
sample.CorrectedValues[7][idx] = decay_corrected[7][idx]
|
|
160
163
|
|
|
161
164
|
data = np.array(sample.CorrectedValues)
|
|
162
165
|
data[1:10:2] = data[1:10:2] = np.abs(np.divide(data[1:10:2], data[0:10:2])) * 100
|
|
@@ -769,7 +772,7 @@ def monte_carlo_f(sample: Sample):
|
|
|
769
772
|
blank_gain_corr=sample.TotalParam[111][i],
|
|
770
773
|
MDF_method=sample.TotalParam[100][i],
|
|
771
774
|
force_to_zero=sample.TotalParam[101][i],
|
|
772
|
-
monte_carlo_size=
|
|
775
|
+
monte_carlo_size=4000,
|
|
773
776
|
)
|
|
774
777
|
|
|
775
778
|
yield res
|
|
@@ -191,7 +191,7 @@ def initial(smp: Sample):
|
|
|
191
191
|
),
|
|
192
192
|
preference=ArArBasic(**PREFERENCE_RES),
|
|
193
193
|
irradiation= ArArBasic(
|
|
194
|
-
label='', pos_h='', pos_x='', pos_y='',
|
|
194
|
+
label='', pos_h='', pos_x='', pos_y='', location='', info=''
|
|
195
195
|
)
|
|
196
196
|
))
|
|
197
197
|
|
|
@@ -234,7 +234,7 @@ def initial(smp: Sample):
|
|
|
234
234
|
))
|
|
235
235
|
setattr(smp, 'TotalParamsTable', Table(
|
|
236
236
|
id='8', name='Total Params', header=samples.TOTAL_PARAMS_HEADERS, decimal_places=decimal_places,
|
|
237
|
-
text_indexes=[0, 1, 2, 30, 31, 33, 34, 61, 100, 103,
|
|
237
|
+
text_indexes=[0, 1, 2, 29, 30, 31, 33, 34, 61, 100, 103, 118],
|
|
238
238
|
# numeric_indexes=list(range(1, 120)),
|
|
239
239
|
))
|
|
240
240
|
|
|
@@ -359,10 +359,25 @@ def check_version(smp: Sample):
|
|
|
359
359
|
smp.TotalParam[32] = [np.nan for index in range(smp.Info.experiment.step_num)]
|
|
360
360
|
else:
|
|
361
361
|
smp.TotalParam[32] = [item / (3600 * 24 * 365.242) for item in stand_time_second] # stand year
|
|
362
|
-
smp = smp.recalculate(re_table_style=True)
|
|
363
|
-
smp = smp.recalculate(re_set_table=True)
|
|
364
362
|
smp.version = "20251001"
|
|
365
363
|
|
|
364
|
+
# 20251231 change publish table
|
|
365
|
+
if version < 20251231:
|
|
366
|
+
smp.PublishValues = arr.create_arr((len(samples.PUBLISH_TABLE_HEADERS) - 3, smp.Info.experiment.step_num))
|
|
367
|
+
try:
|
|
368
|
+
data = np.array(smp.CorrectedValues)
|
|
369
|
+
data[1:10:2] = np.abs(np.divide(data[1:10:2], data[0:10:2])) * 100
|
|
370
|
+
smp.PublishValues[0:10] = copy.deepcopy(data.tolist())
|
|
371
|
+
smp.PublishValues[10:14] = copy.deepcopy(smp.ApparentAgeValues[0:4])
|
|
372
|
+
smp.PublishValues[14:16] = copy.deepcopy(smp.ApparentAgeValues[6:8])
|
|
373
|
+
except (BaseException, Exception) as e:
|
|
374
|
+
print(f"{type(e).__name__}: {str(e)}")
|
|
375
|
+
pass
|
|
376
|
+
else:
|
|
377
|
+
smp = smp.recalculate(re_table_style=True)
|
|
378
|
+
smp = smp.recalculate(re_set_table=True)
|
|
379
|
+
smp.version = "20251231"
|
|
380
|
+
|
|
366
381
|
return smp
|
|
367
382
|
|
|
368
383
|
|
|
@@ -36,182 +36,176 @@ ISOCHRON_INDEX_DICT = {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
# Reset plot data
|
|
41
|
-
# =======================
|
|
42
|
-
def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
|
|
43
|
-
isPlateau: bool = True, **kwargs):
|
|
39
|
+
def set_plot_data(sample: Sample, isInit: bool = True, **kwargs):
|
|
44
40
|
"""
|
|
45
41
|
Parameters
|
|
46
42
|
----------
|
|
47
43
|
sample
|
|
48
|
-
isInit
|
|
49
|
-
isIsochron
|
|
50
|
-
isPlateau
|
|
51
44
|
kwargs
|
|
52
45
|
|
|
53
46
|
Returns
|
|
54
47
|
-------
|
|
55
48
|
|
|
56
49
|
"""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
# try:
|
|
87
|
-
# recalc_plateaus(sample)
|
|
88
|
-
# except (Exception, BaseException):
|
|
89
|
-
# print("recalc_plateaus(sample) error:\n", traceback.format_exc())
|
|
90
|
-
# pass
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
# =======================
|
|
94
|
-
# Initialize plot data
|
|
95
|
-
# =======================
|
|
96
|
-
def initial_plot_data(smp: Sample):
|
|
50
|
+
all_figures = ['figure_2', 'figure_3', 'figure_4', 'figure_5', 'figure_6', 'figure_7', 'figure_8', 'figure_9', 'figure_1', ]
|
|
51
|
+
figures = kwargs.get('figures', all_figures)
|
|
52
|
+
for idx, fig_id in enumerate(all_figures):
|
|
53
|
+
if fig_id not in figures:
|
|
54
|
+
continue
|
|
55
|
+
if fig_id == 'figure_1':
|
|
56
|
+
if isInit:
|
|
57
|
+
init_age_spec_plot(sample)
|
|
58
|
+
recalc_plateaus(sample)
|
|
59
|
+
if fig_id == 'figure_2':
|
|
60
|
+
plot_normal_iso(sample, isInit=isInit)
|
|
61
|
+
if fig_id == 'figure_3':
|
|
62
|
+
plot_inverse_iso(sample, isInit=isInit)
|
|
63
|
+
if fig_id == 'figure_4':
|
|
64
|
+
plot_cl1_iso(sample, isInit=isInit)
|
|
65
|
+
if fig_id == 'figure_5':
|
|
66
|
+
plot_cl2_iso(sample, isInit=isInit)
|
|
67
|
+
if fig_id == 'figure_6':
|
|
68
|
+
plot_cl3_iso(sample, isInit=isInit)
|
|
69
|
+
if fig_id == 'figure_7':
|
|
70
|
+
plot_3D_iso(sample, isInit=isInit)
|
|
71
|
+
if fig_id == 'figure_8':
|
|
72
|
+
recalc_degassing_plot(sample)
|
|
73
|
+
if fig_id == 'figure_9':
|
|
74
|
+
recalc_agedistribution(sample)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Isochrons
|
|
78
|
+
def get_iso_res(sample: Sample, figure: Plot):
|
|
97
79
|
"""
|
|
98
|
-
|
|
80
|
+
|
|
99
81
|
Parameters
|
|
100
82
|
----------
|
|
101
|
-
|
|
83
|
+
sample
|
|
84
|
+
kwargs
|
|
102
85
|
|
|
103
86
|
Returns
|
|
104
87
|
-------
|
|
105
|
-
None
|
|
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
88
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
list(range(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
|
143
|
-
# Try to calculate total gas age
|
|
144
|
-
try:
|
|
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
|
|
89
|
+
"""
|
|
90
|
+
figure.set3.data, figure.set1.data, figure.set2.data = \
|
|
91
|
+
sample.UnselectedSequence.copy(), sample.SelectedSequence1.copy(), sample.SelectedSequence2.copy()
|
|
92
|
+
for index, sequence in enumerate([figure.set1.data, figure.set2.data, figure.set3.data]):
|
|
93
|
+
set_data = calc.arr.partial(
|
|
94
|
+
sample.IsochronValues, rows=sequence, cols=list(range(*ISOCHRON_INDEX_DICT[figure.id]['data_index'])))
|
|
95
|
+
if figure.id != 'figure_7':
|
|
96
|
+
iso_res = get_isochron_results(
|
|
97
|
+
set_data, figure_type=ISOCHRON_INDEX_DICT[figure.id]["figure_type"], smp=sample, sequence=sequence)
|
|
98
|
+
sample.Info.results.isochron[figure.id].update({index: iso_res})
|
|
157
99
|
else:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
total_age = handle(total_f[:2], smp=smp)
|
|
161
|
-
except (Exception, BaseException):
|
|
162
|
-
print(traceback.format_exc())
|
|
163
|
-
total_f = [np.nan] * 2
|
|
164
|
-
total_age = [np.nan] * 4
|
|
165
|
-
smp.Info.results.age_spectra['TGA'].update(
|
|
166
|
-
{'Ar39': 100, 'F': total_f[0], 'sF': total_f[1], 'age': total_age[0],
|
|
167
|
-
's1': total_age[1], 's2': total_age[2], 's3': total_age[3], 'Num': len(smp.DegasValues[24])}
|
|
168
|
-
)
|
|
169
|
-
try:
|
|
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)
|
|
172
|
-
except (Exception, BaseException):
|
|
173
|
-
print(traceback.format_exc())
|
|
174
|
-
smp.AgeSpectraPlot.data = []
|
|
100
|
+
iso_res = get_3D_results(data=set_data, sequence=sequence, sample=sample)
|
|
101
|
+
sample.Info.results.isochron[figure.id].update({index: iso_res})
|
|
175
102
|
|
|
176
|
-
# Degassing plot
|
|
177
|
-
recalc_degassing_plot(smp)
|
|
178
103
|
|
|
179
|
-
|
|
180
|
-
recalc_agedistribution(smp)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# =======================
|
|
184
|
-
# Isochron results
|
|
185
|
-
# =======================
|
|
186
|
-
def recalc_isochrons(sample: Sample, **kwargs):
|
|
104
|
+
def set_iso_line_data(sample: Sample, figure: Plot):
|
|
187
105
|
"""
|
|
188
|
-
|
|
106
|
+
Set isochron regression lines
|
|
189
107
|
Parameters
|
|
190
108
|
----------
|
|
191
|
-
sample
|
|
192
|
-
kwargs
|
|
109
|
+
sample : sample instance
|
|
193
110
|
|
|
194
111
|
Returns
|
|
195
112
|
-------
|
|
196
|
-
|
|
113
|
+
None, set regression lines data to sample instance.
|
|
197
114
|
"""
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
figure
|
|
203
|
-
figure
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
115
|
+
for index in [0, 1]:
|
|
116
|
+
xscale, yscale = [figure.xaxis.min, figure.xaxis.max], [figure.yaxis.min, figure.yaxis.max]
|
|
117
|
+
coeffs = [sample.Info.results.isochron[figure.id][index]['k'], sample.Info.results.isochron[figure.id][index]['m1']]
|
|
118
|
+
line_point = calc.isochron.get_line_points(xscale, yscale, coeffs)
|
|
119
|
+
setattr(getattr(figure, ['line1', 'line2'][index]), 'data', line_point)
|
|
120
|
+
setattr(getattr(figure, ['text1', 'text2'][index]), 'text', "") # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def get_iso_init(sample: Sample, figure: Plot):
|
|
124
|
+
# data
|
|
125
|
+
val = ISOCHRON_INDEX_DICT.get(figure.id)['data_index']
|
|
126
|
+
data = [*sample.IsochronValues[val[0]:val[1]], list(range(sample.Info.experiment.step_num))]
|
|
127
|
+
# ellipse
|
|
128
|
+
ellipse_data = []
|
|
129
|
+
if figure.id != 'figure_7':
|
|
130
|
+
for point in calc.arr.transpose(data[:5]):
|
|
131
|
+
if '' not in point and None not in point:
|
|
132
|
+
ellipse_data.append(calc.isochron.get_ellipse(*point))
|
|
133
|
+
return data, ellipse_data
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def plot_normal_iso(sample: Sample, isInit: bool = False):
|
|
137
|
+
figure = sample.NorIsochronPlot
|
|
138
|
+
# data
|
|
139
|
+
if isInit:
|
|
140
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
141
|
+
figure.data = data
|
|
142
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
143
|
+
# iso res
|
|
144
|
+
get_iso_res(sample, figure)
|
|
145
|
+
# line data
|
|
146
|
+
set_iso_line_data(sample, figure)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def plot_inverse_iso(sample: Sample, isInit: bool = False):
|
|
150
|
+
figure = sample.InvIsochronPlot
|
|
151
|
+
# data
|
|
152
|
+
if isInit:
|
|
153
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
154
|
+
figure.data = data
|
|
155
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
156
|
+
# iso res
|
|
157
|
+
get_iso_res(sample, figure)
|
|
158
|
+
# line data
|
|
159
|
+
set_iso_line_data(sample, figure)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def plot_cl1_iso(sample: Sample, isInit: bool = False):
|
|
163
|
+
figure = sample.KClAr1IsochronPlot
|
|
164
|
+
# data
|
|
165
|
+
if isInit:
|
|
166
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
167
|
+
figure.data = data
|
|
168
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
169
|
+
# iso res
|
|
170
|
+
get_iso_res(sample, figure)
|
|
171
|
+
# line data
|
|
172
|
+
set_iso_line_data(sample, figure)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def plot_cl2_iso(sample: Sample, isInit: bool = False):
|
|
176
|
+
figure = sample.KClAr2IsochronPlot
|
|
177
|
+
# data
|
|
178
|
+
if isInit:
|
|
179
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
180
|
+
figure.data = data
|
|
181
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
182
|
+
# iso res
|
|
183
|
+
get_iso_res(sample, figure)
|
|
184
|
+
# line data
|
|
185
|
+
set_iso_line_data(sample, figure)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def plot_cl3_iso(sample: Sample, isInit: bool = False):
|
|
189
|
+
figure = sample.KClAr3IsochronPlot
|
|
190
|
+
# data
|
|
191
|
+
if isInit:
|
|
192
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
193
|
+
figure.data = data
|
|
194
|
+
getattr(figure, 'ellipse', Set(id='ellipse')).data = ellipse_data
|
|
195
|
+
# iso res
|
|
196
|
+
get_iso_res(sample, figure)
|
|
197
|
+
# line data
|
|
198
|
+
set_iso_line_data(sample, figure)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def plot_3D_iso(sample: Sample, isInit: bool = False):
|
|
202
|
+
figure = sample.ThreeDIsochronPlot
|
|
203
|
+
# data
|
|
204
|
+
if isInit:
|
|
205
|
+
data, ellipse_data = get_iso_init(sample, figure)
|
|
206
|
+
figure.data = data
|
|
207
|
+
# iso res
|
|
208
|
+
get_iso_res(sample, figure)
|
|
215
209
|
|
|
216
210
|
|
|
217
211
|
def get_isochron_results(data: list, smp: Sample, sequence, figure_type: int = 0):
|
|
@@ -331,33 +325,55 @@ def get_3D_results(data: list, sequence: list, sample: Sample):
|
|
|
331
325
|
return iso_res
|
|
332
326
|
|
|
333
327
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
Set isochron regression lines
|
|
337
|
-
Parameters
|
|
338
|
-
----------
|
|
339
|
-
smp : sample instance
|
|
328
|
+
# Spectra
|
|
329
|
+
def init_age_spec_plot(sample: Sample):
|
|
340
330
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
331
|
+
figure = sample.AgeSpectraPlot
|
|
332
|
+
|
|
333
|
+
try:
|
|
334
|
+
params_to_check = {
|
|
335
|
+
'40Arr/39ArK': {'data': sample.ApparentAgeValues[2:4], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
|
|
336
|
+
'39ArK%': {'data': sample.ApparentAgeValues[7], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
|
|
337
|
+
}
|
|
338
|
+
except (IndexError, AttributeError) as e:
|
|
339
|
+
raise
|
|
340
|
+
if not basic.validate_params(fatal=False, **params_to_check):
|
|
341
|
+
return
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
if str(sample.Info.sample.type).lower() == "unknown":
|
|
345
|
+
a0, e0 = sum(sample.DegasValues[24]), pow(sum([i ** 2 for i in sample.DegasValues[25]]), 0.5)
|
|
346
|
+
a1, e1 = sum(sample.DegasValues[20]), pow(sum([i ** 2 for i in sample.DegasValues[21]]), 0.5)
|
|
347
|
+
handler = basic.calc_age
|
|
348
|
+
elif str(sample.Info.sample.type).lower() == "standard":
|
|
349
|
+
a0, e0 = sum(sample.DegasValues[24]), pow(sum([i ** 2 for i in sample.DegasValues[25]]), 0.5)
|
|
350
|
+
a1, e1 = sum(sample.DegasValues[20]), pow(sum([i ** 2 for i in sample.DegasValues[21]]), 0.5)
|
|
351
|
+
handler = basic.calc_j
|
|
352
|
+
elif str(sample.Info.sample.type).lower() == "air":
|
|
353
|
+
a0, e0 = sum(sample.DegasValues[26]), pow(sum([i ** 2 for i in sample.DegasValues[27]]), 0.5)
|
|
354
|
+
a1, e1 = sum(sample.DegasValues[ 0]), pow(sum([i ** 2 for i in sample.DegasValues[ 1]]), 0.5)
|
|
355
|
+
handler = basic.calc_mdf
|
|
356
|
+
else:
|
|
357
|
+
msg = f"Sample type is not supported: {sample.Info.sample.type}"
|
|
358
|
+
context = {'names': [figure.name], 'classnames': [f'k7'], 'messages': [msg]}
|
|
359
|
+
raise basic.ParamsInvalid(400, msg, context=context, fatal=False)
|
|
360
|
+
|
|
361
|
+
total_f = [a0 / a1, calc.err.div((a0, e0), (a1, e1))]
|
|
362
|
+
total_age = handler(total_f[:2], smp=sample)
|
|
363
|
+
except (Exception, BaseException) as e:
|
|
364
|
+
total_f = [np.nan] * 2
|
|
365
|
+
total_age = [np.nan] * 4
|
|
366
|
+
|
|
367
|
+
sample.Info.results.age_spectra['TGA'].update(
|
|
368
|
+
{'Ar39': 100, 'F': total_f[0], 'sF': total_f[1], 'age': total_age[0],
|
|
369
|
+
's1': total_age[1], 's2': total_age[2], 's3': total_age[3], 'Num': len(sample.DegasValues[24])}
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
figure.data = calc.arr.transpose(
|
|
373
|
+
calc.spectra.get_data(*sample.ApparentAgeValues[2:4], sample.ApparentAgeValues[7])
|
|
374
|
+
)
|
|
356
375
|
|
|
357
376
|
|
|
358
|
-
# =======================
|
|
359
|
-
# Age spectra results
|
|
360
|
-
# =======================
|
|
361
377
|
def recalc_plateaus(sample: Sample, **kwargs):
|
|
362
378
|
if sample.Info.sample.type == "Unknown":
|
|
363
379
|
return recalc_age_plateaus(sample, **kwargs)
|
|
@@ -379,6 +395,19 @@ def recalc_age_plateaus(sample: Sample, **kwargs):
|
|
|
379
395
|
-------
|
|
380
396
|
None
|
|
381
397
|
"""
|
|
398
|
+
|
|
399
|
+
try:
|
|
400
|
+
params_to_check = {
|
|
401
|
+
'39ArK': {'data': sample.DegasValues[20:22], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
|
|
402
|
+
'40Arr': {'data': sample.DegasValues[24:26], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
|
|
403
|
+
'J Factor': {'data': sample.TotalParam[136], 'dtype': float, 'func': lambda x: np.isfinite(x) and x > 0, 'class': 'k1', },
|
|
404
|
+
'J Factor': {'data': sample.TotalParam[137], 'dtype': float, 'func': lambda x: np.isfinite(x), 'class': 'k1', },
|
|
405
|
+
}
|
|
406
|
+
except (IndexError, AttributeError) as e:
|
|
407
|
+
raise
|
|
408
|
+
if not basic.validate_params(fatal=False, **params_to_check):
|
|
409
|
+
return
|
|
410
|
+
|
|
382
411
|
ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.TotalParam[136:138])
|
|
383
412
|
ar40r, sar40r = sample.DegasValues[24:26]
|
|
384
413
|
ar40rar39k = calc.arr.div([ar40r, sar40r], [ar39k, sar39k])
|
|
@@ -561,6 +590,30 @@ def recalc_mdf_plateaus(sample: Sample, **kwargs):
|
|
|
561
590
|
sample.AgeSpectraPlot.text2.text = ""
|
|
562
591
|
|
|
563
592
|
|
|
593
|
+
def recalc_j_plateaus(sample: Sample, **kwargs):
|
|
594
|
+
|
|
595
|
+
ar40rar39k = sample.ApparentAgeValues[0:2]
|
|
596
|
+
j = sample.ApparentAgeValues[2:4]
|
|
597
|
+
|
|
598
|
+
try:
|
|
599
|
+
set1_res, _, set1_data = get_plateau_results(sample, sample.SelectedSequence1, ar40rar39k=ar40rar39k)
|
|
600
|
+
except ValueError:
|
|
601
|
+
pass
|
|
602
|
+
else:
|
|
603
|
+
sample.Info.results.age_plateau.update({0: set1_res})
|
|
604
|
+
sample.AgeSpectraPlot.set1.data = calc.arr.transpose(set1_data)
|
|
605
|
+
sample.AgeSpectraPlot.text1.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
606
|
+
|
|
607
|
+
try:
|
|
608
|
+
set2_res, _, set2_data = get_plateau_results(sample, sample.SelectedSequence2, ar40rar39k=ar40rar39k)
|
|
609
|
+
except ValueError:
|
|
610
|
+
pass
|
|
611
|
+
else:
|
|
612
|
+
sample.Info.results.age_plateau.update({1: set2_res})
|
|
613
|
+
sample.AgeSpectraPlot.set2.data = calc.arr.transpose(set2_data)
|
|
614
|
+
sample.AgeSpectraPlot.text2.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
615
|
+
|
|
616
|
+
|
|
564
617
|
def calc_ar40ar39(r, sr, smp):
|
|
565
618
|
"""
|
|
566
619
|
Calculate Ar40r / Ar39K based on passed initial ratio.
|
|
@@ -693,33 +746,7 @@ def get_wma_results(sample: Sample, sequence: list, ar40rar39k: list = None, ar3
|
|
|
693
746
|
return spectra_res
|
|
694
747
|
|
|
695
748
|
|
|
696
|
-
def recalc_j_plateaus(sample: Sample, **kwargs):
|
|
697
|
-
|
|
698
|
-
ar40rar39k = sample.ApparentAgeValues[0:2]
|
|
699
|
-
j = sample.ApparentAgeValues[2:4]
|
|
700
|
-
|
|
701
|
-
try:
|
|
702
|
-
set1_res, _, set1_data = get_plateau_results(sample, sample.SelectedSequence1, ar40rar39k=ar40rar39k)
|
|
703
|
-
except ValueError:
|
|
704
|
-
pass
|
|
705
|
-
else:
|
|
706
|
-
sample.Info.results.age_plateau.update({0: set1_res})
|
|
707
|
-
sample.AgeSpectraPlot.set1.data = calc.arr.transpose(set1_data)
|
|
708
|
-
sample.AgeSpectraPlot.text1.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
709
|
-
|
|
710
|
-
try:
|
|
711
|
-
set2_res, _, set2_data = get_plateau_results(sample, sample.SelectedSequence2, ar40rar39k=ar40rar39k)
|
|
712
|
-
except ValueError:
|
|
713
|
-
pass
|
|
714
|
-
else:
|
|
715
|
-
sample.Info.results.age_plateau.update({1: set2_res})
|
|
716
|
-
sample.AgeSpectraPlot.set2.data = calc.arr.transpose(set2_data)
|
|
717
|
-
sample.AgeSpectraPlot.text2.text = "" # 注意和js的配合,js那边根据text是否为空判断是否重新生成文字
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
# =======================
|
|
721
749
|
# Age Distribution Plot
|
|
722
|
-
# =======================
|
|
723
750
|
def recalc_agedistribution(smp: Sample, **kwargs):
|
|
724
751
|
try:
|
|
725
752
|
ages = smp.ApparentAgeValues[2]
|
|
@@ -769,14 +796,32 @@ def recalc_agedistribution(smp: Sample, **kwargs):
|
|
|
769
796
|
plot.set2.data = [[], []]
|
|
770
797
|
|
|
771
798
|
|
|
772
|
-
# =======================
|
|
773
799
|
# Age Distribution Plot
|
|
774
|
-
# =======================
|
|
775
800
|
def recalc_degassing_plot(smp: Sample, **kwargs):
|
|
801
|
+
figure = smp.DegasPatternPlot
|
|
802
|
+
|
|
803
|
+
try:
|
|
804
|
+
params_to_check = {
|
|
805
|
+
'degas pattern': [
|
|
806
|
+
{'data': smp.DegasValues[0], 'dtype': float, 'class': 'k8', },
|
|
807
|
+
{'data': smp.DegasValues[8], 'dtype': float, 'class': 'k8', },
|
|
808
|
+
{'data': smp.DegasValues[10], 'dtype': float, 'class': 'k8', },
|
|
809
|
+
{'data': smp.DegasValues[20], 'dtype': float, 'class': 'k8', },
|
|
810
|
+
{'data': smp.DegasValues[24], 'dtype': float, 'class': 'k8', },
|
|
811
|
+
{'data': smp.CorrectedValues[0:10:2], 'dtype': float, 'class': 'k8', },
|
|
812
|
+
],
|
|
813
|
+
}
|
|
814
|
+
except (IndexError, AttributeError) as e:
|
|
815
|
+
context = {'names': [figure.name], 'classnames': [f'k8'], 'messages': [f"{figure.name}: {str(e)}"]}
|
|
816
|
+
raise basic.ParamsInvalid(400, f"{figure.name}: {str(e)}", context=context, fatal=False)
|
|
817
|
+
|
|
818
|
+
if not basic.validate_params(fatal=False, **params_to_check):
|
|
819
|
+
return
|
|
820
|
+
|
|
776
821
|
if not hasattr(smp, 'DegasPatternPlot'):
|
|
777
822
|
setattr(smp, 'DegasPatternPlot', Plot(id='figure_8', name='Degas Pattern Plot'))
|
|
778
823
|
isotope_percentage = lambda l: [e / sum(l) * 100 if sum(l) != 0 else 0 for e in l]
|
|
779
|
-
|
|
824
|
+
figure.data = [
|
|
780
825
|
isotope_percentage(smp.DegasValues[0]), # Ar36a
|
|
781
826
|
isotope_percentage(smp.DegasValues[8]), # Ar37Ca
|
|
782
827
|
isotope_percentage(smp.DegasValues[10]), # Ar38Cl
|
|
@@ -788,4 +833,4 @@ def recalc_degassing_plot(smp: Sample, **kwargs):
|
|
|
788
833
|
isotope_percentage(smp.CorrectedValues[6]), # Ar39
|
|
789
834
|
isotope_percentage(smp.CorrectedValues[8]), # Ar40
|
|
790
835
|
]
|
|
791
|
-
|
|
836
|
+
figure.info = [True] * 10
|
|
@@ -855,7 +855,8 @@ class Sample:
|
|
|
855
855
|
# self.__version = '20250328' # Experiment info
|
|
856
856
|
# self.__version = '20250404' # J normalization factor
|
|
857
857
|
# self.__version = '20251001' # add marker col for all tables
|
|
858
|
-
self.__version = '20251231' # move montecarlo to params-112
|
|
858
|
+
# self.__version = '20251231' # move montecarlo to params-112
|
|
859
|
+
self.__version = '20260101' #
|
|
859
860
|
|
|
860
861
|
self.Doi = ""
|
|
861
862
|
self.RawData = RawData()
|
|
@@ -60,8 +60,6 @@ def set_plot_style(smp: Sample):
|
|
|
60
60
|
initial.initial_plot_styles(smp, except_attrs=['data'])
|
|
61
61
|
# Auto scale
|
|
62
62
|
reset_plot_scale(smp)
|
|
63
|
-
# Reset isochron data
|
|
64
|
-
plots.reset_isochron_line_data(smp)
|
|
65
63
|
# Auto position and contents of texts
|
|
66
64
|
reset_text(smp)
|
|
67
65
|
# Set title, which are deleted in initializing
|
|
@@ -69,8 +67,16 @@ def set_plot_style(smp: Sample):
|
|
|
69
67
|
smp_name = smp.Info.sample.name
|
|
70
68
|
name = f"{exp_name} {smp_name}" if str(exp_name).lower().strip() != str(smp_name).lower().strip() else exp_name
|
|
71
69
|
suffix = f"{name} {smp.Info.sample.material}"
|
|
70
|
+
|
|
72
71
|
for figure_id, figure in basic.get_components(smp).items():
|
|
72
|
+
if not isinstance(figure, Plot):
|
|
73
|
+
continue
|
|
74
|
+
|
|
73
75
|
if isinstance(figure, Plot):
|
|
76
|
+
# Reset isochron line
|
|
77
|
+
if figure_id in ['figure_2', 'figure_3', 'figure_4', 'figure_5', 'figure_6', ]:
|
|
78
|
+
plots.set_iso_line_data(smp, figure)
|
|
79
|
+
# name and title
|
|
74
80
|
if not hasattr(figure, 'title'):
|
|
75
81
|
setattr(figure, 'title', Plot.Text())
|
|
76
82
|
setattr(getattr(figure, 'title'), 'text', f"{suffix} {getattr(figure, 'name', '')}")
|
|
@@ -111,8 +117,8 @@ def reset_plot_scale(smp: Sample, only_figure: str = None):
|
|
|
111
117
|
if k == 'figure_1':
|
|
112
118
|
try:
|
|
113
119
|
k0 = calc.arr.transpose(v.data)
|
|
114
|
-
k1 = calc.arr.transpose(v.set1.data) if len(v.set1.data) != 0 else [[]
|
|
115
|
-
k2 = calc.arr.transpose(v.set2.data) if len(v.set2.data) != 0 else [[]
|
|
120
|
+
k1 = calc.arr.transpose(v.set1.data) if len(v.set1.data) != 0 else [[] for i in range(3)]
|
|
121
|
+
k2 = calc.arr.transpose(v.set2.data) if len(v.set2.data) != 0 else [[] for i in range(3)]
|
|
116
122
|
data = np.concatenate([k0, k1, k2], axis=1)
|
|
117
123
|
ylist = np.concatenate([data[1], data[2]])
|
|
118
124
|
yscale = calc.plot.get_axis_scale(ylist, min_interval=5, extra_count=1)
|
|
@@ -60,7 +60,10 @@ def update_table_data(smp: Sample, only_table: str = None):
|
|
|
60
60
|
elif key == '8':
|
|
61
61
|
data = [smp.SequenceName, smp.SequenceValue, smp.IsochronMark, *smp.TotalParam]
|
|
62
62
|
else:
|
|
63
|
-
|
|
63
|
+
raise KeyError(f"Invalid table id")
|
|
64
|
+
|
|
65
|
+
data = _normalize_data(
|
|
66
|
+
data, len(comp.header), smp.Info.experiment.step_num, text_col_indexes=comp.text_indexes)
|
|
64
67
|
|
|
65
68
|
try:
|
|
66
69
|
params_to_check = {
|
|
@@ -94,61 +97,46 @@ def update_handsontable(smp: Sample, data: list, id: str):
|
|
|
94
97
|
|
|
95
98
|
"""
|
|
96
99
|
|
|
97
|
-
def _normalize_data(a, cols, start_col=0):
|
|
98
|
-
if len(a) >= cols:
|
|
99
|
-
return a[start_col:cols]
|
|
100
|
-
else:
|
|
101
|
-
return a[start_col:] + [[''] * len(a[0])] * (cols - len(a))
|
|
102
|
-
|
|
103
|
-
def _strToBool(cols):
|
|
104
|
-
bools_dict = {
|
|
105
|
-
'true': True, 'false': False, 'True': True, 'False': False, '1': True, '0': False, 'none': False,
|
|
106
|
-
}
|
|
107
|
-
return [bools_dict.get(str(col).lower(), False) for col in cols]
|
|
108
|
-
|
|
109
|
-
def _digitize_data(a):
|
|
110
|
-
# pattern = r'^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$'
|
|
111
|
-
# return [[ast.literal_eval(str(cell)) if re.fullmatch(pattern, str(cell)) else np.nan if str(cell) == "" else cell for cell in row] for row in a]
|
|
112
|
-
return a
|
|
113
100
|
|
|
114
101
|
try:
|
|
115
|
-
|
|
102
|
+
col3 = _normalize_data(data[0:3], cols=3, rows=len(data[0]), text_col_indexes=[0, 1, 2])
|
|
116
103
|
except IndexError:
|
|
117
|
-
|
|
104
|
+
raise
|
|
118
105
|
|
|
119
106
|
update_all_table = False
|
|
120
107
|
try:
|
|
121
|
-
if
|
|
108
|
+
if col3[0] != smp.SequenceName or col3[1] != smp.SequenceValue or col3[2] != smp.IsochronMark:
|
|
122
109
|
update_all_table = True
|
|
123
|
-
smp.
|
|
124
|
-
smp.
|
|
110
|
+
smp.SequenceName = col3[0]
|
|
111
|
+
smp.SequenceValue = col3[1]
|
|
112
|
+
smp.IsochronMark = col3[2]
|
|
125
113
|
except IndexError:
|
|
126
114
|
print(f"Check sequence value / isochron mark failed")
|
|
127
|
-
|
|
128
|
-
|
|
115
|
+
raise
|
|
116
|
+
n = len(data[0])
|
|
129
117
|
if id == '1': # 样品值
|
|
130
|
-
data = _normalize_data(data, len(samples.SAMPLE_INTERCEPT_HEADERS), 3)
|
|
118
|
+
data = _normalize_data(data, len(samples.SAMPLE_INTERCEPT_HEADERS), n, 3)
|
|
131
119
|
smp.SampleIntercept = _digitize_data(data)
|
|
132
120
|
elif id == '2': # 本底值
|
|
133
|
-
data = _normalize_data(data, len(samples.BLANK_INTERCEPT_HEADERS), 3)
|
|
121
|
+
data = _normalize_data(data, len(samples.BLANK_INTERCEPT_HEADERS), n, 3)
|
|
134
122
|
smp.BlankIntercept = _digitize_data(data)
|
|
135
123
|
elif id == '3': # 校正值
|
|
136
|
-
data = _normalize_data(data, len(samples.CORRECTED_HEADERS), 3)
|
|
124
|
+
data = _normalize_data(data, len(samples.CORRECTED_HEADERS), n, 3)
|
|
137
125
|
smp.CorrectedValues = _digitize_data(data)
|
|
138
126
|
elif id == '4': # Degas table
|
|
139
|
-
data = _normalize_data(data, len(samples.DEGAS_HEADERS), 3)
|
|
127
|
+
data = _normalize_data(data, len(samples.DEGAS_HEADERS), n, 3)
|
|
140
128
|
smp.DegasValues = _digitize_data(data)
|
|
141
129
|
elif id == '5': # 发行表
|
|
142
|
-
data = _normalize_data(data, len(samples.PUBLISH_TABLE_HEADERS), 3)
|
|
130
|
+
data = _normalize_data(data, len(samples.PUBLISH_TABLE_HEADERS), n, 3)
|
|
143
131
|
smp.PublishValues = _digitize_data(data)
|
|
144
132
|
elif id == '6': # 年龄谱
|
|
145
|
-
data = _normalize_data(data, len(samples.SPECTRUM_TABLE_HEADERS), 3)
|
|
133
|
+
data = _normalize_data(data, len(samples.SPECTRUM_TABLE_HEADERS), n, 3)
|
|
146
134
|
smp.ApparentAgeValues = _digitize_data(data)
|
|
147
135
|
elif id == '7': # 等时线
|
|
148
|
-
data = _normalize_data(data, len(samples.ISOCHRON_TABLE_HEADERS), 3)
|
|
136
|
+
data = _normalize_data(data, len(samples.ISOCHRON_TABLE_HEADERS), n, 3)
|
|
149
137
|
smp.IsochronValues = _digitize_data(data)
|
|
150
138
|
elif id == '8': # 总参数
|
|
151
|
-
data = _normalize_data(data, len(samples.TOTAL_PARAMS_HEADERS), 3)
|
|
139
|
+
data = _normalize_data(data, len(samples.TOTAL_PARAMS_HEADERS), n, 3)
|
|
152
140
|
data = _digitize_data(data)
|
|
153
141
|
data[101: 112] = [_strToBool(i) for i in data[101: 112]]
|
|
154
142
|
smp.TotalParam = data
|
|
@@ -198,4 +186,50 @@ def update_data_from_table(smp: Sample, only_table: str = None):
|
|
|
198
186
|
pass
|
|
199
187
|
|
|
200
188
|
|
|
189
|
+
def _normalize_data(a, cols, rows, start_col=0, start_row=0, text_col_indexes=[]):
|
|
190
|
+
if isinstance(a, np.ndarray):
|
|
191
|
+
a = a.tolist()
|
|
192
|
+
if not isinstance(a, list):
|
|
193
|
+
raise ValueError(f"List required, but {type(a)} given.")
|
|
194
|
+
if len(a) >= cols:
|
|
195
|
+
a = a[start_col:cols]
|
|
196
|
+
else:
|
|
197
|
+
a = a[start_col:] + [[] for j in range(cols - len(a))]
|
|
198
|
+
|
|
199
|
+
def f(_, _i):
|
|
200
|
+
if _i in text_col_indexes:
|
|
201
|
+
if isinstance(_, type(None)):
|
|
202
|
+
return ""
|
|
203
|
+
if isinstance(_, float) and np.isnan(_):
|
|
204
|
+
return ""
|
|
205
|
+
return str(_)
|
|
206
|
+
else:
|
|
207
|
+
if _ in ["", None, np.nan]:
|
|
208
|
+
return np.nan
|
|
209
|
+
elif isinstance(_, str):
|
|
210
|
+
if _.lower() == 'true':
|
|
211
|
+
return 1
|
|
212
|
+
elif _.lower() == 'false':
|
|
213
|
+
return 0
|
|
214
|
+
return float(_)
|
|
215
|
+
|
|
216
|
+
for i in range(cols - start_col):
|
|
217
|
+
if len(a[i]) >= rows:
|
|
218
|
+
a[i] = [f(each, i + start_col) for each in a[i][start_row:rows]]
|
|
219
|
+
else:
|
|
220
|
+
a[i] = [f(each, i + start_col) for each in a[i][start_row:]] + [f("", i + start_col) for j in range(rows - len(a[i]))]
|
|
221
|
+
|
|
222
|
+
return a
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _digitize_data(a):
|
|
226
|
+
# pattern = r'^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$'
|
|
227
|
+
# return [[ast.literal_eval(str(cell)) if re.fullmatch(pattern, str(cell)) else np.nan if str(cell) == "" else cell for cell in row] for row in a]
|
|
228
|
+
return a
|
|
229
|
+
|
|
201
230
|
|
|
231
|
+
def _strToBool(cols):
|
|
232
|
+
bools_dict = {
|
|
233
|
+
'true': True, 'false': False, 'True': True, 'False': False, '1': True, '0': False, 'none': False,
|
|
234
|
+
}
|
|
235
|
+
return [bools_dict.get(str(col).lower(), False) for col in cols]
|
|
@@ -16,7 +16,7 @@ long_description = (here / 'README.md').read_text(encoding='utf-8')
|
|
|
16
16
|
|
|
17
17
|
setuptools.setup(
|
|
18
18
|
name='ararpy', #
|
|
19
|
-
version='0.2.
|
|
19
|
+
version='0.2.4', # version
|
|
20
20
|
author='Yang Wu',
|
|
21
21
|
author_email='wuycug@hotmail.com',
|
|
22
22
|
description='A project for Ar-Ar geochronology', # short description
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|