ararpy 0.1.19__py3-none-any.whl → 0.1.21__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 +4 -2
- ararpy/calc/age.py +35 -36
- ararpy/calc/arr.py +16 -6
- ararpy/calc/corr.py +9 -7
- ararpy/calc/jvalue.py +1 -1
- ararpy/calc/plot.py +5 -2
- ararpy/files/calc_file.py +2 -5
- ararpy/files/raw_file.py +3 -4
- ararpy/files/xls.py +1 -2
- ararpy/smp/basic.py +121 -71
- ararpy/smp/corr.py +69 -51
- ararpy/smp/export.py +82 -49
- ararpy/smp/initial.py +47 -17
- ararpy/smp/plots.py +126 -87
- ararpy/smp/sample.py +57 -19
- ararpy/smp/style.py +23 -16
- {ararpy-0.1.19.dist-info → ararpy-0.1.21.dist-info}/METADATA +1 -1
- {ararpy-0.1.19.dist-info → ararpy-0.1.21.dist-info}/RECORD +21 -21
- {ararpy-0.1.19.dist-info → ararpy-0.1.21.dist-info}/WHEEL +1 -1
- {ararpy-0.1.19.dist-info → ararpy-0.1.21.dist-info}/licenses/LICENSE +0 -0
- {ararpy-0.1.19.dist-info → ararpy-0.1.21.dist-info}/top_level.txt +0 -0
ararpy/__init__.py
CHANGED
|
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
|
|
|
16
16
|
""" Information """
|
|
17
17
|
|
|
18
18
|
name = 'ararpy'
|
|
19
|
-
version = '0.
|
|
19
|
+
version = '0.1.21'
|
|
20
20
|
__version__ = version
|
|
21
21
|
full_version = version
|
|
22
|
-
last_update = '2024-
|
|
22
|
+
last_update = '2024-03-28'
|
|
23
23
|
|
|
24
24
|
""" ArArPy Functions """
|
|
25
25
|
|
|
@@ -116,6 +116,8 @@ Sample.plot_cl_3 = lambda _smp: smp.calculation.recalculate(
|
|
|
116
116
|
Sample.plot_3D = lambda _smp: smp.calculation.recalculate(
|
|
117
117
|
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_7'])
|
|
118
118
|
|
|
119
|
+
Sample.to_excel = lambda _smp, file_path, *args, **kwargs: smp.export.to_excel(_smp, file_path=file_path, *args, **kwargs)
|
|
120
|
+
|
|
119
121
|
Sample.show_data = lambda _smp: \
|
|
120
122
|
f"Sample Name: \n\t{_smp.name()}\n" \
|
|
121
123
|
f"Doi: \n\t{_smp.doi()}\n" \
|
ararpy/calc/age.py
CHANGED
|
@@ -41,11 +41,13 @@ def calc_age_min(F, sF, **kwargs) -> tuple:
|
|
|
41
41
|
J = arr.array_as_float(kwargs.pop('J'))
|
|
42
42
|
sJ = arr.array_as_float(kwargs.pop('sJ') * J / 100)
|
|
43
43
|
A = arr.array_as_float(kwargs.pop('A'))
|
|
44
|
-
sA = arr.array_as_float(kwargs.pop('sA') * A / 100)
|
|
44
|
+
sA = arr.array_as_float(kwargs.pop('sA') * A / 100) # total A, A = Aec + (Ab+) + (Ab-). Ab- for Ca
|
|
45
45
|
Ae = arr.array_as_float(kwargs.pop('Ae'))
|
|
46
|
-
sAe = arr.array_as_float(kwargs.pop('sAe') * Ae / 100)
|
|
46
|
+
sAe = arr.array_as_float(kwargs.pop('sAe') * Ae / 100) # Aec
|
|
47
47
|
Ab = arr.array_as_float(kwargs.pop('Ab'))
|
|
48
|
-
sAb = arr.array_as_float(kwargs.pop('sAb') * Ab / 100)
|
|
48
|
+
sAb = arr.array_as_float(kwargs.pop('sAb') * Ab / 100) # Ab-
|
|
49
|
+
Abp = arr.array_as_float(kwargs.pop('Abp'))
|
|
50
|
+
sAbp = arr.array_as_float(kwargs.pop('sAbp') * Ab / 100) # Ab+
|
|
49
51
|
W = arr.array_as_float(kwargs.pop('W'))
|
|
50
52
|
sW = arr.array_as_float(kwargs.pop('sW') * W / 100)
|
|
51
53
|
Y = arr.array_as_float(kwargs.pop('Y'))
|
|
@@ -61,21 +63,22 @@ def calc_age_min(F, sF, **kwargs) -> tuple:
|
|
|
61
63
|
Lb = arr.array_as_float(kwargs.pop('Lb'))
|
|
62
64
|
sLb = arr.array_as_float(kwargs.pop('sLb') * Lb / 100)
|
|
63
65
|
t = arr.array_as_float(kwargs.pop('t'))
|
|
64
|
-
st = arr.array_as_float(kwargs.pop('st')
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
st = arr.array_as_float(kwargs.pop('st'))
|
|
67
|
+
Ap = arr.array_as_float(kwargs.pop('Ap'))
|
|
68
|
+
sAp = arr.array_as_float(kwargs.pop('sAp') * Ap / 100)
|
|
69
|
+
Kp = arr.array_as_float(kwargs.pop('Kp'))
|
|
70
|
+
sKp = arr.array_as_float(kwargs.pop('sKp') * Kp / 100)
|
|
69
71
|
|
|
70
|
-
#
|
|
72
|
+
# calculating using Min et al.(2000) equation
|
|
71
73
|
# lmd = A * W * Y / (f * No)
|
|
72
74
|
V = f * No / ((Ab + Ae) * W * Y)
|
|
73
75
|
sV = pow((V / f * sf) ** 2 + (V / No * sNo) ** 2 + (V / (Ab + Ae)) ** 2 * (sAb ** 2 + sAe ** 2) +
|
|
74
76
|
(V / W * sW) ** 2 + (V / Y * sY) ** 2, 0.5)
|
|
77
|
+
|
|
75
78
|
# standard age in year, change to Ma
|
|
76
79
|
t = t * 1000000
|
|
77
80
|
st = st * 1000000
|
|
78
|
-
# back-calculating Ar40/Ar39
|
|
81
|
+
# back-calculating Ar40/Ar39 of the standard
|
|
79
82
|
stdR = (np.exp(t * L) - 1) / J
|
|
80
83
|
# errors of standard age and decay constants were not applied
|
|
81
84
|
sStdR = pow((stdR / J) ** 2 * sJ ** 2, 0.5)
|
|
@@ -84,31 +87,27 @@ def calc_age_min(F, sF, **kwargs) -> tuple:
|
|
|
84
87
|
sR_1 = np.sqrt((sF / stdR) ** 2 + (F * sStdR / stdR ** 2) ** 2) # errors of measured 40Ar/39Ar and J value
|
|
85
88
|
sR_2 = np.sqrt((sF / stdR) ** 2) # error of measured 40Ar/39Ar only
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
useStandardAge = True
|
|
91
|
+
if useStandardAge:
|
|
92
|
+
# ln part in Min 2000 equation
|
|
93
|
+
BB = 1
|
|
94
|
+
KK = np.exp(t / V) - 1 # 40Arr / 40K Use standard age
|
|
95
|
+
else: # use Ar40* and K concentrations of primary standard
|
|
96
|
+
# not fanished, this function is wrong
|
|
97
|
+
BB = (Ab + Ae) / Ae
|
|
98
|
+
KK = Ap / Kp / f
|
|
99
|
+
raise TypeError(f"Not use standard age. Not supported.")
|
|
100
|
+
|
|
89
101
|
XX = BB * KK * R + 1
|
|
90
102
|
k0 = V * np.log(XX)
|
|
91
|
-
|
|
92
|
-
e2 = (np.log(XX) * V / No) ** 2 * sNo ** 2 # sNo
|
|
93
|
-
e3 = (-1 * np.log(XX) * V / A + BB * KK * R / (A * XX)) ** 2 * sAb ** 2 # sAb
|
|
94
|
-
e4 = (-1 * np.log(XX) * V / A - Ab * KK * R / (Ae ** 2 * XX)) ** 2 * sAe ** 2 # sAe
|
|
95
|
-
e5 = (-1 * np.log(XX) * V / W - V * BB * KK * R / (W * XX)) ** 2 * sW ** 2 # sW
|
|
96
|
-
e6 = (np.log(XX) * V / Y) ** 2 * sY ** 2 # sY
|
|
97
|
-
e7 = (V * BB * KK / XX) ** 2 * sR_1 ** 2 # sR
|
|
98
|
-
# e8 = (V * BB * KK * R / (Ap * XX)) ** 2 * sAp ** 2 # sAp
|
|
99
|
-
# e9 = (V * BB * KK * R / (Kp * XX)) ** 2 * sKp ** 2 # sKp
|
|
100
|
-
e8, e9 = 0, 0
|
|
101
|
-
# useDecayConst = False
|
|
102
|
-
# if useDecayConst: # k0 = log(L / Le * KK * R + 1) / L
|
|
103
|
-
# e1 = (V * BB * KK * R / (f * XX)) ** 2 * sf ** 2
|
|
104
|
-
# e2 = 0
|
|
105
|
-
# e3 = (-1 * np.log(XX) * V / L + BB * KK * R / (L * XX)) ** 2 * sLb ** 2
|
|
106
|
-
# e4 = (-1 * np.log(XX) * V / L - Lb * KK * R / (Le ** 2 * XX)) ** 2 * sLe ** 2
|
|
107
|
-
# e5 = (V * BB * KK * R / (W * XX)) ** 2 * sW ** 2
|
|
108
|
-
# e6 = 0
|
|
109
|
-
useStandardAge = True
|
|
103
|
+
|
|
110
104
|
if useStandardAge:
|
|
111
|
-
|
|
105
|
+
# k0 = V * ln(exp(t/V) - 1 * R + 1)
|
|
106
|
+
e1 = (np.log(XX) - R * (KK + 1) * t / (V * XX)) ** 2 * sV ** 2 # sV
|
|
107
|
+
e2 = (BB * (KK + 1) * R / XX) ** 2 * st ** 2 # st
|
|
108
|
+
e3 = (V * BB * KK / XX) ** 2 * sR_1 ** 2 # sR
|
|
109
|
+
else:
|
|
110
|
+
e1, e2, e3 = 0, 0, 0
|
|
112
111
|
|
|
113
112
|
# change to Ma
|
|
114
113
|
# analytical error, error of 40Ar/39Ar only
|
|
@@ -116,7 +115,7 @@ def calc_age_min(F, sF, **kwargs) -> tuple:
|
|
|
116
115
|
# internal error, errors of 40Ar/39Ar and J value
|
|
117
116
|
s2 = np.sqrt((V * KK * BB / XX) ** 2 * sR_1 ** 2)
|
|
118
117
|
# total external error
|
|
119
|
-
s3 = np.sqrt(e1 + e2 + e3
|
|
118
|
+
s3 = np.sqrt(e1 + e2 + e3)
|
|
120
119
|
age = k0
|
|
121
120
|
return age, s1, s2, s3
|
|
122
121
|
|
|
@@ -145,7 +144,7 @@ def calc_age_general(F, sF, J, sJ, L, sL, **kwargs):
|
|
|
145
144
|
v1 = sF ** 2 * (J / (L * (1 + J * F))) ** 2
|
|
146
145
|
v2 = sJ ** 2 * (F / (L * (1 + J * F))) ** 2
|
|
147
146
|
v3 = sL ** 2 * (np.log(1 + J * F) / (L ** 2)) ** 2
|
|
148
|
-
s1 = v1 ** .5 # analytical error
|
|
149
|
-
s2 = (v1 + v2) ** .5 # internal error
|
|
150
|
-
s3 = (v1 + v2 + v3) ** .5 # full external error
|
|
147
|
+
s1 = v1 ** .5 # analytical error, F only
|
|
148
|
+
s2 = (v1 + v2) ** .5 # internal error, F and J
|
|
149
|
+
s3 = (v1 + v2 + v3) ** .5 # full external error. F, J and L
|
|
151
150
|
return age, s1, s2, s3
|
ararpy/calc/arr.py
CHANGED
|
@@ -38,7 +38,7 @@ def mul(*args):
|
|
|
38
38
|
|
|
39
39
|
Returns
|
|
40
40
|
-------
|
|
41
|
-
|
|
41
|
+
two-D list, [values, errors]
|
|
42
42
|
"""
|
|
43
43
|
v = np.array(args)
|
|
44
44
|
res = np.zeros([2, v.shape[-1]], dtype=np.float64)
|
|
@@ -67,10 +67,11 @@ def div(a, b):
|
|
|
67
67
|
n = np.shape([a, b])[-1]
|
|
68
68
|
k0, k1 = [], []
|
|
69
69
|
for i in range(n):
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
(np.divide(a[1][i] ** 2, b[0][i] ** 2) +
|
|
73
|
-
|
|
70
|
+
try:
|
|
71
|
+
k0.append(np.divide(a[0][i], b[0][i]))
|
|
72
|
+
k1.append((np.divide(a[1][i] ** 2, b[0][i] ** 2) + np.divide(a[0][i] ** 2 * b[1][i] ** 2, b[0][i] ** 4)) ** .5)
|
|
73
|
+
except TypeError as e:
|
|
74
|
+
raise TypeError(f"a = {a[0][i]}, b = {b[0][i]}, {e}")
|
|
74
75
|
return [k0, k1]
|
|
75
76
|
|
|
76
77
|
|
|
@@ -514,6 +515,15 @@ def transpose(obj, ignore: bool = True):
|
|
|
514
515
|
raise ValueError
|
|
515
516
|
|
|
516
517
|
|
|
518
|
+
def remove_empty(a: list):
|
|
519
|
+
index = 0
|
|
520
|
+
for i in range(len(a)):
|
|
521
|
+
if not is_empty(a[-(i + 1)]):
|
|
522
|
+
index = len(a) - i
|
|
523
|
+
break
|
|
524
|
+
return transpose(a[:index])
|
|
525
|
+
|
|
526
|
+
|
|
517
527
|
def get_item(obj: list, loc: (list, tuple, int), default: Union[str, int, float, bool] = None,
|
|
518
528
|
base: Union[int, tuple, list] = 0) -> Union[str, int, float, bool]:
|
|
519
529
|
""" Get item from a n-dimension list
|
|
@@ -566,7 +576,7 @@ def wtd_mean(a: list, e: list, sf: int = 1, adjust_error: bool = True):
|
|
|
566
576
|
k0 = sum(a * wt) / sum(wt) # error weighting
|
|
567
577
|
k4 = sum((a - k0) ** 2 * wt) # Chi square
|
|
568
578
|
k3 = k4 / df # MSWD mentioned in Min et al., 2000
|
|
569
|
-
if adjust_error:
|
|
579
|
+
if adjust_error and k3 > 1:
|
|
570
580
|
k1 = (k3 / sum(wt)) ** .5
|
|
571
581
|
else:
|
|
572
582
|
k1 = (1 / sum(wt)) ** .5
|
ararpy/calc/corr.py
CHANGED
|
@@ -72,18 +72,18 @@ def mdf(rm: float, srm: float, m1: float, m2: float, ra: float = 298.56,
|
|
|
72
72
|
v3 = err.div((np.log(ra / rm), v1), (np.log(ratio_m), v2))
|
|
73
73
|
k4 = err.div((np.log(ra / rm) / np.log(ratio_m), v3), (m1, sm1))
|
|
74
74
|
except Exception:
|
|
75
|
-
k3, k4 =
|
|
75
|
+
k3, k4 = 0, 0
|
|
76
76
|
# pow
|
|
77
77
|
try:
|
|
78
78
|
k5 = pow((ra / rm), (1 / delta_m)) # Renne2009, B.D. Turrin2010
|
|
79
79
|
k6 = err.pow((ra / rm, err.div((ra, sra), (rm, srm))),
|
|
80
80
|
(1 / delta_m, err.div((1, 0), (delta_m, sdelta_m))))
|
|
81
81
|
except Exception:
|
|
82
|
-
k5, k6 =
|
|
83
|
-
return k1, k2, k3, k4, k5, k6
|
|
82
|
+
k5, k6 = 0, 0
|
|
83
|
+
return k1, k2, k2, k2, k3, k4, k4, k4, k5, k6, k6, k6
|
|
84
84
|
else:
|
|
85
85
|
mdf_line_2 = (rm / ra - 1) / delta_m # Ryu et al., 2013
|
|
86
|
-
return mdf_line_2, 0, 0, 0, 0, 0
|
|
86
|
+
return mdf_line_2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def discr(a0: list, e0: list, mdf: list, smdf: list, m: list, m40: list,
|
|
@@ -268,7 +268,7 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
|
|
|
268
268
|
M37: Tuple[float, float], M36: Tuple[float, float],
|
|
269
269
|
G40: Tuple[float, float], G39: Tuple[float, float], G38: Tuple[float, float],
|
|
270
270
|
G37: Tuple[float, float], G36: Tuple[float, float],
|
|
271
|
-
stand_time_year: float,
|
|
271
|
+
stand_time_year: float, JNFactor: Tuple[float, float],
|
|
272
272
|
**options):
|
|
273
273
|
"""
|
|
274
274
|
|
|
@@ -294,6 +294,7 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
|
|
|
294
294
|
L36cl
|
|
295
295
|
MDFunc
|
|
296
296
|
MDF
|
|
297
|
+
JNFactor
|
|
297
298
|
options
|
|
298
299
|
|
|
299
300
|
Returns
|
|
@@ -307,9 +308,7 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
|
|
|
307
308
|
Monte_Carlo_Size = 10000
|
|
308
309
|
|
|
309
310
|
# generate random
|
|
310
|
-
print(ar40m)
|
|
311
311
|
ar40m = random_normal_absolute(*ar40m, size=Monte_Carlo_Size)
|
|
312
|
-
print(ar40m)
|
|
313
312
|
ar39m = random_normal_absolute(*ar39m, size=Monte_Carlo_Size)
|
|
314
313
|
ar38m = random_normal_absolute(*ar38m, size=Monte_Carlo_Size)
|
|
315
314
|
ar37m = random_normal_absolute(*ar37m, size=Monte_Carlo_Size)
|
|
@@ -347,6 +346,8 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
|
|
|
347
346
|
R38v39k = random_normal_relative(*R38v39k, size=Monte_Carlo_Size)
|
|
348
347
|
R36v38clp = random_normal_relative(*R36v38clp, size=Monte_Carlo_Size)
|
|
349
348
|
|
|
349
|
+
JNFactor = random_normal_absolute(*JNFactor, size=Monte_Carlo_Size)
|
|
350
|
+
|
|
350
351
|
blank_gain_corr = options.get('blank_gain_corr', True)
|
|
351
352
|
|
|
352
353
|
def do_simulation():
|
|
@@ -376,6 +377,7 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
|
|
|
376
377
|
_ar36a = _ar36res - _ar36cl
|
|
377
378
|
_ar40r = _ar40 - _ar36a * R40v36a[i] - _ar39k * R40v39k[i]
|
|
378
379
|
_ar40ar = _ar40 - _ar39k * R40v39k[i]
|
|
380
|
+
_ar39k = _ar39k * JNFactor[i]
|
|
379
381
|
_f = _ar40r / _ar39k
|
|
380
382
|
i += 1
|
|
381
383
|
# yield _f, _ar36, _ar37, _ar38, _ar39, _ar40, _ar36a, _ar37ca, _ar39k, _ar40r, _ar36cl
|
ararpy/calc/jvalue.py
CHANGED
ararpy/calc/plot.py
CHANGED
|
@@ -39,8 +39,11 @@ def get_axis_scale(data: list, count=6, increment=None, extra_count=0, min_inter
|
|
|
39
39
|
"""
|
|
40
40
|
if len(data) == 0:
|
|
41
41
|
return 0, 1, 5, 0.2 # Default return
|
|
42
|
-
_max =
|
|
43
|
-
_min =
|
|
42
|
+
_max = np.ma.masked_invalid(data).max()
|
|
43
|
+
_min = np.ma.masked_invalid(data).min()
|
|
44
|
+
if isinstance(_max, np.ma.core.MaskedConstant) or isinstance(_min, np.ma.core.MaskedConstant):
|
|
45
|
+
return 0, 1, 5, 0.2 # Default return
|
|
46
|
+
_max = float(_max); _min = float(_min)
|
|
44
47
|
interval = (_max - _min) / count
|
|
45
48
|
if interval == 0:
|
|
46
49
|
interval = 10
|
ararpy/files/calc_file.py
CHANGED
|
@@ -49,8 +49,7 @@ def read_calc_file(file_path: str):
|
|
|
49
49
|
book_contents[each_sheet] = sheet_contents
|
|
50
50
|
os.remove(decrypt_file_path)
|
|
51
51
|
except Exception as e:
|
|
52
|
-
|
|
53
|
-
return False
|
|
52
|
+
raise
|
|
54
53
|
else:
|
|
55
54
|
return book_contents
|
|
56
55
|
|
|
@@ -420,7 +419,7 @@ def open_full_xls(file_path: str, sample_name: str = ''):
|
|
|
420
419
|
try:
|
|
421
420
|
res = xls.open_xls(file_path)
|
|
422
421
|
except (Exception, BaseException) as e:
|
|
423
|
-
|
|
422
|
+
raise
|
|
424
423
|
start_row = 5
|
|
425
424
|
rows_num = len(res['Sample Parameters']) - 5
|
|
426
425
|
|
|
@@ -583,8 +582,6 @@ class ArArCalcFile:
|
|
|
583
582
|
|
|
584
583
|
def open(self):
|
|
585
584
|
book_contents = read_calc_file(self.file_path)
|
|
586
|
-
if not book_contents:
|
|
587
|
-
raise ValueError('Fail to open the file')
|
|
588
585
|
# create data frames for book values
|
|
589
586
|
content = pd.DataFrame(book_contents['Data Tables'])
|
|
590
587
|
logs01 = pd.DataFrame(book_contents['Logs01'])
|
ararpy/files/raw_file.py
CHANGED
|
@@ -274,7 +274,7 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
|
|
|
274
274
|
raise ValueError(f"Step name not found")
|
|
275
275
|
except (TypeError, ValueError, IndexError):
|
|
276
276
|
# When parsing the step name fails, the end of the file has been reached
|
|
277
|
-
|
|
277
|
+
raise
|
|
278
278
|
|
|
279
279
|
# other information
|
|
280
280
|
options = get_sample_info(file_contents, optional_info_index, default="", base=[1, 1 - idx, 1])
|
|
@@ -345,10 +345,9 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
|
|
|
345
345
|
break
|
|
346
346
|
|
|
347
347
|
step_list.append(current_step)
|
|
348
|
-
|
|
349
|
-
idx = input_filter[32] * step_index
|
|
348
|
+
idx = input_filter[32] * len(step_list)
|
|
350
349
|
|
|
351
|
-
if not check_box_index[0] or
|
|
350
|
+
if not check_box_index[0] or len(step_list) >= 500: # check_box_index[0]: multiple sequences
|
|
352
351
|
break
|
|
353
352
|
|
|
354
353
|
return step_list
|
ararpy/files/xls.py
CHANGED
|
@@ -20,8 +20,7 @@ def open_xls(filepath: str):
|
|
|
20
20
|
sheet = wb.sheet_by_name(sheet_name)
|
|
21
21
|
res[sheet_name] = [[sheet.cell(row, col).value for col in range(sheet.ncols)] for row in range(sheet.nrows)]
|
|
22
22
|
except biffh.XLRDError as e:
|
|
23
|
-
|
|
24
|
-
return e
|
|
23
|
+
raise
|
|
25
24
|
else:
|
|
26
25
|
return res
|
|
27
26
|
|
ararpy/smp/basic.py
CHANGED
|
@@ -44,39 +44,97 @@ def calc_apparent_ages(smp: Sample):
|
|
|
44
44
|
-------
|
|
45
45
|
|
|
46
46
|
"""
|
|
47
|
-
if smp.Info.sample.type == "
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
smp.
|
|
58
|
-
|
|
47
|
+
if str(smp.Info.sample.type).lower() == "unknown":
|
|
48
|
+
v = calc_age(smp=smp)
|
|
49
|
+
elif str(smp.Info.sample.type).lower() == "standard":
|
|
50
|
+
v = calc_j(smp=smp)
|
|
51
|
+
elif str(smp.Info.sample.type).lower() == "air":
|
|
52
|
+
v = calc_mdf(smp=smp)
|
|
53
|
+
else:
|
|
54
|
+
raise TypeError(f"Sample type is not supported: {smp.Info.sample.type}")
|
|
55
|
+
try:
|
|
56
|
+
smp.ApparentAgeValues[2:6] = v[0:4]
|
|
57
|
+
smp.PublishValues[5:7] = copy.deepcopy(v[0:2])
|
|
58
|
+
except (Exception, BaseException):
|
|
59
|
+
raise
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
def calc_j(ar40ar39=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
params_index_dict = {
|
|
64
|
+
34: 'L', 35: 'rsL', 59: 'Age', 60: 'sAge'
|
|
65
|
+
}
|
|
66
|
+
if ar40ar39 is None and smp is not None:
|
|
67
|
+
ar40ar39 = smp.ApparentAgeValues[0:2] # ar40ar39 air, error
|
|
68
|
+
if len(np.shape(ar40ar39)) == 1:
|
|
69
|
+
ar40ar39 = np.reshape(ar40ar39, (2, 1))
|
|
70
|
+
if index is None:
|
|
71
|
+
index = list(range(np.shape(ar40ar39)[-1]))
|
|
72
|
+
if smp is None and params is None:
|
|
73
|
+
raise ValueError(f"Parameters are required for calculating mdf, or it is empty.")
|
|
74
|
+
if params is not None:
|
|
75
|
+
for key, val in params.items():
|
|
76
|
+
if not isinstance(val, list):
|
|
77
|
+
params[key] = list(val)
|
|
78
|
+
if smp is not None:
|
|
79
|
+
try:
|
|
80
|
+
params_from_smp = dict(zip(
|
|
81
|
+
list(params_index_dict.values()),
|
|
82
|
+
[[smp.TotalParam[i][j] for j in index] for i in params_index_dict.keys()]
|
|
83
|
+
))
|
|
84
|
+
except Exception:
|
|
85
|
+
print(traceback.format_exc())
|
|
86
|
+
raise ValueError(f"Parameters cannot be found in the given sample object")
|
|
87
|
+
if params is not None:
|
|
88
|
+
params_from_smp.update(params)
|
|
89
|
+
params = params_from_smp
|
|
90
|
+
|
|
91
|
+
j = calc.jvalue.j_value(params['Age'], params['sAge'], *ar40ar39, params['L'], params['rsL'])
|
|
92
|
+
|
|
93
|
+
if len(index) == 1:
|
|
94
|
+
return np.array(j).squeeze().tolist()
|
|
95
|
+
else:
|
|
96
|
+
return np.array(j).tolist()
|
|
67
97
|
|
|
68
98
|
|
|
69
99
|
def calc_mdf(ar40ar36=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
100
|
+
params_index_dict = {
|
|
101
|
+
71: 'M36', 72: 'sM36', 79: 'M40', 80: 'sM40', 93: 'Air', 94: 'rsAir', 100: 'Discr'
|
|
102
|
+
}
|
|
103
|
+
if ar40ar36 is None and smp is not None:
|
|
104
|
+
ar40ar36 = smp.ApparentAgeValues[0:2] # ar40ar36 air, error
|
|
105
|
+
if len(np.shape(ar40ar36)) == 1:
|
|
106
|
+
ar40ar36 = np.reshape(ar40ar36, (2, 1))
|
|
107
|
+
if index is None:
|
|
108
|
+
index = list(range(np.shape(ar40ar36)[-1]))
|
|
109
|
+
if smp is None and params is None:
|
|
110
|
+
raise ValueError(f"Parameters are required for calculating mdf, or it is empty.")
|
|
111
|
+
if params is not None:
|
|
112
|
+
for key, val in params.items():
|
|
113
|
+
if not isinstance(val, list):
|
|
114
|
+
params[key] = list(val)
|
|
115
|
+
if smp is not None:
|
|
116
|
+
try:
|
|
117
|
+
params_from_smp = dict(zip(
|
|
118
|
+
list(params_index_dict.values()),
|
|
119
|
+
[[smp.TotalParam[i][j] for j in index] for i in params_index_dict.keys()]
|
|
120
|
+
))
|
|
121
|
+
except Exception:
|
|
122
|
+
print(traceback.format_exc())
|
|
123
|
+
raise ValueError(f"Parameters cannot be found in the given sample object")
|
|
124
|
+
if params is not None:
|
|
125
|
+
params_from_smp.update(params)
|
|
126
|
+
params = params_from_smp
|
|
127
|
+
|
|
75
128
|
mdf = []
|
|
76
|
-
for i in range(len(
|
|
77
|
-
k = calc.corr.mdf(
|
|
78
|
-
|
|
79
|
-
|
|
129
|
+
for i in range(len(index)):
|
|
130
|
+
k = calc.corr.mdf(ar40ar36[0][i], ar40ar36[1][i], params['M36'][i], params['M40'][i],
|
|
131
|
+
params['Air'][i], params['rsAir'][i]) # linear, exp, pow
|
|
132
|
+
mdf.append({"linear": k[0:4], "exp": k[4:8], "pow": k[8:12]}[params['Discr'][i].lower()])
|
|
133
|
+
|
|
134
|
+
if len(index) == 1:
|
|
135
|
+
return np.transpose(mdf).squeeze().tolist()
|
|
136
|
+
else:
|
|
137
|
+
return np.transpose(mdf).tolist()
|
|
80
138
|
|
|
81
139
|
|
|
82
140
|
def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list = None):
|
|
@@ -95,7 +153,8 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
|
|
|
95
153
|
"""
|
|
96
154
|
params_index_dict = {
|
|
97
155
|
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',
|
|
156
|
+
50: 'Ae', 51: 'sAe', 52: 'Ab', 53: 'sAb', 54: 'Abp', 55: 'sAbp', 59: 't', 60: 'st',
|
|
157
|
+
61: 'Ap', 62: 'sAp', 63: 'Kp', 64: 'sKp', 67: 'J', 68: 'sJ',
|
|
99
158
|
81: 'W', 82: 'sW', 83: 'No', 84: 'sNo', 85: 'Y', 86: 'sY', 87: 'f', 88: 'sf', 110: 'Min'
|
|
100
159
|
}
|
|
101
160
|
|
|
@@ -477,7 +536,7 @@ def get_diff_smp(backup: (dict, Sample), smp: (dict, Sample)):
|
|
|
477
536
|
# =======================
|
|
478
537
|
# Set parameters
|
|
479
538
|
# =======================
|
|
480
|
-
def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None):
|
|
539
|
+
def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None, rows: Optional[List] =None):
|
|
481
540
|
"""
|
|
482
541
|
Parameters
|
|
483
542
|
----------
|
|
@@ -485,84 +544,76 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
485
544
|
params
|
|
486
545
|
flag : optional, should be one of 'calc', 'irra', and 'smp'. If it is not given,
|
|
487
546
|
the text of the extension without a dot will be used
|
|
547
|
+
rows
|
|
488
548
|
|
|
489
549
|
Returns
|
|
490
550
|
-------
|
|
491
551
|
|
|
492
552
|
"""
|
|
553
|
+
if rows is None:
|
|
554
|
+
rows = []
|
|
555
|
+
rows = list(set(rows))
|
|
556
|
+
|
|
493
557
|
if isinstance(params, str) and os.path.isfile(params):
|
|
494
558
|
if flag is None:
|
|
495
559
|
flag = params.split(".")[-1]
|
|
496
560
|
return set_params(smp, read_params(params), flag=flag)
|
|
497
561
|
|
|
498
|
-
def
|
|
499
|
-
|
|
562
|
+
def isValid(item):
|
|
563
|
+
valid = True
|
|
564
|
+
if isinstance(item, (float, int)):
|
|
565
|
+
valid = not np.isnan(item)
|
|
566
|
+
return valid and item is not None and item != ""
|
|
567
|
+
|
|
568
|
+
def remove_none(old_params, new_params, row_list, length):
|
|
569
|
+
res = [[old_params[i][j] if j < len(old_params[i]) else None for j in range(max(len(old_params[i]), length))] for i in range(len(old_params))]
|
|
500
570
|
for index, item in enumerate(new_params):
|
|
501
|
-
if item
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
res[index] = [item] * rows
|
|
571
|
+
if isValid(item):
|
|
572
|
+
for row in row_list:
|
|
573
|
+
res[index][row] = item
|
|
505
574
|
return res
|
|
506
575
|
|
|
507
576
|
n = len(smp.SequenceName)
|
|
508
|
-
|
|
509
577
|
if n == 0:
|
|
510
|
-
raise ValueError(f"The number of sample sequences is
|
|
578
|
+
raise ValueError(f"The number of sample sequences is zero")
|
|
511
579
|
|
|
512
580
|
if flag == 'calc':
|
|
513
|
-
smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22],
|
|
514
|
-
smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48],
|
|
581
|
+
smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22], rows, n)
|
|
582
|
+
smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48], rows, n)
|
|
515
583
|
elif flag == 'irra':
|
|
516
|
-
smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20],
|
|
517
|
-
smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22],
|
|
518
|
-
smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29],
|
|
519
|
-
# smp.TotalParam[26] = [params[26]] * n
|
|
584
|
+
smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20], rows, n)
|
|
585
|
+
smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22], rows, n) # Cl36/38 productivity
|
|
586
|
+
smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29], rows, n)
|
|
520
587
|
irradiation_time = []
|
|
521
588
|
duration = []
|
|
522
589
|
if None not in params[29:-3] and '' not in params[29:-3]:
|
|
523
590
|
for i in range(len(params[29:-3])):
|
|
524
591
|
if i % 2 == 0:
|
|
525
|
-
# [d, t] = params[29:-3][i].split('T')
|
|
526
|
-
# [t1, t2] = t.split(':')
|
|
527
|
-
# irradiation_time.append(d + '-' + t1 + '-' + t2 + 'D' + str(params[29:-3][i + 1]))
|
|
528
|
-
text = params[29:-3][i]
|
|
529
|
-
for char in ['T', ':']:
|
|
530
|
-
text = text.replace(char, '-')
|
|
531
592
|
irradiation_time.append(params[29:-3][i] + 'D' + str(params[29:-3][i + 1]))
|
|
532
593
|
duration.append(float(params[29:-3][i + 1]))
|
|
533
|
-
smp.TotalParam[27] = ['S'.join(irradiation_time)]
|
|
534
|
-
smp.TotalParam[28] = [params[-3]] * n
|
|
535
|
-
smp.TotalParam[29] = [sum(duration)] * n
|
|
594
|
+
smp.TotalParam[27:30] = remove_none(smp.TotalParam[27:30], ['S'.join(irradiation_time), params[-3], sum(duration)], rows, n)
|
|
536
595
|
if params[-5] != '':
|
|
537
|
-
|
|
538
|
-
# [b, c] = b.split(':')
|
|
539
|
-
# smp.TotalParam[30] = [a + '-' + b + '-' + c] * n
|
|
540
|
-
text = params[-5]
|
|
541
|
-
for char in ['T', ':']:
|
|
542
|
-
text = text.replace(char, '-')
|
|
543
|
-
# smp.TotalParam[30] = [text] * n
|
|
544
|
-
smp.TotalParam[30] = [params[-5]] * n
|
|
596
|
+
smp.TotalParam[30:32] = remove_none(smp.TotalParam[30:32], [params[-5], None], rows, n)
|
|
545
597
|
try:
|
|
546
598
|
stand_time_second = [
|
|
547
599
|
calc.basic.get_datetime(*re.findall(r"\d+", smp.TotalParam[31][i])) - calc.basic.get_datetime(
|
|
548
|
-
*re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(
|
|
600
|
+
*re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(len(smp.TotalParam[30]))]
|
|
549
601
|
except (BaseException, Exception):
|
|
550
602
|
print(f'Error in calculate standing duration: {traceback.format_exc()}')
|
|
551
|
-
|
|
603
|
+
smp.TotalParam[32] = [None for index in range(n)]
|
|
552
604
|
else:
|
|
553
|
-
smp.TotalParam[32] = [
|
|
605
|
+
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
|
|
554
606
|
|
|
555
607
|
elif flag == 'smp':
|
|
556
|
-
|
|
557
|
-
smp.TotalParam[67
|
|
558
|
-
smp.TotalParam[
|
|
559
|
-
smp.TotalParam[
|
|
560
|
-
smp.TotalParam[
|
|
561
|
-
smp.TotalParam[
|
|
562
|
-
# smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], n, 123 - 120)
|
|
608
|
+
smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], rows, n)
|
|
609
|
+
smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], rows, n)
|
|
610
|
+
smp.TotalParam[97:100] = remove_none(smp.TotalParam[97:100], params[13:16], rows, n)
|
|
611
|
+
smp.TotalParam[115:120] = remove_none(smp.TotalParam[115:120], params[16:21], rows, n)
|
|
612
|
+
smp.TotalParam[126:136] = remove_none(smp.TotalParam[126:136], params[21:31], rows, n)
|
|
613
|
+
# smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], rows, n)
|
|
563
614
|
smp.TotalParam[100:114] = remove_none(
|
|
564
615
|
smp.TotalParam[100:114],
|
|
565
|
-
[['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]],
|
|
616
|
+
[['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
|
|
566
617
|
pref = dict(zip(preference_keys, params[31:35]))
|
|
567
618
|
smp.Info.preference.update(pref)
|
|
568
619
|
for key, comp in get_components(smp).items():
|
|
@@ -570,7 +621,6 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
570
621
|
comp.decimal_places = pref['decimalPlaces']
|
|
571
622
|
comp.set_coltypes()
|
|
572
623
|
smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(pref['ageUnit']).capitalize()})"
|
|
573
|
-
print(smp.Info.preference)
|
|
574
624
|
|
|
575
625
|
else:
|
|
576
626
|
raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
|