ararpy 0.1.199__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. ararpy/Example - Check arr.py +52 -0
  2. ararpy/Example - Granite Cooling History.py +411 -0
  3. ararpy/Example - Plot temperature calibration.py +291 -0
  4. ararpy/Example - Show MDD results.py +561 -0
  5. ararpy/Example - Show all Kfs age spectra.py +344 -0
  6. ararpy/Example - Show random walk results.py +363 -0
  7. ararpy/Example - Tc calculation.py +437 -0
  8. ararpy/__init__.py +3 -4
  9. ararpy/calc/age.py +34 -36
  10. ararpy/calc/arr.py +0 -20
  11. ararpy/calc/basic.py +26 -3
  12. ararpy/calc/corr.py +131 -85
  13. ararpy/calc/plot.py +1 -2
  14. ararpy/calc/raw_funcs.py +41 -2
  15. ararpy/calc/regression.py +224 -132
  16. ararpy/files/arr_file.py +2 -1
  17. ararpy/files/basic.py +0 -22
  18. ararpy/files/calc_file.py +107 -84
  19. ararpy/files/raw_file.py +242 -229
  20. ararpy/smp/basic.py +133 -34
  21. ararpy/smp/calculation.py +6 -6
  22. ararpy/smp/corr.py +339 -153
  23. ararpy/smp/diffusion_funcs.py +345 -36
  24. ararpy/smp/export.py +247 -129
  25. ararpy/smp/info.py +2 -2
  26. ararpy/smp/initial.py +93 -45
  27. ararpy/smp/json.py +2 -2
  28. ararpy/smp/plots.py +144 -164
  29. ararpy/smp/raw.py +11 -15
  30. ararpy/smp/sample.py +222 -181
  31. ararpy/smp/style.py +26 -7
  32. ararpy/smp/table.py +42 -33
  33. ararpy/thermo/atomic_level_random_walk.py +56 -48
  34. ararpy/thermo/basic.py +2 -2
  35. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/METADATA +1 -1
  36. ararpy-0.2.1.dist-info/RECORD +73 -0
  37. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/WHEEL +1 -1
  38. ararpy-0.1.199.dist-info/RECORD +0 -66
  39. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/licenses/LICENSE +0 -0
  40. {ararpy-0.1.199.dist-info → ararpy-0.2.1.dist-info}/top_level.txt +0 -0
ararpy/smp/basic.py CHANGED
@@ -20,7 +20,7 @@ from typing import Optional, Union, List
20
20
  from .. import calc
21
21
  from ..files.basic import (read as read_params)
22
22
  from .sample import Sample, Table, Plot, ArArData, ArArBasic, Sequence, RawData
23
- from .initial import preference_keys
23
+ from .initial import PREFERENCE_RES
24
24
 
25
25
  Set = Plot.Set
26
26
  Label = Plot.Label
@@ -30,6 +30,62 @@ Text = Plot.Text
30
30
  pd.options.mode.chained_assignment = None # default='warn'
31
31
 
32
32
 
33
+ # =======================
34
+ # Params validate
35
+ # =======================
36
+ class ParamsInvalid(Exception):
37
+ """ """
38
+ def __init__(self, code, message, context=None):
39
+ self.code = code
40
+ self.message = message
41
+ self.context = context or {}
42
+ # 调用父类构造函数,确保异常能正常抛出
43
+ super().__init__(f"{self.message}")
44
+
45
+
46
+ def validate_params(**kwargs):
47
+
48
+ def check(data, dtype, **kwargs):
49
+ k = np.array(data, dtype=dtype)
50
+ # if dtype != str:
51
+ # if np.isnan(k).any():
52
+ # raise ValueError("Array contains NaN value(s)")
53
+ # if np.isinf(k).any():
54
+ # raise ValueError("Array contains Inf value(s)")
55
+ if dtype == bool:
56
+ if not all([isinstance(i, bool) or i in [0, 1] for i in np.array(data).flatten()]):
57
+ raise ValueError("array contains non-bool value(s)")
58
+ elif dtype == int:
59
+ for each in k.flatten():
60
+ if isinstance(each, dtype):
61
+ raise ValueError(f"type error, {type(each)} is given")
62
+ if kwargs.keys().__contains__('func'):
63
+ for each in k.ravel():
64
+ try:
65
+ if not kwargs.get('func')(each):
66
+ raise ValueError
67
+ except (Exception, BaseException) as e:
68
+ raise ValueError(f"{type(e).__name__}: invalid value, {each}")
69
+
70
+ context = {'names': [], 'classnames': [], 'messages': []}
71
+ for index, (name, content) in enumerate(kwargs.items(), 1):
72
+
73
+ try:
74
+ if isinstance(content, dict):
75
+ check(**content)
76
+ elif isinstance(content, list):
77
+ for each in content:
78
+ check(**each)
79
+ except (Exception, BaseException) as e:
80
+ context['names'].append(name)
81
+ context['classnames'].append(f"k{index}")
82
+ context['messages'].append(f"{name} {str(e)}")
83
+ if not context['names']:
84
+ return True
85
+ else:
86
+ raise ParamsInvalid(400, '. '.join(context['messages']), context)
87
+
88
+
33
89
  # =======================
34
90
  # Calculate ages
35
91
  # =======================
@@ -44,18 +100,26 @@ def calc_apparent_ages(smp: Sample):
44
100
  -------
45
101
 
46
102
  """
47
- if smp.Info.sample.type == "Unknown":
48
- age = calc_age(smp=smp)
49
- smp.ApparentAgeValues[2:6] = age
50
- smp.PublishValues[5:7] = copy.deepcopy(age[0:2])
51
- if smp.Info.sample.type == "Standard":
52
- j = calc_j(smp=smp)
53
- smp.ApparentAgeValues[2:4] = j
54
- smp.PublishValues[5:7] = copy.deepcopy(j[0:2])
55
- if smp.Info.sample.type == "Air":
56
- mdf = calc_mdf(smp=smp)
57
- smp.ApparentAgeValues[2:4] = mdf
58
- smp.PublishValues[5:7] = copy.deepcopy(mdf[0:2])
103
+ try:
104
+ params_to_check = {
105
+ 'sample type': {'data': smp.Info.sample.type, 'dtype': str, 'func': lambda x: str(x).lower() in ['unknown', 'standard', 'air'],},
106
+ }
107
+ except (IndexError, AttributeError) as e:
108
+ raise
109
+ if not validate_params(**params_to_check):
110
+ return
111
+
112
+ if str(smp.Info.sample.type).lower() == "unknown":
113
+ v = calc_age(smp=smp)
114
+ elif str(smp.Info.sample.type).lower() == "standard":
115
+ v = calc_j(smp=smp)
116
+ elif str(smp.Info.sample.type).lower() == "air":
117
+ v = calc_mdf(smp=smp)
118
+ else:
119
+ raise TypeError(f"Sample type is not supported: {smp.Info.sample.type}")
120
+
121
+ smp.ApparentAgeValues[2:6] = v[0:4]
122
+ smp.PublishValues[5:7] = copy.deepcopy(v[0:2])
59
123
 
60
124
 
61
125
  def calc_j(ar40ar39=None, params: dict = None, smp: Sample = None, index: list = None):
@@ -97,7 +161,7 @@ def calc_j(ar40ar39=None, params: dict = None, smp: Sample = None, index: list =
97
161
 
98
162
  def calc_mdf(ar40ar36=None, params: dict = None, smp: Sample = None, index: list = None):
99
163
  params_index_dict = {
100
- 71: 'M36', 72: 'sM36', 79: 'M40', 80: 'sM40', 93: 'Air', 94: 'sAir', 100: 'Discr'
164
+ 71: 'M36', 72: 'sM36', 79: 'M40', 80: 'sM40', 93: 'Air', 94: 'rsAir', 100: 'Discr'
101
165
  }
102
166
  if ar40ar36 is None and smp is not None:
103
167
  ar40ar36 = smp.ApparentAgeValues[0:2] # ar40ar36 air, error
@@ -127,7 +191,7 @@ def calc_mdf(ar40ar36=None, params: dict = None, smp: Sample = None, index: list
127
191
  mdf = []
128
192
  for i in range(len(index)):
129
193
  k = calc.corr.mdf(ar40ar36[0][i], ar40ar36[1][i], params['M36'][i], params['M40'][i],
130
- params['Air'][i], params['sAir'][i]) # linear, exp, pow
194
+ params['Air'][i], params['rsAir'][i]) # linear, exp, pow
131
195
  mdf.append({"linear": k[0:4], "exp": k[4:8], "pow": k[8:12]}[params['Discr'][i].lower()])
132
196
 
133
197
  if len(index) == 1:
@@ -152,7 +216,8 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
152
216
  """
153
217
  params_index_dict = {
154
218
  34: 'L', 35: 'sL', 36: 'Le', 37: 'sLe', 38: 'Lb', 39: 'sLb', 48: 'A', 49: 'sA',
155
- 50: 'Ae', 51: 'sAe', 52: 'Ab', 53: 'sAb', 59: 't', 60: 'st', 67: 'J', 68: 'sJ',
219
+ 50: 'Ae', 51: 'sAe', 52: 'Ab', 53: 'sAb', 54: 'Abp', 55: 'sAbp', 59: 't', 60: 'st',
220
+ 61: 'Ap', 62: 'sAp', 63: 'Kp', 64: 'sKp', 67: 'J', 68: 'sJ',
156
221
  81: 'W', 82: 'sW', 83: 'No', 84: 'sNo', 85: 'Y', 86: 'sY', 87: 'f', 88: 'sf', 110: 'Min'
157
222
  }
158
223
 
@@ -188,7 +253,7 @@ def calc_age(ar40ar39=None, params: dict = None, smp: Sample = None, index: list
188
253
 
189
254
  u = 'Ma'
190
255
  try:
191
- u = smp.Info.preference['ageUnit']
256
+ u = smp.Info.preference.age_unit
192
257
  except:
193
258
  print(traceback.format_exc())
194
259
  pass
@@ -426,21 +491,22 @@ def get_merged_smp(a: Sample, b: (Sample, dict)):
426
491
  symbol_size = 10, line_type = 'solid'))
427
492
  """
428
493
 
429
- def get_similar_name(_name: str):
494
+ def get_similar_name(name: str):
430
495
  res = []
431
- for i in range(len(_name) + 1):
432
- str_list = [i for i in _name]
433
- str_list.insert(i, '_')
434
- res.append(''.join(str_list))
435
- for i in range(len(_name)):
436
- str_list = [i for i in _name]
437
- str_list[i] = str_list[i].capitalize()
438
- res.append(''.join(str_list))
439
- for i in range(len(_name)):
440
- str_list = [i for i in _name]
441
- if _name[i] in '-_':
442
- str_list.pop(i)
496
+ for _name in set([name, name.lower(), name.upper()]):
497
+ for i in range(len(_name) + 1):
498
+ str_list = [i for i in _name]
499
+ str_list.insert(i, '_')
443
500
  res.append(''.join(str_list))
501
+ for i in range(len(_name)):
502
+ str_list = [i for i in _name]
503
+ str_list[i] = str_list[i].capitalize()
504
+ res.append(''.join(str_list))
505
+ for i in range(len(_name)):
506
+ str_list = [i for i in _name]
507
+ if _name[i] in '-_':
508
+ str_list.pop(i)
509
+ res.append(''.join(str_list))
444
510
  return res
445
511
 
446
512
  if not isinstance(b, dict):
@@ -612,13 +678,13 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
612
678
  smp.TotalParam[100:114] = remove_none(
613
679
  smp.TotalParam[100:114],
614
680
  [['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
615
- pref = dict(zip(preference_keys, params[31:35]))
616
- smp.Info.preference.update(pref)
681
+ for index, (key, val) in enumerate(PREFERENCE_RES.items()):
682
+ setattr(smp.Info.preference, key, type(val)(params[31:35][index]))
617
683
  for key, comp in get_components(smp).items():
618
684
  if isinstance(comp, Table):
619
- comp.decimal_places = pref['decimalPlaces']
685
+ comp.decimal_places = smp.Info.preference.decimal_places
620
686
  comp.set_coltypes()
621
- smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(pref['ageUnit']).capitalize()})"
687
+ smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(smp.Info.preference.age_unit).capitalize()})"
622
688
 
623
689
  else:
624
690
  raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
@@ -660,3 +726,36 @@ def get_results(smp: Sample):
660
726
  for (key, value) in smp.Info.results.age_plateau.items()))
661
727
  )
662
728
 
729
+
730
+ def set_selection(smp: Sample, index: int, mark: int):
731
+ """
732
+ Parameters
733
+ ----------
734
+ smp : sample instance
735
+ index : int, data point index
736
+ mark : int, 0 for unselected, 1 for set1, 2 for set2
737
+
738
+ Returns
739
+ -------
740
+
741
+ """
742
+ if mark not in [1, 2, '1', '2']:
743
+ raise ValueError(f"invalid mark value: {mark}, must be 1 or 2.")
744
+
745
+ def seq(_i): return [smp.UnselectedSequence, smp.SelectedSequence1, smp.SelectedSequence2][_i]
746
+
747
+ if index in seq(mark):
748
+ seq(mark).remove(index)
749
+ smp.UnselectedSequence.append(index)
750
+ else:
751
+ for i in [0, [0, 2, 1][mark]]:
752
+ if index in seq(i):
753
+ seq(i).remove(index)
754
+ seq(mark).append(index)
755
+ smp.IsochronMark = [
756
+ '1' if i in smp.SelectedSequence1 else '2' if i in smp.SelectedSequence2 else '' for i in
757
+ range(len(smp.IsochronValues[2]))]
758
+ #
759
+ smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
760
+ smp.Info.results.selection[1]['data'] = smp.SelectedSequence2
761
+ smp.Info.results.selection[2]['data'] = smp.UnselectedSequence
ararpy/smp/calculation.py CHANGED
@@ -22,7 +22,8 @@ def recalculate(
22
22
  re_corr_blank: bool = False, re_corr_massdiscr: bool = False,
23
23
  re_corr_decay: bool = False, re_degas_ca: bool = False, re_degas_k: bool = False,
24
24
  re_degas_cl: bool = False, re_degas_atm: bool = False, re_degas_r: bool = False,
25
- re_calc_ratio: bool = False, re_calc_apparent_age: bool = False, monte_carlo: bool = False,
25
+ re_calc_ratio: bool = False, re_calc_apparent_age: bool = False,
26
+ # monte_carlo: bool = False,
26
27
  re_plot: bool = False, re_plot_style: bool = False, re_set_table: bool = False,
27
28
  re_table_style: bool = False, **kwargs
28
29
  ):
@@ -42,7 +43,6 @@ def recalculate(
42
43
  re_degas_r
43
44
  re_calc_ratio
44
45
  re_calc_apparent_age
45
- monte_carlo
46
46
  re_plot
47
47
  re_plot_style
48
48
  re_set_table
@@ -59,13 +59,11 @@ def recalculate(
59
59
  # print(f"{sample.UnselectedSequence = }")
60
60
  # print(f"{sample.SelectedSequence1 = }")
61
61
  # print(f"{sample.SelectedSequence2 = }")
62
+
62
63
  # --- initializing ---
63
- re_corr_gain = re_corr_blank
64
64
  if re_initial: # 1
65
65
  initial.re_set_smp(sample)
66
66
  # --- calculating ---
67
- if re_corr_gain: # 2 2024-10-04 add
68
- corr.corr_gain(sample)
69
67
  if re_corr_blank: # 2
70
68
  corr.corr_blank(sample)
71
69
  if re_corr_massdiscr: # 3
@@ -82,8 +80,10 @@ def recalculate(
82
80
  corr.calc_degas_atm(sample)
83
81
  if re_degas_r: # 9
84
82
  corr.calc_degas_r(sample)
83
+ corr.calc_degas_c(sample)
85
84
  if re_calc_ratio: # 10
86
- corr.calc_ratio(sample, monte_carlo)
85
+ corr.calc_ratio(sample)
86
+ corr.calc_ratio_monte_carlo(sample)
87
87
  if re_calc_apparent_age: # 11
88
88
  basic.calc_apparent_ages(sample)
89
89
  # --- plot and table ---