ararpy 0.1.34__py3-none-any.whl → 0.1.36__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 CHANGED
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
16
16
  """ Information """
17
17
 
18
18
  name = 'ararpy'
19
- version = '0.1.34'
19
+ version = '0.1.36'
20
20
  __version__ = version
21
21
  full_version = version
22
- last_update = '2025-10-22'
22
+ last_update = '2025-12-08'
23
23
 
24
24
  """ ArArPy Functions """
25
25
 
ararpy/calc/basic.py CHANGED
@@ -10,8 +10,7 @@
10
10
  #
11
11
  """
12
12
  import copy
13
- import random
14
- import string
13
+ import secrets
15
14
  import numpy as np
16
15
  from scipy import stats
17
16
  from datetime import datetime, timezone, timedelta
@@ -100,8 +99,8 @@ def update_dicts(a: dict, b: dict):
100
99
  return res
101
100
 
102
101
 
103
- def get_random_digits(length: int = 7) -> str:
104
- return ''.join(random.choices(string.digits, k=length))
102
+ def get_random_string(length: int = 8) -> str:
103
+ return secrets.token_hex(max(int(length/2), 1))
105
104
 
106
105
 
107
106
  def monte_carlo(func, inputs, confidence_level, **kwargs):
ararpy/calc/raw_funcs.py CHANGED
@@ -30,8 +30,8 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
30
30
 
31
31
  """
32
32
  def power(a0, a1):
33
- return regression.power(a0, a1)
34
- # raise ValueError("Deprecated regression")
33
+ # return regression.power(a0, a1)
34
+ raise ValueError("Deprecated regression")
35
35
  # if unselected is None:
36
36
  # unselected = []
37
37
  # linesData = []
@@ -42,9 +42,9 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
42
42
  power, regression.average]
43
43
  # size = 50
44
44
  # lines_x = [(max(x + un_x) - 0) / size * i for i in range(size + 1)]
45
+ x, y = transpose(points_data, ignore=False)
45
46
  for i in range(len(reg_handler)):
46
47
  try:
47
- x, y = transpose(points_data, ignore=False)
48
48
  res = reg_handler[i](a0=y, a1=x)
49
49
  # line_data = transpose([lines_x, res[7](lines_x)])
50
50
  line_results = res[0:4]
ararpy/calc/regression.py CHANGED
@@ -16,7 +16,7 @@ import traceback
16
16
  import numpy as np
17
17
  import pandas as pd
18
18
  from scipy.stats import distributions
19
- from scipy.optimize import fsolve
19
+ from scipy.optimize import minimize_scalar
20
20
  import warnings
21
21
  from scipy.optimize import minimize
22
22
  warnings.simplefilter(action="ignore", category=RuntimeWarning)
@@ -495,16 +495,19 @@ def linest(a0: list, a1: list, *args):
495
495
  # calculate Y values base on the fitted formula
496
496
  estimate_y = np.matmul(x, beta)
497
497
  resid = (estimate_y - y) ** 2
498
- reg = (estimate_y - np.mean(estimate_y)) ** 2
499
- ssresid = resid.sum()
500
- ssreg = reg.sum()
501
- sstotal = ssreg + ssresid
498
+ reg = (estimate_y - np.mean(y)) ** 2
499
+ ssresid = resid.sum() # 残差平方和
500
+ ssreg = reg.sum() # 回归平方和
501
+ sstotal = ((y - np.mean(y)) ** 2).sum()
502
+ r2 = ssreg / sstotal if sstotal != 0 else np.inf
503
+
502
504
  df = m - n
503
- m_ssresid = ssresid / df
504
- se_beta = (m_ssresid * np.diagonal(inv_xtx)) ** .5
505
- beta = beta.transpose()[0]
505
+ m_ssresid = ssresid / df # 均方残差,与加权平均中的MSWD对应
506
+ cov_beta = m_ssresid * inv_xtx
507
+ se_beta = np.diagonal(cov_beta) ** .5
508
+
509
+ beta = beta.flatten()
506
510
  rse_beta = se_beta / beta
507
- r2 = ssreg / sstotal if sstotal != 0 else np.inf
508
511
 
509
512
  def get_adjusted_y(*args):
510
513
  args = [[1] * len(args[0]), *args]
@@ -538,7 +541,7 @@ def average(a0: list, a1=None):
538
541
  k1 = pow(sum([(i - k0) ** 2 for i in a0]) / df, 0.5) # standard deviation
539
542
  k2 = k1 / k0 * 100 if k0 != 0 else 0 # relative standard error
540
543
  k3 = r2 # determination coefficient
541
- k4 = 'MSWD'
544
+ k4 = m_ssresid # 'MSWD'
542
545
  k5 = [k0]
543
546
  k6 = [k1]
544
547
  k8 = m_ssresid
@@ -869,92 +872,101 @@ def power(a0: list, a1: list):
869
872
 
870
873
 
871
874
  def exponential(a0: list, a1: list):
872
- """
873
- :param a0: known_y's, y = a * b ^ x + c
874
- :param a1: known_x's
875
- :return: intercept | standard error of intercept | relative error | R2 | MSWD | [m, c, b] | [sem, sec, seb]
876
- """
877
875
 
878
- def _exp_func(x, a, b, c):
879
- return a * b ** x + c
876
+ X = np.array(a1)
877
+ Y = np.array(a0)
878
+ y = np.array([a0]).transpose()
880
879
 
881
- def _residuals(params):
882
- a, b, c = params
883
- return [_exp_func(xi, a, b, c) - yi for xi, yi in zip(a1, a0)]
880
+ def _exp_func(xi, a, b, c):
881
+ return a * np.exp(b * xi) + c
884
882
 
885
- def _sum_squared_error(params):
886
- return sum(r**2 for r in _residuals(params))
883
+ @np.vectorize
884
+ def _get_s(b):
885
+ x = np.concatenate(([np.ones(len(a1))], [np.exp(b * np.array(a1))]), axis=0).transpose()
886
+ try:
887
+ inv_xtx = np.linalg.inv(np.matmul(x.transpose(), x))
888
+ except np.linalg.LinAlgError:
889
+ raise np.linalg.LinAlgError(f"The determinant of the given matrix must not be zero ")
890
+ beta = np.matmul(inv_xtx, np.matmul(x.transpose(), y))
891
+ c, a = beta.flatten()
892
+ reg_y = _exp_func(X, a, b, c)
893
+ resid = (reg_y - Y) ** 2
894
+ ssresid = sum(resid)
895
+ return ssresid
887
896
 
888
- def _get_ac(b):
889
- f = linest(a0, [b ** xi for xi in a1])
890
- return f[5][1], b, f[0]
891
897
 
892
- def _get_init():
893
- f = linest(np.log(np.array(a0)), np.array(a1))
894
- return np.exp(f[0]), np.exp(f[5][1]), 0
898
+ ini_f = linest(np.log(Y), X)
899
+ ini_b = ini_f[5][1]
895
900
 
901
+ # 替换原来的 minimize_scalar 部分
896
902
  try:
897
- a, b, c = _get_init()
898
- # a, b, c = minimize(_sum_squared_error, [a, b, c], method="Nelder-Mead").x # 优化方法
899
- count = 0
900
- step = 0.01
901
- while count < 100:
902
- a, b, c = _get_ac(b)
903
- s = _sum_squared_error([a, b, c])
904
- b_left, b_right = b - step * b, b + step * b
905
- s_left = _sum_squared_error(_get_ac(b_left))
906
- s_right = _sum_squared_error(_get_ac(b_right))
907
- if s_left > s > s_right:
908
- b = b_right
909
- continue
910
- elif s_left < s < s_right:
911
- b = b_left
912
- continue
913
- elif s_left < s_right:
914
- b = (b + b_left) / 2
915
- else:
916
- b = (b + b_right) / 2
917
- count += 1
918
- step = step * 0.5
919
- if step < 0.000001:
920
- break
903
+ b, count = newton_minimize_1d(_get_s, x0=ini_b, h=1e-5, tol=1e-8, max_iter=30)
904
+ except Exception as e:
905
+ # 使用 scipy 一维优化
906
+ res = minimize_scalar(_get_s, bounds=(-2, 2), method='bounded', options={'xatol': 1e-8})
907
+ b, count = res.x, res.nfev
921
908
 
922
- except RuntimeError:
923
- raise RuntimeError
924
- except np.linalg.LinAlgError:
925
- raise np.linalg.LinAlgError
926
- except TypeError:
927
- raise TypeError
928
- except IndexError:
929
- raise IndexError
930
-
931
- f = linest(a0, [b ** _x for _x in a1])
932
- a, sea, c, sec = f[5][1], f[6][1], f[0], f[1]
909
+ # print(f"{b = }, {count = }")
933
910
 
934
- calculated_y = [_exp_func(i, a, b, c) for i in a1]
935
- resid = [(calculated_y[i] - a0[i]) ** 2 for i in range(len(a0))]
936
- reg = [(i - sum(calculated_y) / len(calculated_y)) ** 2 for i in calculated_y]
937
- ssresid = sum(resid)
938
- ssreg = sum(reg)
939
- sstotal = ssreg + ssresid
940
- dp = len(a1)
941
- df = dp - 1
942
- m_ssresid = ssresid / df
911
+ x = np.concatenate(([np.ones(len(a1))], [np.exp(b * np.array(a1))]), axis=0).transpose()
912
+ m, n = x.shape # number of data, number of unknown x
913
+ try:
914
+ inv_xtx = np.linalg.inv(np.matmul(x.transpose(), x))
915
+ except np.linalg.LinAlgError:
916
+ raise np.linalg.LinAlgError(f"The determinant of the given matrix must not be zero ")
917
+ beta = np.matmul(inv_xtx, np.matmul(x.transpose(), y))
918
+ estimate_y = np.matmul(x, beta)
919
+ resid = (estimate_y - y) ** 2
920
+ reg = (estimate_y - np.mean(y)) ** 2
921
+ ssresid = resid.sum() # 残差平方和
922
+ ssreg = reg.sum() # 回归平方和
923
+ sstotal = ((y - np.mean(y)) ** 2).sum()
943
924
  r2 = ssreg / sstotal if sstotal != 0 else 1
944
925
 
945
- z = [b ** i for i in a1]
926
+ df = m - n
927
+ m_ssresid = ssresid / df # 均方残差,与加权平均中的MSWD对应
928
+ cov_beta = m_ssresid * inv_xtx
929
+
930
+ sc, sa = np.diagonal(cov_beta) ** .5
931
+ c, a = beta.flatten()
946
932
  intercept = a + c
947
- se_intercept_1 = np.sqrt(sea ** 2 + sec ** 2)
948
- # calculate error of intercept
949
- errfz = pow(sum([i ** 2 for i in z]) / (dp * sum([i ** 2 for i in z]) - sum(z) ** 2), 0.5)
950
- errfx = pow(sum([i ** 2 for i in a1]) / (dp * sum([i ** 2 for i in a1]) - sum(a1) ** 2), 0.5)
951
- # seb = errfz * sey = errfz * ssresid / df -> se_intercept = sey * errfx = seb / errfz * errfx
952
- se_intercept = sec / errfz * errfx
953
- rse_intercept = se_intercept / intercept * 100
933
+ se_intercept = pow(sa ** 2 + sc ** 2 + 2 * cov_beta[0][1] , 0.5)
954
934
 
955
- return intercept, se_intercept, rse_intercept, r2, 'mswd', [a, b, c], 'se', \
956
- lambda x: [_exp_func(i, a, b, c) for i in x], m_ssresid
935
+ return intercept, se_intercept, se_intercept / intercept * 100, r2, m_ssresid, [a, b, c], 'se', \
936
+ lambda x: [_exp_func(xi, a, b, c) for xi in x], m_ssresid
937
+
938
+
939
+ def newton_minimize_1d(func, x0, h=1e-5, tol=1e-8, max_iter=20):
940
+ x = x0
941
+ for i in range(max_iter):
942
+ fx = func(x)
943
+ if not np.isfinite(fx):
944
+ raise ValueError("Newton Minimize: Function returned non-finite value at x={}".format(x))
945
+
946
+ # 一阶导数(中心差分)
947
+ f_plus = func(x + h)
948
+ f_minus = func(x - h)
949
+ if not (np.isfinite(f_plus) and np.isfinite(f_minus)):
950
+ raise ValueError("Newton Minimize: Non-finite values in derivative computation")
951
+
952
+ df = (f_plus - f_minus) / (2 * h)
953
+ d2f = (f_plus - 2 * fx + f_minus) / (h * h)
954
+
955
+ # 牛顿步长
956
+ if abs(d2f) < 1e-12: # 避免除零或平坦区域
957
+ print("Newton Minimize: Second derivative too small, stopping.")
958
+ break
959
+
960
+ step = df / d2f
961
+ x_new = x - step
962
+
963
+ if abs(step) < tol:
964
+ x = x_new
965
+ break
966
+
967
+ x = x_new
957
968
 
969
+ return x, i + 1
958
970
 
959
971
  """ line functions """
960
972
 
ararpy/files/basic.py CHANGED
@@ -12,31 +12,9 @@
12
12
 
13
13
  import os
14
14
  import pickle
15
- import traceback
16
15
  import json
17
16
 
18
17
 
19
- def upload(file, media_dir):
20
- try:
21
- name, suffix = os.path.splitext(file.name)
22
- if suffix.lower() not in [
23
- '.xls', '.age', '.xlsx', '.arr', '.jpg', '.png', '.txt',
24
- '.log', '.seq', '.json', '.ahd', '.csv', '.ngxdp']:
25
- raise TypeError(f"The imported file is not supported: {suffix}")
26
- web_file_path = os.path.join(media_dir, file.name)
27
- with open(web_file_path, 'wb') as f:
28
- for chunk in file.chunks():
29
- f.write(chunk)
30
- print("File path on the server: %s" % web_file_path)
31
- except PermissionError:
32
- raise ValueError(f'Permission denied')
33
- except (Exception, BaseException) as e:
34
- print(traceback.format_exc())
35
- raise ValueError(f'Error in opening file: {e}')
36
- else:
37
- return web_file_path, name, suffix
38
-
39
-
40
18
  def read(file_path):
41
19
  """ Read text files, default 'r', 'rb'
42
20
  Parameters
ararpy/files/calc_file.py CHANGED
@@ -493,40 +493,41 @@ def open_full_xls(file_path: str, sample_name: str = ''):
493
493
  res['Inverse Isochron Table'], rows, [4, 5, 6, 7, 10])
494
494
  total_param = arr.partial(
495
495
  res['Sample Parameters'], rows, [
496
- # 1, 2, # 0-1
497
- -1, -1, -1, -1, # 2-5
498
- -1, -1, -1, -1, # 6-9
499
- -1, -1, -1, -1, -1, -1, # 10-15
500
- -1, -1, -1, -1, # 16-19
501
- -1, -1, # 20-21
502
- 23, 24, -1, -1, -1, -1, # 22-27
503
- -1, -1, # 28-29
504
- 22, -1, -1, -1, # 30-33
505
- -1, -1, # 34-35
506
- -1, -1, # 36-37
507
- -1, -1, # 38-39
508
- -1, -1, # 40-41
509
- -1, -1, # 42-43
510
- -1, -1, # 44-45
511
- -1, -1, # 46-47
512
- -1, -1, # 48-49
513
- -1, -1, # 50-51
514
- -1, -1, # 52-53
515
- -1, -1, # 54-55
516
- -1, -1, # 56-57
517
- -1, -1, # 58-59
518
- -1, -1, -1, -1, -1, -1, -1, -1, -1, # 60-68
519
- 10, 11, 12, 13, # 69-72
520
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 73-84
521
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 85-94
522
- -1, -1, -1, -1, # 95-98
523
- -1, -1, -1, -1, # 99-102
524
- -1, -1, -1, -1, # 103-106
525
- -1, -1, -1, -1, # 107-110
526
- -1, -1, -1, -1, # 111-114
527
- -1, -1, -1, -1, -1, -1, -1, -1, # 115-122
528
- -1, -1, -1, -1, -1, -1, -1, -1, # 123-130
529
- -1, -1, -1, -1, -1, # 131-135
496
+ # 1, 2, -1, # 0-2
497
+ -1, -1, -1, -1, # 3-6
498
+ -1, -1, -1, -1, # 7-10
499
+ -1, -1, -1, -1, -1, -1, # 11-16
500
+ -1, -1, -1, -1, # 17-20
501
+ -1, -1, # 21-22
502
+ 23, 24, -1, -1, -1, -1, # 23-28
503
+ -1, -1, # 29-30
504
+ 22, -1, -1, -1, # 31-34
505
+ -1, -1, # 35-36
506
+ -1, -1, # 37-38
507
+ -1, -1, # 39-40
508
+ -1, -1, # 41-42
509
+ -1, -1, # 43-44
510
+ -1, -1, # 45-46
511
+ -1, -1, # 47-48
512
+ -1, -1, # 49-50
513
+ -1, -1, # 51-52
514
+ -1, -1, # 53-54
515
+ -1, -1, # 55-56
516
+ -1, -1, # 57-58
517
+ -1, -1, # 59-60
518
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, # 61-69
519
+ 10, 11, 12, 13, # 70-73
520
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 74-85
521
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 86-95
522
+ -1, -1, -1, -1, # 96-99
523
+ -1, -1, -1, -1, # 100-103
524
+ -1, -1, -1, -1, # 104-107
525
+ -1, -1, -1, -1, # 108-111
526
+ -1, -1, -1, -1, # 112-115
527
+ -1, -1, -1, -1, -1, -1, -1, -1, # 116-123
528
+ -1, -1, -1, -1, -1, -1, -1, -1, # 124-131
529
+ -1, -1, -1, -1, -1, # 132-136
530
+ -1, -1, -1, -1, # 137-140
530
531
  ])
531
532
 
532
533
  month_convert = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
ararpy/files/raw_file.py CHANGED
@@ -65,7 +65,7 @@ DEFAULT_SAMPLE_INFO = {
65
65
 
66
66
 
67
67
 
68
- def open_file(file_path: str, input_filter: List[Union[str, int, bool]]):
68
+ def open_file(file_path: str, input_filter: List[Union[str, int, bool]], name=None):
69
69
  """
70
70
  Parameters
71
71
  ----------
@@ -94,63 +94,14 @@ def open_file(file_path: str, input_filter: List[Union[str, int, bool]]):
94
94
  """
95
95
  extension = str(os.path.split(file_path)[-1]).split('.')[-1]
96
96
  try:
97
- handler = {'txt': open_raw_txt, 'excel': open_raw_xls,
98
- 'Qtegra Exported XLS': open_qtegra_exported_xls, 'Seq': open_raw_seq}[
99
- ['txt', 'excel', 'Qtegra Exported XLS', 'Seq'][int(input_filter[1])]]
97
+ handler = {'txt': open_raw_txt, 'excel': open_raw_xls, 'Seq': open_raw_seq}[
98
+ ['txt', 'excel', 'Qtegra Excel (deleted)', 'Seq'][int(input_filter[1])]]
100
99
  except KeyError:
101
100
  raise FileNotFoundError("Wrong File.")
102
- return handler(file_path, input_filter)
101
+ return handler(file_path, input_filter, name)
103
102
 
104
103
 
105
- def open_qtegra_exported_xls(filepath, input_filter=None):
106
- if input_filter is None:
107
- input_filter = []
108
- try:
109
- wb = open_workbook(filepath)
110
- sheets = wb.sheet_names()
111
- sheet = wb.sheet_by_name(sheets[0])
112
- value, step_header, step_list = [], [], []
113
- for row in range(sheet.nrows):
114
- row_set = []
115
- for col in range(sheet.ncols):
116
- if sheet.cell(row, col).value == '':
117
- pass
118
- else:
119
- row_set.append(sheet.cell(row, col).value)
120
- if row_set != [] and len(row_set) > 1:
121
- value.append(row_set)
122
- for each_row in value:
123
- # if the first item of each row is float (1.0, 2.0, ...) this row is the header of a step.
124
- if isinstance(each_row[0], float):
125
- each_row[0] = int(each_row[0])
126
- if "M" in each_row[1].upper():
127
- each_row[1] = datetime.strptime(each_row[1], '%m/%d/%Y %I:%M:%S %p').isoformat(timespec='seconds')
128
- else:
129
- each_row[1] = datetime.strptime(each_row[1], '%m/%d/%Y %H:%M:%S').isoformat(timespec='seconds')
130
- step_header.append(each_row)
131
- for step_index, each_step_header in enumerate(step_header):
132
- row_start_number = value.index(each_step_header)
133
- try:
134
- row_stop_number = value.index(step_header[step_index + 1])
135
- except IndexError:
136
- row_stop_number = len(value) + 1
137
- step_values = [
138
- each_step_header[0:4],
139
- *list(map(
140
- # lambda x: [x[0], x[1], x[2], x[1], x[3], x[1], x[4], x[1], x[5], x[1], x[6]],
141
- # x[1] = time, x[2] = H2:40, x[3] = H1: 39, x[4] = AX: 38, x[5] = L1: 37, x[6] = L2: 36
142
- lambda x: [x[0], x[1], x[6], x[1], x[5], x[1], x[4], x[1], x[3], x[1], x[2]],
143
- # in sequence: Ar36, Ar37, Ar38, Ar39, Ar40
144
- [value[i] for i in range(row_start_number + 2, row_stop_number - 7, 1)]))
145
- ]
146
- step_list.append(step_values)
147
- except Exception as e:
148
- raise ValueError('Error in opening the original file: %s' % str(e))
149
- else:
150
- return {'data': step_list}
151
-
152
-
153
- def open_raw_txt(file_path, input_filter: List[Union[str, int]]):
104
+ def open_raw_txt(file_path, input_filter: List[Union[str, int]], name=None):
154
105
  """
155
106
  Parameters
156
107
  ----------
@@ -173,12 +124,12 @@ def open_raw_txt(file_path, input_filter: List[Union[str, int]]):
173
124
  lines = [line.strip().split(['\t', ';', " ", ",", input_filter[3]][int(input_filter[2])])
174
125
  for line in contents.decode(encoding=encoding["encoding"]).split('\r\n')]
175
126
 
176
- file_name = os.path.basename(file_path).rstrip(os.path.splitext(file_path)[-1])
127
+ file_name = os.path.basename(file_path).rstrip(os.path.splitext(file_path)[-1]) if name is None else name
177
128
  step_list = get_raw_data([lines], input_filter, file_name=file_name)
178
129
  return {'data': step_list}
179
130
 
180
131
 
181
- def open_raw_xls(file_path, input_filter: List[Union[str, int]]):
132
+ def open_raw_xls(file_path, input_filter: List[Union[str, int]], name):
182
133
  """
183
134
  Parameters
184
135
  ----------
@@ -205,13 +156,13 @@ def open_raw_xls(file_path, input_filter: List[Union[str, int]]):
205
156
 
206
157
  wb = open_workbook(file_path)
207
158
  contents = [_get_content_from_sheet(i) for i in range(100)]
208
- file_name = os.path.basename(file_path).rstrip(os.path.splitext(file_path)[-1])
159
+ file_name = os.path.basename(file_path).rstrip(os.path.splitext(file_path)[-1]) if name is None else name
209
160
  step_list = get_raw_data(contents, input_filter, file_name=file_name)
210
161
 
211
162
  return {'data': step_list}
212
163
 
213
164
 
214
- def open_raw_seq(file_path, input_filter=None):
165
+ def open_raw_seq(file_path, input_filter=None, name=None):
215
166
 
216
167
  class RenameUnpickler(pickle.Unpickler):
217
168
  def find_class(self, module: str, name: str):
@@ -257,20 +208,29 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
257
208
 
258
209
  """
259
210
 
260
- def datetime_parse(string, f):
211
+ def datetime_parse(string: str, f: str):
261
212
  try:
262
213
  return datetime.strptime(string, f)
263
214
  except ValueError as v:
215
+ print(traceback.format_exc())
264
216
  if f.strip() == "":
265
217
  return datetime_parser.parse(string)
266
218
  elif len(v.args) > 0 and v.args[0].startswith('unconverted data remains: '):
267
- string = string[:-(len(v.args[0]) - 26)]
268
- return datetime.strptime(string, f)
219
+ # %f handles microseconds (6 digits), remove the remains
220
+ return datetime_parse(string[:-(len(v.args[0]) - 26)], f)
221
+ # elif f.upper()[-2:] in ['PM', 'AM']:
222
+ # return datetime_parse(string, f[:-2])
269
223
  else:
270
224
  raise
271
225
 
226
+ def step_num_parse(s: str):
227
+ try:
228
+ return f"{round(float(s)):02d}"
229
+ except (ValueError, TypeError):
230
+ return s
231
+
272
232
  step_list = []
273
- idx = step_index = 0
233
+ idx = 0 # step_index
274
234
 
275
235
  header = input_filter[5]
276
236
  isotope_index = input_filter[8:28]
@@ -293,13 +253,10 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
293
253
  if res is not None and "en" in res.named.keys():
294
254
  experiment_name = res.named.get("en")
295
255
  if res is not None and "sn" in res.named.keys():
296
- step_index = res.named.get("sn")
297
- if step_index.isnumeric():
298
- step_name = f"{experiment_name}-{int(step_index):02d}"
299
- else:
300
- step_name = f"{experiment_name}-{step_index}"
301
- if step_name == "":
302
- raise ValueError(f"Step name not found")
256
+ step_name = res.named.get("sn")
257
+ if str(step_name) == "":
258
+ raise ValueError(f"Step name not found, break reading steps")
259
+ step_name = f"{experiment_name}-{step_num_parse(step_name)}"
303
260
  except (TypeError, ValueError, IndexError):
304
261
  # When parsing the step name fails, the end of the file has been reached
305
262
  # raise
@@ -417,7 +374,7 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
417
374
  step_list.append(current_step)
418
375
  idx = data_index[28] * len(step_list)
419
376
  if not check_box_index[0] or len(step_list) >= 500: # check_box_index[0]: multiple sequences
420
- print(f"Multiple Sequence = {check_box_index[0]}, Step number = {len(step_list)}")
377
+ # print(f"Multiple Sequence = {check_box_index[0]}, Step number = {len(step_list)}")
421
378
  break
422
379
 
423
380
  if not step_list:
@@ -4436,7 +4436,7 @@ def get_random_dir(path: str, length=7, random_index=""):
4436
4436
  try:
4437
4437
  exist_ok = random_index != ""
4438
4438
  if random_index == "":
4439
- random_index = calc.basic.get_random_digits(length=length)
4439
+ random_index = calc.basic.get_random_string(length=length)
4440
4440
  destination_folder = os.path.join(path, random_index)
4441
4441
  os.makedirs(destination_folder, exist_ok=exist_ok)
4442
4442
  return destination_folder, random_index
ararpy/smp/export.py CHANGED
@@ -23,7 +23,7 @@ from math import log
23
23
  from decimal import Decimal
24
24
 
25
25
  from ..calc import arr, isochron, spectra, err
26
- from ..calc.basic import get_random_digits, merge_dicts
26
+ from ..calc.basic import get_random_string, merge_dicts
27
27
  from ..calc.plot import get_axis_scale
28
28
  from . import basic, sample, consts
29
29
 
@@ -329,8 +329,8 @@ def getRectFromSpectra(data):
329
329
 
330
330
  def _get_additional_text_series(name):
331
331
  return {
332
- 'type': 'text', 'id': f'text-{name}-{get_random_digits()}',
333
- 'name': f'text-{name}-{get_random_digits()}', 'color': 'black',
332
+ 'type': 'text', 'id': f'text-{name}-{get_random_string()}',
333
+ 'name': f'text-{name}-{get_random_string()}', 'color': 'black',
334
334
  'text': "", 'size': title_size,
335
335
  'data': [[50, 50]], 'axis_index': 1,
336
336
  'h_align': "middle", 'v_align': "center",
@@ -353,7 +353,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
353
353
  X = x + list(reversed(x))
354
354
  Y = y1 + list(reversed(y2))
355
355
  series.append({
356
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
356
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}', 'name': f'line-{smp.name()}-{get_random_string()}',
357
357
  'color': color, 'fill_color': color, 'line_width': line_width, 'line_style': 'solid', 'z_index': 19,
358
358
  'data': np.transpose([X, Y]).tolist(),
359
359
  'line_caps': line_caps,
@@ -373,7 +373,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
373
373
  # spectra_fill_data = list(map(lambda each: [data[0][each - 1], min(data[1][each], data[2][each]), data[0][each + 1] - data[0][each], sigma * abs(data[1][each] - data[2][each])], selection))
374
374
  spectra_fill_data = getRectFromSpectra(plateau_data)
375
375
  series.append({
376
- 'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
376
+ 'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_string()}', 'name': f'rect-{smp.name()}-{get_random_string()}',
377
377
  'color': [colors_map['red'], colors_map['blue']][index], 'fill_color': [colors_map['red'], colors_map['blue']][index], 'line_style': 'none', 'z_index': 9,
378
378
  'data': spectra_fill_data, 'line_caps': 'none', 'fill': True,
379
379
  'axis_index': 0,
@@ -382,8 +382,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
382
382
  X = x + list(reversed(x))
383
383
  Y = y1 + list(reversed(y2))
384
384
  series.append({
385
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
386
- 'name': f'line-{smp.name()}-{get_random_digits()}',
385
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}',
386
+ 'name': f'line-{smp.name()}-{get_random_string()}',
387
387
  'color': [colors_map['red'], colors_map['blue']][index], 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
388
388
  'data': np.transpose([X, Y]).tolist(),
389
389
  'line_caps': line_caps,
@@ -392,8 +392,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
392
392
  })
393
393
  # plateau line
394
394
  series.append({
395
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
396
- 'name': f'line-{smp.name()}-{get_random_digits()}',
395
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}',
396
+ 'name': f'line-{smp.name()}-{get_random_string()}',
397
397
  'color': '#A9A9A9', 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
398
398
  'data': [[0, res['age']], [100, res['age']]],
399
399
  'line_caps': line_caps,
@@ -401,7 +401,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
401
401
  'axis_index': 0,
402
402
  })
403
403
  series.append({
404
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
404
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}', 'name': f'text-{smp.name()}-{get_random_string()}',
405
405
  'color': [colors_map['red'], colors_map['blue']][index], 'fill_color': [colors_map['red'], colors_map['blue']][index],
406
406
  'text': f"Corrected = {res['age']:.2f} ± {(sigma * res['s2']):.2f} {unit} ({sigma}s)<r>"
407
407
  f"MSWD = {res['MSWD']:.2f}, n = {res['Num']:.0f}<r>"
@@ -416,8 +416,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
416
416
  spe = smp.Info.results.age_spectra[index]
417
417
  if not np.isnan(res['age']):
418
418
  series.append({
419
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}',
420
- 'name': f'text-{smp.name()}-{get_random_digits()}',
419
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}',
420
+ 'name': f'text-{smp.name()}-{get_random_string()}',
421
421
  'color': color, 'fill_color': color,
422
422
  'text': f"WMPA = {spe['age']:.2f} ± {(sigma * spe['s2']):.2f} {unit} ({sigma}s)",
423
423
  'size': title_size,
@@ -431,7 +431,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
431
431
  tga = smp.Info.results.age_spectra['TGA']
432
432
  if not np.isnan(tga['age']):
433
433
  series.append({
434
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
434
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}', 'name': f'text-{smp.name()}-{get_random_string()}',
435
435
  'color': color, 'fill_color': color,
436
436
  'text': f"TGA = {tga['age']:.2f} ± {(sigma * tga['s2']):.2f} {unit} ({sigma}s)",
437
437
  'size': title_size,
@@ -455,7 +455,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
455
455
  # print(f"{min_index = }")
456
456
 
457
457
  series.append({
458
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
458
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}', 'name': f'text-{smp.name()}-{get_random_string()}',
459
459
  'color': color, 'fill_color': color,
460
460
  'text': f"Max. = {age[max_index, 0]:.2f} ± {(sigma * age[max_index, 2]):.2f} {unit}",
461
461
  'size': title_size,
@@ -466,7 +466,7 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
466
466
  })
467
467
 
468
468
  series.append({
469
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
469
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}', 'name': f'text-{smp.name()}-{get_random_string()}',
470
470
  'color': color, 'fill_color': color,
471
471
  'text': f"Min. = {age[min_index, 0]:.2f} ± {(sigma * age[min_index, 2]):.2f} {unit}",
472
472
  'size': title_size,
@@ -477,8 +477,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
477
477
  })
478
478
 
479
479
  series.append({
480
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
481
- 'name': f'line-{smp.name()}-{get_random_digits()}',
480
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}',
481
+ 'name': f'line-{smp.name()}-{get_random_string()}',
482
482
  'color': '#A9A9A9', 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
483
483
  'data': [[0, age[max_index, 0]], [100, age[max_index, 0]]],
484
484
  'line_caps': line_caps,
@@ -486,8 +486,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
486
486
  'axis_index': 0,
487
487
  })
488
488
  series.append({
489
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
490
- 'name': f'line-{smp.name()}-{get_random_digits()}',
489
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}',
490
+ 'name': f'line-{smp.name()}-{get_random_string()}',
491
491
  'color': '#A9A9A9', 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
492
492
  'data': [[0, age[min_index, 0]], [100, age[min_index, 0]]],
493
493
  'line_caps': line_caps,
@@ -496,8 +496,8 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
496
496
  })
497
497
  # title
498
498
  series.append({
499
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}',
500
- 'name': f'text-{smp.name()}-{get_random_digits()}', 'color': color,
499
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}',
500
+ 'name': f'text-{smp.name()}-{get_random_string()}', 'color': color,
501
501
  'text': smp.name(), 'size': title_size,
502
502
  'data': [[50, 95]], 'axis_index': 1, 'z_index': 29,
503
503
  'h_align': "middle", 'v_align': "center",
@@ -624,21 +624,21 @@ def _get_plot_data_inv_isochron_series(smp: sample, **options):
624
624
  set3 = smp.InvIsochronPlot.set3.data
625
625
  # set 1
626
626
  series.append({
627
- 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_digits()}', 'name': f'scatter-{smp.name()}-{get_random_digits()}',
627
+ 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_string()}', 'name': f'scatter-{smp.name()}-{get_random_string()}',
628
628
  'stroke_color': colors_map['red'], 'fill_color': colors_map['red80'], 'myType': 'scatter', 'size': marker_size, 'line_width': 0,
629
629
  'data': (data[[0, 2], :][:, set1]).transpose().tolist(),
630
630
  'axis_index': 0, 'z_index': 99
631
631
  })
632
632
  # set 2
633
633
  series.append({
634
- 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_digits()}', 'name': f'scatter-{smp.name()}-{get_random_digits()}',
634
+ 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_string()}', 'name': f'scatter-{smp.name()}-{get_random_string()}',
635
635
  'stroke_color': colors_map['blue'], 'fill_color': colors_map['blue80'], 'myType': 'scatter', 'size': marker_size, 'line_width': 0,
636
636
  'data': (data[[0, 2], :][:, set2]).transpose().tolist(),
637
637
  'axis_index': 0, 'z_index': 99
638
638
  })
639
639
  # set 3
640
640
  series.append({
641
- 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_digits()}', 'name': f'scatter-{smp.name()}-{get_random_digits()}',
641
+ 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_string()}', 'name': f'scatter-{smp.name()}-{get_random_string()}',
642
642
  'stroke_color': 'black', 'fill_color': 'white', 'myType': 'scatter', 'size': marker_size, 'line_width': 0,
643
643
  'data': (data[[0, 2], :][:, set3]).transpose().tolist(),
644
644
  'axis_index': 0, 'z_index': 0
@@ -653,14 +653,14 @@ def _get_plot_data_inv_isochron_series(smp: sample, **options):
653
653
  (float(xAxis[0]['extent'][1]), float(xAxis[0]['extent'][1]) * smp.Info.results.isochron['figure_3'][index]['m1'] + smp.Info.results.isochron['figure_3'][index]['k']),
654
654
  ]
655
655
  series.append({
656
- 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
656
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_string()}', 'name': f'line-{smp.name()}-{get_random_string()}',
657
657
  'color': [colors_map['red'], colors_map['blue']][index], 'fill_color': [colors_map['red'], colors_map['blue']][index],
658
658
  'line_width': 1, 'line_style': 'solid',
659
659
  'data': isochron_data,
660
660
  'axis_index': 0,
661
661
  })
662
662
  series.append({
663
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
663
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}', 'name': f'text-{smp.name()}-{get_random_string()}',
664
664
  'color': [colors_map['red'], colors_map['blue']][index], 'fill_color': [colors_map['red'], colors_map['blue']][index],
665
665
  'text': f"IIA = {smp.Info.results.isochron['figure_3'][index]['age']:.2f} ± {(sigma * smp.Info.results.isochron['figure_3'][index]['s2']):.2f} Ma ({sigma}s)<r>"
666
666
  f"(40Ar/36Ar)0 = {smp.Info.results.isochron['figure_3'][index]['initial']:.2f} ± {(sigma * smp.Info.results.isochron['figure_3'][index]['sinitial']):.2f}<r>"
@@ -673,8 +673,8 @@ def _get_plot_data_inv_isochron_series(smp: sample, **options):
673
673
  })
674
674
 
675
675
  series.append({
676
- 'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}',
677
- 'name': f'text-{smp.name()}-{get_random_digits()}', 'color': color,
676
+ 'type': 'text', 'id': f'text-{smp.name()}-{get_random_string()}',
677
+ 'name': f'text-{smp.name()}-{get_random_string()}', 'color': color,
678
678
  'text': smp.name(), 'size': title_size,
679
679
  'data': [[50, 95]], 'axis_index': 1,
680
680
  'h_align': "middle", 'v_align': "center",
@@ -695,7 +695,7 @@ def _get_plot_data_degas_pattern(smp: sample, **options):
695
695
  data = np.array([x, y])
696
696
  # set 1
697
697
  series.append({
698
- 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_digits()}', 'name': f'scatter-{smp.name()}-{get_random_digits()}',
698
+ 'type': 'series.scatter', 'id': f'scatter-{smp.name()}-{get_random_string()}', 'name': f'scatter-{smp.name()}-{get_random_string()}',
699
699
  'stroke_color': color, 'fill_color': 'white', 'myType': 'scatter', 'size': 4, 'line_width': 1,
700
700
  'data': data.transpose().tolist(), 'axis_index': 0, 'z_index': 99
701
701
  })
@@ -787,7 +787,7 @@ def _get_plot_data_degas_spectra_series(smp: sample, **options):
787
787
 
788
788
  # set 1
789
789
  series.append({
790
- 'type': 'rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
790
+ 'type': 'rect', 'id': f'rect-{smp.name()}-{get_random_string()}', 'name': f'rect-{smp.name()}-{get_random_string()}',
791
791
  'color': color, 'myType': 'rect', 'line_width': 1,
792
792
  'data': data.transpose().tolist(),
793
793
  'axis_index': 0, 'z_index': 99
@@ -844,13 +844,13 @@ def _get_plot_data_degas_curve_series(smp: sample, **options):
844
844
 
845
845
  # line
846
846
  series.append({
847
- 'type': 'line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
847
+ 'type': 'line', 'id': f'line-{smp.name()}-{get_random_string()}', 'name': f'line-{smp.name()}-{get_random_string()}',
848
848
  'color': color, 'myType': 'line', 'line_width': 1, 'line_style': 'solid',
849
849
  'data': np.array([x, released]).transpose().tolist(),
850
850
  'axis_index': 0, 'z_index': 99
851
851
  })
852
852
  series.append({
853
- 'type': 'line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
853
+ 'type': 'line', 'id': f'line-{smp.name()}-{get_random_string()}', 'name': f'line-{smp.name()}-{get_random_string()}',
854
854
  'color': color, 'myType': 'line', 'line_width': 1, 'line_style': 'solid',
855
855
  'data': np.array([x, remained]).transpose().tolist(),
856
856
  'axis_index': 0, 'z_index': 99
ararpy/smp/raw.py CHANGED
@@ -22,7 +22,7 @@ RawData = samples.RawData
22
22
  Sequence = samples.Sequence
23
23
 
24
24
 
25
- def to_raw(file_path: Union[str, List[str]], input_filter_path: Union[str, List[str]], **kwargs):
25
+ def to_raw(file_path: Union[str, List[str]], input_filter_path: Union[str, List[str]], file_name=None, **kwargs):
26
26
  """ Read raw data from files, can create raw data instance based on the given files
27
27
  Raw data will have the structure like:
28
28
  [
@@ -35,6 +35,7 @@ def to_raw(file_path: Union[str, List[str]], input_filter_path: Union[str, List[
35
35
  ----------
36
36
  file_path
37
37
  input_filter_path
38
+ file_name
38
39
  kwargs
39
40
 
40
41
  Returns
@@ -42,21 +43,16 @@ def to_raw(file_path: Union[str, List[str]], input_filter_path: Union[str, List[
42
43
 
43
44
  """
44
45
  if isinstance(file_path, list) and isinstance(input_filter_path, list):
45
- raw = concatenate([to_raw(file, input_filter_path[index]) for index, file in enumerate(file_path)])
46
+ raw = concatenate([to_raw(file, input_filter_path[index],
47
+ file_name[index] if isinstance(file_name, list) else file_name) for index, file in enumerate(file_path)])
46
48
  elif isinstance(file_path, str) and isinstance(input_filter_path, str):
47
49
  input_filter = read_params(input_filter_path)
48
- file_name = str(os.path.split(file_path)[-1]).split('.')[0]
49
- res = raw_file.open_file(file_path, input_filter)
50
+ file_name = str(os.path.split(file_path)[-1]).split('.')[0] if file_name is None else file_name
51
+ res = raw_file.open_file(file_path, input_filter, file_name)
50
52
  data = res.get('data', None)
51
53
  sequences = res.get('sequences', None)
52
54
  sequence_num = len(data) if data is not None else len(sequences)
53
- # default fitting method, all exponential
54
- # <option value=0>Linear</option>
55
- # <option value=1>Quadratic</option>
56
- # <option value=2>Exponential</option>
57
- # <option value=3>Power</option>
58
- # <option value=4>Average</option>
59
- fitting_method = [2, 0, 2, 2, 2]
55
+ fitting_method = [2, 0, 2, 2, 2] # 0 - linear, 1 - quadratic, 2 - exponential, 3 - power, 4 - average
60
56
  raw = RawData(name=file_name, data=data, isotopic_num=10, sequence_num=sequence_num, source=[file_path],
61
57
  sequence=sequences, unit=str(input_filter[30]), fitting_method=[*fitting_method])
62
58
  else:
ararpy/smp/sample.py CHANGED
@@ -109,67 +109,67 @@ ISOCHRON_TABLE_HEADERS = [
109
109
  TOTAL_PARAMS_HEADERS = [
110
110
  'Sequence', '', 'Mark', # 0-2
111
111
  '(\u2074\u2070Ar/\u00B3\u2076Ar)t', '%1\u03C3',
112
- '(\u2074\u2070Ar/\u00B3\u2076Ar)c', '%1\u03C3', # 2-5
112
+ '(\u2074\u2070Ar/\u00B3\u2076Ar)c', '%1\u03C3', # 3-6
113
113
  '(\u00B3\u2078Ar/\u00B3\u2076Ar)t', '%1\u03C3',
114
- '(\u00B3\u2078Ar/\u00B3\u2076Ar)c', '%1\u03C3', # 6-9
114
+ '(\u00B3\u2078Ar/\u00B3\u2076Ar)c', '%1\u03C3', # 7-10
115
115
  '(\u00B3\u2079Ar/\u00B3\u2077Ar)Ca', '%1\u03C3',
116
116
  '(\u00B3\u2078Ar/\u00B3\u2077Ar)Ca', '%1\u03C3',
117
- '(\u00B3\u2076Ar/\u00B3\u2077Ar)Ca', '%1\u03C3', # 10-15
117
+ '(\u00B3\u2076Ar/\u00B3\u2077Ar)Ca', '%1\u03C3', # 11-16
118
118
  '(\u2074\u2070Ar/\u00B3\u2079Ar)K', '%1\u03C3',
119
- '(\u00B3\u2078Ar/\u00B3\u2079Ar)K', '%1\u03C3', # 16-19
120
- '(\u00B3\u2076Ar/\u00B3\u2078Ar)Cl', '%1\u03C3', # 20-21
121
- 'K/Ca', '%1\u03C3', 'K/Cl', '%1\u03C3', 'Ca/Cl', '%1\u03C3', # 22-27
122
- 'Cycle Number', 'Irradiation Cycles', # 28-29
123
- 'Irradiation', 'duration', 'Irradiation Time', 'Experiment Time', # 30-33
124
- 'Storage Years', '', # 34-35
125
- 'Decay Constant \u2074\u2070K', '%1\u03C3', # 36-37
126
- 'Decay Constant \u2074\u2070K(EC)', '%1\u03C3', # 38-39
127
- 'Decay Constant \u2074\u2070K(\u03B2<sup>-</sup>)', '%1\u03C3', # 40-41
128
- 'Decay Constant \u2074\u2070K(\u03B2<sup>+</sup>)', '%1\u03C3', # 42-43
129
- 'Decay Constant \u00B3\u2079Ar', '%1\u03C3', # 44-45
130
- 'Decay Constant \u00B3\u2077Ar', '%1\u03C3', # 46-47
131
- 'Decay Constant \u00B3\u2076Cl', '%1\u03C3', # 48-49
132
- 'Decay Activity \u2074\u2070K', '%1\u03C3', # 50-51
133
- 'Decay Activity \u2074\u2070K(EC)', '%1\u03C3', # 52-53
134
- 'Decay Activity \u2074\u2070K(\u03B2<sup>-</sup>)', '%1\u03C3', # 54-55
135
- 'Decay Activity \u2074\u2070K(\u03B2<sup>+</sup>)', '%1\u03C3', # 56-57
136
- '\u00B3\u2076Cl/\u00B3\u2078Cl Productivity', '%1\u03C3', # 58-59
137
- 'Std Name', 'Std Age', '1\u03C3', '\u2074\u2070Ar%', '1\u03C3', 'K%', '1\u03C3', # 60-66
138
- '\u2074\u2070Ar<sup>*</sup>/K', '1\u03C3', # 67-68
139
- 'J', '%1\u03C3', 'MDF', '%1\u03C3', # 69-72
140
- 'Mass \u00B3\u2076Ar', '%1\u03C3', 'Mass \u00B3\u2077Ar', '%1\u03C3', # 73-76
141
- 'Mass \u00B3\u2078Ar', '%1\u03C3', 'Mass \u00B3\u2079Ar', '%1\u03C3', # 77-80
142
- 'Mass \u2074\u2070', '%1\u03C3', 'K Mass', '%1\u03C3', # 81-84
119
+ '(\u00B3\u2078Ar/\u00B3\u2079Ar)K', '%1\u03C3', # 17-20
120
+ '(\u00B3\u2076Ar/\u00B3\u2078Ar)Cl', '%1\u03C3', # 21-22
121
+ 'K/Ca', '%1\u03C3', 'K/Cl', '%1\u03C3', 'Ca/Cl', '%1\u03C3', # 23-28
122
+ 'Cycle Number', 'Irradiation Cycles', # 29-30
123
+ 'Irradiation', 'duration', 'Irradiation Time', 'Experiment Time', # 31-34
124
+ 'Storage Years', '', # 35-36
125
+ 'Decay Constant \u2074\u2070K', '%1\u03C3', # 37-38
126
+ 'Decay Constant \u2074\u2070K(EC)', '%1\u03C3', # 39-40
127
+ 'Decay Constant \u2074\u2070K(\u03B2<sup>-</sup>)', '%1\u03C3', # 41-42
128
+ 'Decay Constant \u2074\u2070K(\u03B2<sup>+</sup>)', '%1\u03C3', # 43-44
129
+ 'Decay Constant \u00B3\u2079Ar', '%1\u03C3', # 45-46
130
+ 'Decay Constant \u00B3\u2077Ar', '%1\u03C3', # 47-48
131
+ 'Decay Constant \u00B3\u2076Cl', '%1\u03C3', # 49-50
132
+ 'Decay Activity \u2074\u2070K', '%1\u03C3', # 51-52
133
+ 'Decay Activity \u2074\u2070K(EC)', '%1\u03C3', # 53-54
134
+ 'Decay Activity \u2074\u2070K(\u03B2<sup>-</sup>)', '%1\u03C3', # 55-56
135
+ 'Decay Activity \u2074\u2070K(\u03B2<sup>+</sup>)', '%1\u03C3', # 57-58
136
+ '\u00B3\u2076Cl/\u00B3\u2078Cl Productivity', '%1\u03C3', # 59-60
137
+ 'Std Name', 'Std Age', '1\u03C3', '\u2074\u2070Ar%', '1\u03C3', 'K%', '1\u03C3', # 61-67
138
+ '\u2074\u2070Ar<sup>*</sup>/K', '1\u03C3', # 68-69
139
+ 'J', '%1\u03C3', 'MDF', '%1\u03C3', # 70-73
140
+ 'Mass \u00B3\u2076Ar', '%1\u03C3', 'Mass \u00B3\u2077Ar', '%1\u03C3', # 74-77
141
+ 'Mass \u00B3\u2078Ar', '%1\u03C3', 'Mass \u00B3\u2079Ar', '%1\u03C3', # 78-81
142
+ 'Mass \u2074\u2070', '%1\u03C3', 'K Mass', '%1\u03C3', # 82-85
143
143
  'No', '%1\u03C3', 'Year', '%1\u03C3', '\u2074\u2070K/K', '%1\u03C3',
144
- '\u00B3\u2075Cl/\u00B3\u2077Cl', '%1\u03C3', 'HCl/Cl', '%1\u03C3', # 85-94
145
- '\u2074\u2070Ar/\u00B3\u2076Ar air', '%1\u03C3', # 95-96
146
- '\u00B3\u2078Ar/\u00B3\u2076Ar air', '%1\u03C3', # 97-98
147
- 'Isochron Fitting', 'Convergence', 'Iteration', 'Discrimination', # 99-102
148
- 'Not Zero', 'Corr Blank', 'Corr Discr', 'Corr \u00B3\u2077Ar Decay', # 103-106
149
- 'Corr \u00B3\u2079Ar Decay', # 107
150
- 'Ca Degassing', 'K Degassing', 'Cl Degassing', 'Trap Degassing', # 108-111
151
- 'Using Min Equation', # 112
144
+ '\u00B3\u2075Cl/\u00B3\u2077Cl', '%1\u03C3', 'HCl/Cl', '%1\u03C3', # 86-95
145
+ '\u2074\u2070Ar/\u00B3\u2076Ar air', '%1\u03C3', # 96-97
146
+ '\u00B3\u2078Ar/\u00B3\u2076Ar air', '%1\u03C3', # 98-99
147
+ 'Isochron Fitting', 'Convergence', 'Iteration', 'Discrimination', # 100-103
148
+ 'Not Zero', 'Corr Blank', 'Corr Discr', 'Corr \u00B3\u2077Ar Decay', # 104-107
149
+ 'Corr \u00B3\u2079Ar Decay', # 108
150
+ 'Ca Degassing', 'K Degassing', 'Cl Degassing', 'Trap Degassing', # 109-112
151
+ 'Using Min Equation', # 113
152
152
  # 'Recalibration', 'Using Std Age', 'Use Std Ratio', # 112-115 to be completed
153
- 'Apply Gain Corr to Blanks', # 113
154
- '', '', # 114-115
155
- 'Auto Plateau Method', # 116 the index includes sequence name and unit
156
- 'Initial Ratio Model', # 117
157
- 'Set1 initial Ratio', # 118
158
- '1\u03C3', # 119
159
- 'Set2 initial Ratio', # 120
160
- '1\u03C3', # 121
161
- 'Isotopic Errors', # 122
162
- 'Parameter Errors', # 123
163
- 'Plot Errors', # 124
164
- 'Heating Time (s)', # 125
165
- 'Heating Actual Temp (C)', # 126
166
- 'Heating AT 1\u03C3', # 127
167
- '36Ar Gain', '%1\u03C3', # 128-129
168
- '37Ar Gain', '%1\u03C3', # 130-131
169
- '38Ar Gain', '%1\u03C3', # 132-133
170
- '39Ar Gain', '%1\u03C3', # 134-135
171
- '40Ar Gain', '%1\u03C3', # 136-137
172
- 'Normalize Factor', '1\u03C3', # 138-139
153
+ 'Apply Gain Corr to Blanks', # 114
154
+ '', '', # 115-116
155
+ 'Auto Plateau Method', # 117 the index includes sequence name and unit
156
+ 'Initial Ratio Model', # 118
157
+ 'Set1 initial Ratio', # 119
158
+ '1\u03C3', # 120
159
+ 'Set2 initial Ratio', # 121
160
+ '1\u03C3', # 122
161
+ 'Isotopic Errors', # 123
162
+ 'Parameter Errors', # 124
163
+ 'Plot Errors', # 125
164
+ 'Heating Time (s)', # 126
165
+ 'Heating Actual Temp (C)', # 127
166
+ 'Heating AT 1\u03C3', # 128
167
+ '36Ar Gain', '%1\u03C3', # 129-130
168
+ '37Ar Gain', '%1\u03C3', # 131-132
169
+ '38Ar Gain', '%1\u03C3', # 133-134
170
+ '39Ar Gain', '%1\u03C3', # 135-136
171
+ '40Ar Gain', '%1\u03C3', # 137-138
172
+ 'Normalize Factor', '1\u03C3', # 139-140
173
173
  ]
174
174
 
175
175
  SAMPLE_INTERCEPT_SHORT_HEADERS = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ararpy
3
- Version: 0.1.34
3
+ Version: 0.1.36
4
4
  Summary: A project for Ar-Ar geochronology
5
5
  Home-page: https://github.com/wuyangchn/ararpy.git
6
6
  Author: Yang Wu
@@ -5,20 +5,20 @@ ararpy/Example - Show MDD results.py,sha256=YFkiQual60lyCClsfvivr4REY6waSYuomf0u
5
5
  ararpy/Example - Show all Kfs age spectra.py,sha256=1edPtBpFfS0lC7vLnLu34mDHt_xjbc8ptk6rZ--pf-I,12304
6
6
  ararpy/Example - Show random walk results.py,sha256=8WWvbAI7ySiMR-XwtFe5kTQihW3mcqzL3S7EUZdoxYo,15477
7
7
  ararpy/Example - Tc calculation.py,sha256=sD9pu3IaZ8mBV95rV2wOEhlQUexFNqBUoBqnNMdUBis,19617
8
- ararpy/__init__.py,sha256=lBvc-oTc0Js1bMrGGgXnmSRTJPqkJrqa-vOWCawlPXE,6857
8
+ ararpy/__init__.py,sha256=mVCcRD0R0FoAL0Q6u9paujSfaQ8YBP8A_FXELRXO5AI,6857
9
9
  ararpy/test.py,sha256=4F46-JJ1Ge12HGae0qO44Qc6kiEMHBgn2MsY_5LlHDo,3973
10
10
  ararpy/calc/__init__.py,sha256=kUjRuLE8TLuKOv3i976RnGJoEMj23QBZDu37LWs81U4,322
11
11
  ararpy/calc/age.py,sha256=WOZs70zXiBWDIEhXJLIaNiYTOFJNk0NDbH5e5zCbCks,5435
12
12
  ararpy/calc/arr.py,sha256=jD1Fd0Cj3xc7NqgnG4cp3VWQWxUlV0qCtPBZZokDG8o,15246
13
- ararpy/calc/basic.py,sha256=fVpdXmyqcIUU26nhU1bnI-YK4ZQ4Qqk24P3Yi9YwUwI,4187
13
+ ararpy/calc/basic.py,sha256=X8BoAjZgk52WfAbhOCUTEOkDIdSuz21gepN-Xke4oGA,4165
14
14
  ararpy/calc/corr.py,sha256=QDitvLf6y5IBpHtVEJfOUVjWSlIP9qJ4Jhluk9eDEDE,18801
15
15
  ararpy/calc/err.py,sha256=63LtprqjemlIb1QGDst4Ggcv5KMSDHdlAIL-nyQs1eA,2691
16
16
  ararpy/calc/histogram.py,sha256=0GVbDdsjd91KQ1sa2B7NtZ4KGo0XpRIJapgIrzAwQUo,5777
17
17
  ararpy/calc/isochron.py,sha256=ej9G2e68k6yszonWHsLcEubh3TA7eh1upTJP_X0ttAA,5726
18
18
  ararpy/calc/jvalue.py,sha256=OL5zPYU8Pac-wOxUWPCgu3onh2n01xDnhpi2mlUsjJM,1146
19
19
  ararpy/calc/plot.py,sha256=Hdtb-q18xYC8ZJeDKGRauCSbj4_7e6Z8HQs9aYgfvao,2139
20
- ararpy/calc/raw_funcs.py,sha256=GJ0VW0sc2qPIVp5jSDmPP1ClOoYRa_cc35ye7QDYOiI,2744
21
- ararpy/calc/regression.py,sha256=lWMoZkovtj5OEYM8eT0FcMsGrDIkKm9rsG45ru3IVuk,39798
20
+ ararpy/calc/raw_funcs.py,sha256=Rza1nIBQCOlJK_X0XvzmJqNG_byuaZxotNbdM84M-gI,2736
21
+ ararpy/calc/regression.py,sha256=3L6caRhAptWY7o3EGGk5sfB_C471crSUcwOQRrkLS7Q,40255
22
22
  ararpy/calc/spectra.py,sha256=_Q23eP9necHlaCoHf3_UfW1N3JmVZj5rcWFro8GS-CA,1995
23
23
  ararpy/examples/022_VU124-M11a.ahd,sha256=3m0Gd-ZObou3KsnRNFMf77QwzT1Uz3nu3vA33Sqeyng,5414
24
24
  ararpy/examples/20WHA0103.age,sha256=cT-a4d7Wt77aotx6v0G47vulY_TZIcZUcaVHB3pqTPM,380416
@@ -41,10 +41,10 @@ ararpy/examples/raw_example.xls,sha256=ftcSiXRx_7nYnbqJVma1Yl3Yr_iuceAWlEjhJwlAv
41
41
  ararpy/examples/sample-default.smp,sha256=YNkoQGgPrsL_fXS7ZHxfRtLQWekCDqT9czS6vBScImk,432
42
42
  ararpy/files/__init__.py,sha256=l5B5ZQ01WdtvjjN0aMkyAFNgpwANdM_1I0tQbqnRuEY,69
43
43
  ararpy/files/arr_file.py,sha256=pD5MxkAydL7cNq2wmKFUaOU4jHhc3MzTYrwbxZ3f46w,881
44
- ararpy/files/basic.py,sha256=mGYP7QJBtyasVAYcwT0a9k6tPlcStxASddgzbaxYKkE,2105
45
- ararpy/files/calc_file.py,sha256=RrfMo7Q8-4pBMQdpGY0guF52aSqAk8LEjq2NE3toL2w,28734
44
+ ararpy/files/basic.py,sha256=k2GXgZjhqSmKvpXQLjsXDksS_ZLvqD7AWW54fXnYvTI,1228
45
+ ararpy/files/calc_file.py,sha256=bapIVd3QQBprdMdfxNbY8TJH1UkfphIUtim3ONypc3I,28779
46
46
  ararpy/files/new_file.py,sha256=efblARIBROVLWS2w3-98BxLX5VZ8grRpiTkJFtf_rAk,214
47
- ararpy/files/raw_file.py,sha256=3vGinbUyTWyQ57jMFIuckrPkN0TrNe1hqKCOAWaj70A,21854
47
+ ararpy/files/raw_file.py,sha256=IwU_1Urrk0FjOt3kUuOaYjBBFozhCVAdsP6STxRia-o,19778
48
48
  ararpy/files/xls.py,sha256=DVcZ_yRnc19p-m4leGGjt-YPDpSa2udYKmGyrM0qub0,640
49
49
  ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py,sha256=baDM437tu6hsPv0uYfod0TREXlPd6kvMBFT1S9ZZlkk,3024
50
50
  ararpy/smp/__init__.py,sha256=k6_fa27UJsQK7K7oC5GYlwMo6l0Xd8af3QtOrZz2XJk,478
@@ -52,22 +52,22 @@ ararpy/smp/basic.py,sha256=PMvlSoToY8CJEORRrhEo4rYM2-VfSmjg0IuDpGFOGUM,24899
52
52
  ararpy/smp/calculation.py,sha256=LCFJWjLVLEKEQ5b7RFUIxsMahEzgLdodW4kCYXV5Z34,2919
53
53
  ararpy/smp/consts.py,sha256=XIdjdz8cYxspG2jMnoItdlUsxr3hKbNFJjMZJh1bpzw,393
54
54
  ararpy/smp/corr.py,sha256=U5K1Vld55IHea_fZ7EEY_8dkvjp0f6OhpdSxf7b9WGY,26551
55
- ararpy/smp/diffusion_funcs.py,sha256=q0kl-AYx7TYeWc1kruKLOl4U4JosIuf1uNmkps11eUs,186694
56
- ararpy/smp/export.py,sha256=mWnnNg7DYIxcxyqeGXAWUS7faJmO7UHwnMVPX33_aLg,120638
55
+ ararpy/smp/diffusion_funcs.py,sha256=NC5T0GYXCidgVqSy3BGmIroLWzQhyzYb5x4gg_L0dJ4,186694
56
+ ararpy/smp/export.py,sha256=yAUlTvFBo2U703hZ79NlAcTYC7QZGXHUn_IRP7sQuRA,120638
57
57
  ararpy/smp/info.py,sha256=iKUELm-BuUduDlJKC1d8tKKNHbwwbNmhUg2pi6bcBvA,489
58
58
  ararpy/smp/initial.py,sha256=QGk7vh7JyVqalwnpd9VudQoX2Z9tyWzfIIw_cL5Sok0,18031
59
59
  ararpy/smp/json.py,sha256=BTZCjVN0aj9epc700nwkYEYMKN2lHBYo-pLmtnz5oHY,2300
60
60
  ararpy/smp/plots.py,sha256=fFuJxoFcnvGSysjdEdrbW_ITpukt0iGs2K25gshIKNU,33594
61
- ararpy/smp/raw.py,sha256=51n-rrbW2FqeZHQyevuG7iObPLGvIBzTe414QDVM1FE,6523
62
- ararpy/smp/sample.py,sha256=iaFjG0S0GuNwbLeUFpzEFIbqa0oX0KekRZuLJd2mSCQ,58903
61
+ ararpy/smp/raw.py,sha256=SeKaNZZRWjiE_7fMHwn1IgQxX17t8mNFYMnRiimMLRU,6474
62
+ ararpy/smp/sample.py,sha256=HW2JIZZcNslYVQupAqlfLEKXBWdYol5Xpx0PDdPG44o,58905
63
63
  ararpy/smp/style.py,sha256=Q8f6SsqnxmzocxpZUyGDiNanVW0ijCZpxHKh19UIeoM,7800
64
64
  ararpy/smp/table.py,sha256=Vq3GK9aslEuBhmvlQoUHjcs71Q6raSFYqd5veB1L9mk,6887
65
65
  ararpy/thermo/__init__.py,sha256=6VBuqTRFl403PVqOuMkVrut0nKaQsAosBmfW91X1dMg,263
66
66
  ararpy/thermo/arrhenius.py,sha256=Ass1ichHfqIAtpv8eLlgrUc1UOb3Urh1qzr1E3gLB4U,233
67
67
  ararpy/thermo/atomic_level_random_walk.py,sha256=ncw9DtxRfS6zlQbLVLNX7WNoO9sX_nSomwAsTH0_O3k,25910
68
68
  ararpy/thermo/basic.py,sha256=JJRZbYmvXlpRAV2FeFPwLhrig4ZhNQmJnWqgOjo-1YQ,11508
69
- ararpy-0.1.34.dist-info/licenses/LICENSE,sha256=cvG5t_C1qY_zUyJI7sNOa7gCArdngNPaOrfujl2LYuc,1085
70
- ararpy-0.1.34.dist-info/METADATA,sha256=ZOHvn2PDOQXK_B4Dy0XlzzY0KoxaXraCH-I8u67YQmM,24516
71
- ararpy-0.1.34.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
- ararpy-0.1.34.dist-info/top_level.txt,sha256=9iTpsPCYuRYq09yQTk9d2lqB8JtTEOmbN-IcGB-K3vY,7
73
- ararpy-0.1.34.dist-info/RECORD,,
69
+ ararpy-0.1.36.dist-info/licenses/LICENSE,sha256=cvG5t_C1qY_zUyJI7sNOa7gCArdngNPaOrfujl2LYuc,1085
70
+ ararpy-0.1.36.dist-info/METADATA,sha256=z82ivzCqiDnDN8TjnGAk1EmL4-C_YLhhY99WFbLnw3Y,24516
71
+ ararpy-0.1.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
+ ararpy-0.1.36.dist-info/top_level.txt,sha256=9iTpsPCYuRYq09yQTk9d2lqB8JtTEOmbN-IcGB-K3vY,7
73
+ ararpy-0.1.36.dist-info/RECORD,,