ararpy 0.0.24__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ararpy/__init__.py CHANGED
@@ -29,10 +29,11 @@ from_full = smp.initial.from_full_files
29
29
  from_raw = smp.initial.from_raw_files
30
30
  from_empty = smp.initial.from_empty
31
31
 
32
+ save = lambda _smp, _path: files.arr_file.save(_path, _smp)
33
+
32
34
  """ Classes """
33
35
 
34
36
  Sample = smp.Sample
35
- Info = smp.Info
36
37
  Table = smp.Table
37
38
  Plot = smp.Plot
38
39
  Set = smp.Set
@@ -51,7 +52,7 @@ ArArData.to_list = lambda _ad: _ad.data
51
52
 
52
53
  """ Sample Class Methods """
53
54
 
54
- Sample.name = lambda _smp: _smp.Info.sample.name
55
+ Sample.name = smp.info.name
55
56
  Sample.doi = lambda _smp: _smp.Doi
56
57
  Sample.sample = lambda _smp: _smp.Info.sample
57
58
  Sample.researcher = lambda _smp: _smp.Info.researcher
@@ -115,9 +116,6 @@ Sample.plot_cl_3 = lambda _smp: smp.calculation.recalculate(
115
116
  Sample.plot_3D = lambda _smp: smp.calculation.recalculate(
116
117
  _smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_7'])
117
118
 
118
- # export functions
119
- Sample.to_pdf = lambda _smp, file_path, figure: smp.export.to_pdf(file_path, figure, _smp)
120
-
121
119
  Sample.show_data = lambda _smp: \
122
120
  f"Sample Name: \n\t{_smp.name()}\n" \
123
121
  f"Doi: \n\t{_smp.doi()}\n" \
ararpy/calc/age.py CHANGED
@@ -111,9 +111,9 @@ def calc_age_min(F, sF, **kwargs) -> tuple:
111
111
 
112
112
  # change to Ma
113
113
  # analytical error, error of 40Ar/39Ar only
114
- s1 = np.sqrt((V * KK * R / (R * XX)) ** 2 * sR_2 ** 2) / 1000000
114
+ s1 = np.sqrt((V * KK * BB / XX) ** 2 * sR_2 ** 2) / 1000000
115
115
  # internal error, errors of 40Ar/39Ar and J value
116
- s2 = np.sqrt((V * KK * R / (R * XX)) ** 2 * sR_1 ** 2) / 1000000
116
+ s2 = np.sqrt((V * KK * BB / XX) ** 2 * sR_1 ** 2) / 1000000
117
117
  # total external error
118
118
  s3 = np.sqrt(e1 + e2 + e3 + e4 + e5 + e6 + e7 + e8 + e9) / 1000000
119
119
  age = k0 / 1000000
ararpy/calc/arr.py CHANGED
@@ -40,15 +40,13 @@ def mul(*args):
40
40
  -------
41
41
  2D list, [values, errors]
42
42
  """
43
- n = np.shape([args])[-1]
44
- k0, k1 = [1] * n, [0] * n
45
- k2 = []
46
- for i in range(n):
47
- for arg in args:
48
- k0[i] = np.multiply(k0[i], arg[0][i])
49
- k1[i] = k1[i] + np.divide(arg[1][i] ** 2, arg[0][i] ** 2)
50
- k2.append(abs(k0[i]) * k1[i] ** .5)
51
- return [k0, k2]
43
+ v = np.array(args)
44
+ res = np.zeros([2, v.shape[-1]], dtype=np.float64)
45
+ for i in range(v.shape[-1]):
46
+ res[0, i] = np.prod(v[:, 0, i])
47
+ res[1, i] = err.mul(*v[:, :, i])
48
+
49
+ return res
52
50
 
53
51
 
54
52
  def div(a, b):
@@ -128,7 +126,7 @@ def sub(*args):
128
126
  -------
129
127
 
130
128
  """
131
- args = np.array(args)
129
+ args = np.array(args, dtype=np.float64)
132
130
  args[np.isnan(args)] = 0
133
131
  n = np.shape(args)[-1]
134
132
  k0, k1 = [], []
@@ -213,14 +211,15 @@ def partial(a: list, rows=None, cols=None):
213
211
  except ValueError:
214
212
  # ValueError, the requested array has an inhomogeneous shape
215
213
  return partial(homo(a), rows=rows, cols=cols)
214
+ default_col = [np.nan for i in range(n)]
216
215
  if rows is None:
217
216
  rows = list(range(n))
218
217
  if cols is None:
219
218
  cols = list(range(m))
220
219
  if isinstance(cols, list):
221
- res = [a[i] for i in cols]
220
+ res = [a[i] if i != -1 else default_col for i in cols]
222
221
  elif isinstance(cols, int):
223
- res = a[cols]
222
+ res = a[cols] if cols != -1 else default_col
224
223
  if isinstance(rows, list):
225
224
  if isinstance(cols, list):
226
225
  res = [[i[j] for j in rows] for i in res]
@@ -493,7 +492,7 @@ def transpose(obj, ignore: bool = True):
493
492
  Parameters
494
493
  ----------
495
494
  obj : two dimensional list-like object
496
- ignore : return obj if ingore error is true
495
+ ignore : return obj if ignore error is true
497
496
 
498
497
  Returns
499
498
  -------
@@ -506,20 +505,22 @@ def transpose(obj, ignore: bool = True):
506
505
  m, n = np.shape(obj)
507
506
  return [[obj[i][j] for i in range(m)] for j in range(n)]
508
507
  except (ValueError, TypeError):
509
- # print(traceback.format_exc())
508
+ print(traceback.format_exc())
510
509
  if ignore:
511
510
  return obj
511
+ else:
512
+ raise ValueError
512
513
 
513
514
 
514
515
  def get_item(obj: list, loc: (list, tuple, int), default: Union[str, int, float, bool] = None,
515
- based: int = 0) -> Union[str, int, float, bool]:
516
+ base: Union[int, tuple, list] = 0) -> Union[str, int, float, bool]:
516
517
  """ Get item from a n-dimension list
517
518
  Parameters
518
519
  ----------
519
520
  obj
520
521
  loc
521
522
  default
522
- based
523
+ base
523
524
 
524
525
  Returns
525
526
  -------
@@ -528,13 +529,16 @@ def get_item(obj: list, loc: (list, tuple, int), default: Union[str, int, float,
528
529
  if not isinstance(obj, list):
529
530
  raise TypeError
530
531
  if isinstance(loc, int):
531
- return obj[loc - based if loc - based >= 0 else 0]
532
+ loc = [loc]
533
+ if isinstance(base, int):
534
+ base = [base for i in range(len(loc))]
532
535
  if len(loc) == 1:
533
- return obj[loc[0] - based if loc[0] - based >= 0 else 0]
534
- return get_item(obj[loc[0] - based if loc[0] - based >= 0 else 0], loc[1:], based=based)
536
+ return obj[loc[0] - base[0]] if loc[0] - base[0] >= 0 else ""
537
+ if loc[0] - base[0] < 0:
538
+ raise IndexError
539
+ return get_item(obj[loc[0] - base[0]], loc[1:], base=base[1:], default=default)
535
540
  except (IndexError, TypeError, ValueError):
536
- if default is not None:
537
- return default
541
+ return default
538
542
  raise ValueError(f"Cannot get a item from {obj = }, {loc = }")
539
543
 
540
544
 
ararpy/calc/basic.py CHANGED
@@ -48,6 +48,8 @@ def merge_dicts(a: dict, b: dict):
48
48
  """
49
49
  res = copy.deepcopy(a)
50
50
  for key, val in b.items():
51
+ if key not in res.keys() and key.isnumeric():
52
+ key = int(key)
51
53
  if key not in res.keys():
52
54
  res[key] = val
53
55
  elif isinstance(val, dict):
@@ -55,3 +57,24 @@ def merge_dicts(a: dict, b: dict):
55
57
  else:
56
58
  continue
57
59
  return res
60
+
61
+
62
+ def update_dicts(a: dict, b: dict):
63
+ """
64
+ a and b, two dictionary. Return updated a
65
+ For example:
66
+ a = {"1": 1, "2": {"1": 1, "2": 2, "3": 3, "5": {}, "6": [1, 2]}}
67
+ b = {"1": 'b', "2": {"1": 'b', "2": 'b', "3": 'b', "4": 'b', "5": {"1": 'b'}, "6": [1, 2, 3]}}
68
+ Will return {'1': 'b', ...}
69
+ """
70
+ res = copy.deepcopy(a)
71
+ for key, val in b.items():
72
+ if key not in res.keys() and key.isnumeric():
73
+ key = int(key)
74
+ if key not in res.keys():
75
+ res[key] = val
76
+ elif isinstance(val, dict):
77
+ res[key] = update_dicts(res[key], val)
78
+ else:
79
+ res[key] = val
80
+ return res
ararpy/calc/corr.py CHANGED
@@ -51,7 +51,7 @@ def mdf(rm: float, srm: float, m1: float, m2: float, ra: float = 298.56,
51
51
  if isAapkop:
52
52
  # line
53
53
  k1 = (ra / rm + delta_m - 1) / delta_m # A.A.P.Koppers
54
- k2 = arr.div(((ra / rm + delta_m - 1), arr.div((ra, sra), (rm, srm))), (delta_m, sdelta_m))
54
+ k2 = err.div(((ra / rm + delta_m - 1), err.div((ra, sra), (rm, srm))), (delta_m, sdelta_m))
55
55
  # exp
56
56
  try:
57
57
  k3 = (np.log(ra / rm) / np.log(ratio_m)) * (1 / m1) + 1 # A.A.P.Koppers
@@ -230,7 +230,7 @@ def get_irradiation_datetime_by_string(datetime_str: str):
230
230
 
231
231
  """
232
232
  res = []
233
- if datetime_str == '' or datetime_str is None:
233
+ if datetime_str == '' or datetime_str is None or (isinstance(datetime_str, float) and np.isnan(datetime_str)):
234
234
  return ['', 0]
235
235
  cycles = datetime_str.split('S')
236
236
  for cycle in cycles:
@@ -252,8 +252,8 @@ def get_method_fitting_law_by_name(method_str: str):
252
252
  res = [False] * 3
253
253
  try:
254
254
  res[['Lin', 'Exp', 'Pow'].index(method_str.capitalize()[:3])] = True
255
- except ValueError:
256
- res[0] = True
255
+ except (ValueError, AttributeError):
256
+ pass
257
257
  return res
258
258
 
259
259
 
@@ -379,9 +379,11 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
379
379
  _ar36cl = (_ar36res - _ar38res / R38v36a[i]) / (1 - 1 / (R36v38clp[i] * (1 - exp(-1 * L36cl[i] * stand_time_year)) * R38v36a[i]))
380
380
  _ar36a = _ar36res - _ar36cl
381
381
  _ar40r = (ar40m[i] - ar40b[i]) * P40Mdf - _ar36a * R40v36a[i] - _ar39k * R40v39k[i]
382
+ _ar40ar = (ar40m[i] - ar40b[i]) * P40Mdf - _ar39k * R40v39k[i]
382
383
  _f = _ar40r / _ar39k
383
384
  i += 1
384
- yield _f, _ar36, _ar37, _ar38, _ar39, _ar40, _ar36a, _ar37ca, _ar39k, _ar40r, _ar36cl
385
+ # yield _f, _ar36, _ar37, _ar38, _ar39, _ar40, _ar36a, _ar37ca, _ar39k, _ar40r, _ar36cl
386
+ yield _f, _ar36a, _ar39k, _ar40ar
385
387
 
386
388
  simulation = do_simulation()
387
389
  F = []
@@ -396,18 +398,27 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
396
398
  ar39k = []
397
399
  ar40r = []
398
400
  ar36cl = []
401
+
402
+ nor_x = []
403
+ nor_y = []
404
+ inv_x = []
405
+ inv_y = []
399
406
  for each in simulation:
400
407
  F.append(each[0])
401
- ar36.append(each[1])
402
- ar37.append(each[2])
403
- ar38.append(each[3])
404
- ar39.append(each[4])
405
- ar40.append(each[5])
406
- ar36a.append(each[6])
407
- ar37ca.append(each[7])
408
- ar39k.append(each[8])
409
- ar40r.append(each[9])
410
- ar36cl.append(each[10])
408
+ nor_x.append(each[2] / each[1])
409
+ nor_y.append(each[3] / each[1])
410
+ inv_x.append(each[2] / each[3])
411
+ inv_y.append(each[1] / each[3])
412
+ # ar36.append(each[1])
413
+ # ar37.append(each[2])
414
+ # ar38.append(each[3])
415
+ # ar39.append(each[4])
416
+ # ar40.append(each[5])
417
+ # ar36a.append(each[6])
418
+ # ar37ca.append(each[7])
419
+ # ar39k.append(each[8])
420
+ # ar40r.append(each[9])
421
+ # ar36cl.append(each[10])
411
422
 
412
423
  # print("F = {0} ± {1}".format(np.mean(F), np.std(F)))
413
424
  #
@@ -443,8 +454,12 @@ def Monte_Carlo_F(ar40m: Tuple[float, float], ar39m: Tuple[float, float], ar38m:
443
454
  # f.writelines("\n".join([str(i) for i in ar39k]))
444
455
  # with open("ar40r.txt", 'w') as f: # save serialized json data to a readable text
445
456
  # f.writelines("\n".join([str(i) for i in ar40r]))
446
-
447
- return np.mean(F), np.std(F)
457
+ # F, sF,
458
+ return np.mean(F), np.std(F), \
459
+ np.mean(nor_x), np.std(nor_x), np.mean(nor_y), np.std(nor_y), \
460
+ np.cov(nor_x, nor_y)[0][1] / (np.std(nor_x) * np.std(nor_y)), \
461
+ np.mean(inv_x), np.std(inv_x), np.mean(inv_y), np.std(inv_y), \
462
+ np.cov(inv_x, inv_y)[0][1] / (np.std(inv_x) * np.std(inv_y))
448
463
 
449
464
 
450
465
 
ararpy/calc/err.py CHANGED
@@ -36,8 +36,15 @@ def mul(*args: tuple) -> float:
36
36
  Returns: float, propagated error
37
37
 
38
38
  """
39
- k = abs(np.prod([arg[0] for arg in args])) * sum([np.divide(arg[1] ** 2, arg[0] ** 2) for arg in args]) ** .5
40
- return k
39
+ # k = abs(np.prod([arg[0] for arg in args])) * sum([np.divide(arg[1] ** 2, arg[0] ** 2) for arg in args]) ** .5
40
+ v = np.ma.array(args, mask=False)
41
+ k = 0
42
+ for i in range(v.shape[0]):
43
+ v.mask[i, 0] = True
44
+ k += np.prod(v[:, 0]) ** 2 * v[i, 1] ** 2
45
+ v.mask[i, 0] = False
46
+
47
+ return np.sqrt(k)
41
48
 
42
49
 
43
50
  def rec(a: tuple) -> float:
ararpy/calc/jvalue.py CHANGED
@@ -12,7 +12,7 @@
12
12
  import numpy as np
13
13
 
14
14
 
15
- def j_value(age: float, sage: float, r: float, sr: float, f: float, rsf: float):
15
+ def j_value(age, sage, r, sr, f, rsf):
16
16
  """ Calculate J value according to the given age and the ratio
17
17
 
18
18
  Parameters
@@ -28,11 +28,12 @@ def j_value(age: float, sage: float, r: float, sr: float, f: float, rsf: float):
28
28
  -------
29
29
  tuple of J value and error
30
30
  """
31
+ age, sage, r, sr, f, rsf = np.array([age, sage, r, sr, f, rsf])
31
32
  f = f * 1000000 # exchange to unit of Ma
32
33
  rsf = f * rsf / 100 # exchange to absolute error
33
34
  k0 = (np.exp(f * age) - 1) / r
34
35
  v1 = rsf ** 2 * (age * np.exp(f * age) / r) ** 2
35
36
  v2 = sage ** 2 * (f * np.exp(f * age) / r) ** 2
36
37
  v3 = sr ** 2 * ((1 - np.exp(f * age)) / r ** 2) ** 2
37
- k1 = pow(v1 + v2 + v3, 0.5)
38
+ k1 = np.sqrt(v1 + v2 + v3)
38
39
  return k0, k1
ararpy/calc/raw_funcs.py CHANGED
@@ -33,7 +33,6 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
33
33
  # unselected = []
34
34
  # linesData = []
35
35
  linesResults, regCoeffs = [], []
36
- x, y = transpose(points_data)
37
36
  # un_x = transpose(unselected)[0] if is_twoD(unselected) else []
38
37
  reg_handler = [
39
38
  regression.linest, regression.quadratic, regression.exponential,
@@ -42,6 +41,7 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
42
41
  # lines_x = [(max(x + un_x) - 0) / size * i for i in range(size + 1)]
43
42
  for i in range(len(reg_handler)):
44
43
  try:
44
+ x, y = transpose(points_data, ignore=False)
45
45
  res = reg_handler[i](a0=y, a1=x)
46
46
  # line_data = transpose([lines_x, res[7](lines_x)])
47
47
  line_results = res[0:4]
ararpy/calc/regression.py CHANGED
@@ -18,9 +18,13 @@ import pandas as pd
18
18
  from scipy.stats import distributions
19
19
  from scipy.optimize import fsolve
20
20
  import warnings
21
+ from scipy.optimize import minimize
21
22
  warnings.simplefilter(action="ignore", category=RuntimeWarning)
22
23
 
23
24
 
25
+ """ regression functions for isochrons """
26
+
27
+
24
28
  def york2(x: list, sx: list, y: list, sy: list, ri: list, f: int = 1,
25
29
  convergence: float = 0.001, iteration: int = 100):
26
30
  """
@@ -107,7 +111,7 @@ def york2(x: list, sx: list, y: list, sy: list, ri: list, f: int = 1,
107
111
  chi_square = mswd * (n - 2)
108
112
  p_value = distributions.chi2.sf(chi_square, n - 2)
109
113
  # average error of S
110
- err_s = lambda m, b: list(map(lambda Zi, Yi, Xi: (1 / Zi) ** 1./2. / abs(Yi - m * Xi - b), Z(m, b), y, x))
114
+ err_s = lambda m, b: list(map(lambda Zi, Yi, Xi: (1 / Zi) ** (1./2.) / abs(Yi - m * Xi - b), Z(m, b), y, x))
111
115
  avg_err_s = sum(err_s(m, b)) / len(x) * 100
112
116
 
113
117
  # print('----------------------------------------------------------------')
@@ -402,6 +406,62 @@ def wtd_3D_regression_df(data: pd.DataFrame, f: int = 1, convergence: float = 0.
402
406
  return res
403
407
 
404
408
 
409
+ def max_likelihood(x: list, sx: list, y: list, sy: list, ri: list):
410
+ """
411
+ Parameters
412
+ ----------
413
+ x
414
+ sx
415
+ y
416
+ sy
417
+ ri
418
+
419
+ Returns
420
+ -------
421
+
422
+ """
423
+
424
+ # 定义线性模型
425
+ def linear_model(params, _x):
426
+ return params[0] * _x + params[1]
427
+
428
+ # 定义负对数似然函数
429
+ def negative_log_likelihood(params, _x, _y):
430
+ predicted_y = linear_model(params, _x)
431
+ # 使用高斯误差进行似然计算
432
+ errors = predicted_y - _y
433
+ likelihood = np.sum(-0.5 * np.log(2 * np.pi) - 0.5 * errors ** 2)
434
+ return -likelihood
435
+
436
+ initial = linest(y, x)[5]
437
+ res = minimize(negative_log_likelihood, initial, args=(np.array(x), np.array(y)))
438
+ slope, intercept = res.x
439
+ return intercept, 0, slope, 0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan
440
+
441
+
442
+ def olst(x: list, sx: list, y: list, sy: list, ri: list):
443
+ """
444
+ Parameters
445
+ ----------
446
+ x
447
+ sx
448
+ y
449
+ sy
450
+ ri
451
+
452
+ Returns
453
+ -------
454
+
455
+ """
456
+
457
+ res = linest(y, x)
458
+ # b, sb, m, sm, mswd, m - last m, Di, k, r2,
459
+ return *res[:2], res[5][1], res[6][1], np.nan, np.nan, np.nan, np.nan, res[3], np.nan, np.nan, np.nan
460
+
461
+
462
+ """ regression functions for raw data """
463
+
464
+
405
465
  def linest(a0: list, a1: list, *args):
406
466
  """
407
467
  Parameters
@@ -449,7 +509,7 @@ def linest(a0: list, a1: list, *args):
449
509
  args = [[1] * len(args[0]), *args]
450
510
  return [sum([beta[i] * args[i][j] for i in range(len(beta))]) for j in range(len(args[0]))]
451
511
 
452
- return beta[0], se_beta[0], rse_beta[0] * 100, r2, 'mswd', beta, se_beta, get_adjusted_y, m_ssresid
512
+ return beta[0], se_beta[0], rse_beta[0] * 100, r2, m_ssresid, beta, se_beta, get_adjusted_y, m_ssresid
453
513
 
454
514
 
455
515
  def average(a0: list, a1=None):
@@ -695,10 +755,10 @@ def polynomial(a0: list, a1: list, degree: int = 5):
695
755
  """
696
756
  # y = b + m1 * x + m2 * x ^ 2 + ... + m[n] * x ^ n
697
757
  k = list(linest(a0, *[[j ** (i + 1) for j in a1] for i in range(degree)]))
698
- b, seb, rseb, r2, mswd, [b, m], [seb, sem] = k[0:7]
758
+ b, seb, rseb, r2, mswd, beta, se_beta = k[0:7]
699
759
 
700
760
  def get_adjusted_y(x: list):
701
- return [b + sum([m * _x ** (i + 1) for i in range(degree)]) for _x in x]
761
+ return [sum([beta[i] * _x ** i for i in range(degree + 1)]) for _x in x]
702
762
 
703
763
  k[7] = get_adjusted_y
704
764
 
Binary file
Binary file
ararpy/files/basic.py CHANGED
@@ -21,8 +21,8 @@ def upload(file, media_dir):
21
21
  name, suffix = os.path.splitext(file.name)
22
22
  if suffix.lower() not in [
23
23
  '.xls', '.age', '.xlsx', '.arr', '.jpg', '.png', '.txt',
24
- '.log', '.seq', '.json', '.ahd']:
25
- raise TypeError("Wrong File")
24
+ '.log', '.seq', '.json', '.ahd', '.csv']:
25
+ raise TypeError(f"The imported file is not supported: {suffix}")
26
26
  web_file_path = os.path.join(media_dir, file.name)
27
27
  with open(web_file_path, 'wb') as f:
28
28
  for chunk in file.chunks():
ararpy/files/calc_file.py CHANGED
@@ -35,8 +35,7 @@ def read_calc_file(file_path: str):
35
35
  try:
36
36
  with open(file_path, 'rb') as file:
37
37
  office_file = msoffcrypto.OfficeFile(file)
38
- office_file.load_key(password=bytes.fromhex(
39
- open(os.path.join(os.path.dirname(__file__), '../../conf.txt'), "r").read()).decode())
38
+ office_file.load_key(password=bytes.fromhex('6161706b6f70').decode())
40
39
  office_file.decrypt(open(decrypt_file_path, 'wb'))
41
40
  wb = open_workbook(decrypt_file_path)
42
41
  worksheets = wb.sheet_names()