ararpy 0.1.26__tar.gz → 0.1.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {ararpy-0.1.26 → ararpy-0.1.28}/PKG-INFO +1 -1
  2. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/basic.py +8 -0
  3. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/calc_file.py +36 -29
  4. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/raw_file.py +9 -5
  5. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/corr.py +1 -1
  6. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/export.py +78 -55
  7. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/initial.py +12 -9
  8. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy.egg-info/PKG-INFO +1 -1
  9. {ararpy-0.1.26 → ararpy-0.1.28}/setup.py +1 -1
  10. {ararpy-0.1.26 → ararpy-0.1.28}/LICENSE +0 -0
  11. {ararpy-0.1.26 → ararpy-0.1.28}/README.md +0 -0
  12. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/__init__.py +0 -0
  13. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/__init__.py +0 -0
  14. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/age.py +0 -0
  15. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/arr.py +0 -0
  16. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/corr.py +0 -0
  17. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/err.py +0 -0
  18. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/histogram.py +0 -0
  19. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/isochron.py +0 -0
  20. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/jvalue.py +0 -0
  21. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/plot.py +0 -0
  22. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/raw_funcs.py +0 -0
  23. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/regression.py +0 -0
  24. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/calc/spectra.py +0 -0
  25. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/022_VU124-M11a.ahd +0 -0
  26. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/20WHA0103.age +0 -0
  27. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/22WHA0078.xls +0 -0
  28. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/22WHA0433.age +0 -0
  29. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/22WHA0433.arr +0 -0
  30. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/22WHA0433.full.xls +0 -0
  31. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/24WHN0001-51-592.XLS +0 -0
  32. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/AHD.input-filter +0 -0
  33. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/ArAr.calc +0 -0
  34. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/ArArCALC.age +0 -0
  35. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/NGX-600 - Copy.TXT +0 -0
  36. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/NGX-600.TXT +0 -0
  37. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/NGX-XLS.input-filter +0 -0
  38. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/Qtegra-exported-xls.input-filter +0 -0
  39. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/S01-239.csv +0 -0
  40. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/WH01.irra +0 -0
  41. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/WHA.pdf +0 -0
  42. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/raw_example.xls +0 -0
  43. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/examples/sample-default.smp +0 -0
  44. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/__init__.py +0 -0
  45. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/arr_file.py +0 -0
  46. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/basic.py +0 -0
  47. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/new_file.py +0 -0
  48. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/files/xls.py +0 -0
  49. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +0 -0
  50. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/__init__.py +0 -0
  51. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/basic.py +0 -0
  52. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/calculation.py +0 -0
  53. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/consts.py +0 -0
  54. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/diffusion_funcs.py +0 -0
  55. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/info.py +0 -0
  56. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/json.py +0 -0
  57. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/plots.py +0 -0
  58. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/raw.py +0 -0
  59. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/sample.py +0 -0
  60. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/style.py +0 -0
  61. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/smp/table.py +0 -0
  62. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/test.py +0 -0
  63. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/thermo/__init__.py +0 -0
  64. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/thermo/arrhenius.py +0 -0
  65. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/thermo/atomic_level_random_walk.py +0 -0
  66. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy/thermo/basic.py +0 -0
  67. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy.egg-info/SOURCES.txt +0 -0
  68. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy.egg-info/dependency_links.txt +0 -0
  69. {ararpy-0.1.26 → ararpy-0.1.28}/ararpy.egg-info/top_level.txt +0 -0
  70. {ararpy-0.1.26 → ararpy-0.1.28}/setup.cfg +0 -0
  71. {ararpy-0.1.26 → ararpy-0.1.28}/tests/test.py +0 -0
  72. {ararpy-0.1.26 → ararpy-0.1.28}/tests/test2.py +0 -0
  73. {ararpy-0.1.26 → ararpy-0.1.28}/tests/test_error_correlation.py +0 -0
  74. {ararpy-0.1.26 → ararpy-0.1.28}/tests/test_regression_methods.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ararpy
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: A project for Ar-Ar geochronology
5
5
  Home-page: https://github.com/wuyangchn/ararpy.git
6
6
  Author: Yang Wu
@@ -129,3 +129,11 @@ def monte_carlo(func, inputs, confidence_level, **kwargs):
129
129
  limits = values[:, [l_range, r_range]]
130
130
 
131
131
  return np.concatenate((means, limits), axis=1), cov
132
+
133
+
134
+ def parser(v: str, t: type):
135
+ if t == bool:
136
+ if str(v).lower().rstrip() in ["true", "1"]:
137
+ return True
138
+ return t(v)
139
+
@@ -22,7 +22,7 @@ import os
22
22
  import msoffcrypto
23
23
 
24
24
  from . import xls
25
- from ..calc.basic import get_datetime
25
+ from ..calc.basic import get_datetime, parser
26
26
  from ..calc import arr, err, isochron
27
27
 
28
28
 
@@ -107,9 +107,8 @@ def open_252(data: pd.DataFrame, logs01: pd.DataFrame, logs02: pd.DataFrame):
107
107
  -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, # 90-99
108
108
  -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, # 100-109
109
109
  -999, -999, -999, -999, -1, # 110-114
110
- -999, -999, -999, -999, -999, -999, -999, -999, # 115-122
111
- -999, -999, -999, -999, -999, -999, -999, -999, # 123-130
112
- -999, -999, -999, -999, -999, # 131-135
110
+ -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, # 115-125
111
+ 999, -999, 999, -999, 999, -999, 999, -999, 999, -999, # 126-135
113
112
  ]
114
113
 
115
114
  # double transpose to remove keys
@@ -128,6 +127,13 @@ def open_252(data: pd.DataFrame, logs01: pd.DataFrame, logs02: pd.DataFrame):
128
127
 
129
128
  # adjustment
130
129
  isochron_mark.replace({4.0: '1'}, inplace=True)
130
+
131
+ total_param[71] = 35.96754628
132
+ total_param[73] = 36.9667759
133
+ total_param[75] = 37.9627322
134
+ total_param[77] = 38.964313
135
+ total_param[79] = 39.962383123
136
+
131
137
  total_param[83] = logs01[1][9] # No
132
138
  total_param[84] = logs01[1][10] # %SD
133
139
  total_param[81] = logs01[1][11] # K mass
@@ -150,9 +156,9 @@ def open_252(data: pd.DataFrame, logs01: pd.DataFrame, logs02: pd.DataFrame):
150
156
  total_param[51] = logs01[1][27] # %SD
151
157
  total_param[52] = logs01[1][28] # 40K(\beta-) activities param
152
158
  total_param[53] = logs01[1][29] # %SD
153
- total_param[48] = logs01[1][26] + logs01[1][28] # 40K(EC) activities param
154
- total_param[49] = 100 / total_param[48] * pow(
155
- (logs01[1][27] / 100 * logs01[1][26]) ** 2 + (logs01[1][29] / 100 * logs01[1][28]) ** 2, 0.5) # %SD
159
+ total_param[48] = logs01[1][26] + logs01[1][28] # 40K total activities param
160
+ total_param[49] = round(100 / total_param[48] * pow(
161
+ (logs01[1][27] / 100 * logs01[1][26]) ** 2 + (logs01[1][29] / 100 * logs01[1][28]) ** 2, 0.5), 6) # %SD
156
162
 
157
163
  total_param[34] = logs01[1][36] # decay constant of 40K total
158
164
  total_param[35] = logs01[1][37] # %SD
@@ -169,30 +175,29 @@ def open_252(data: pd.DataFrame, logs01: pd.DataFrame, logs02: pd.DataFrame):
169
175
  total_param[44] = logs01[1][40] # decay constant of 37Ar
170
176
  total_param[45] = logs01[1][41] # %SD
171
177
 
172
- # logs01[1][49]] # 1 for using weighted YORK isochron regression, 2 for unweighted
173
- # logs01[1][50]] # True for including errors on irradiation constants, False for excluding those
174
- # [logs01[1][67]] # MDF method, 'LIN'
178
+ # logs01[1][49] # 1 for using weighted YORK isochron regression, 2 for unweighted
179
+ # logs01[1][50] # True for including errors on irradiation constants, False for excluding those
180
+ # logs01[1][67] # MDF method, 'LIN'
175
181
  total_param[93] = logs01[1][70] # 40Ar/36Ar air
176
182
  total_param[94] = logs01[1][71] # %SD
177
-
178
- total_param[97] = 'York-2' # Fitting method
183
+ total_param[97] = 'York-2' if int(logs01[1][49]) == 1 else "" # Fitting method
179
184
  total_param[98] = logs01[1][0] # Convergence
180
185
  total_param[99] = logs01[1][1] # Iterations number
181
186
  total_param[100] = logs01[1][67] # MDF method
182
- total_param[101] = logs01[1][65] # force negative to zero when correct blank
187
+ total_param[101] = parser(logs01[1][65], bool) # force negative to zero when correct blank
183
188
  total_param[102] = True # Apply 37Ar decay
184
189
  total_param[103] = True # Apply 39Ar decay
185
- total_param[104] = logs01[1][6] # Apply 37Ar decay
186
- total_param[105] = logs01[1][7] # Apply 39Ar decay
187
- total_param[106] = True # Apply K degas
188
- total_param[107] = True # Apply Ca degas
189
- total_param[108] = True # Apply Air degas
190
- total_param[109] = logs01[1][8] # Apply Cl degas
190
+ total_param[104] = parser(logs01[1][6], bool) # Apply 37Ar decay
191
+ total_param[105] = parser(logs01[1][7], bool) # Apply 39Ar decay
192
+ total_param[106] = True # Apply Ca degas
193
+ total_param[107] = True # Apply K degas
194
+ total_param[108] = parser(logs01[1][8], bool) # Apply Cl degas
195
+ total_param[109] = True # Apply Trap degas
191
196
 
192
197
  total_param[110] = True if logs01[1][5] == 'MIN' else False # Calculating ages using Min equation [True] or conventional equation [False]
193
- total_param[111] = logs01[1][89] # Use primary standard or not
194
- total_param[112] = logs01[1][91] # Use standard age or not
195
- total_param[113] = logs01[1][92] # Use primary ratio or not
198
+ total_param[111] = parser(logs01[1][89], bool) # Use primary standard or not
199
+ total_param[112] = parser(logs01[1][91], bool) # Use standard age or not
200
+ total_param[113] = parser(logs01[1][92], bool) # Use primary ratio or not
196
201
 
197
202
  # irradiation time
198
203
  total_param = general_adjustment(
@@ -310,12 +315,12 @@ def open_240(data: pd.DataFrame, logs01: pd.DataFrame, logs02: pd.DataFrame):
310
315
  )
311
316
  # Do adjustment
312
317
  isochron_mark.replace({4.0: '1'}, inplace=True)
313
- total_param[44] = logs01[1][40]
314
- total_param[45] = logs01[1][41]
315
- total_param[42] = logs01[1][38]
316
- total_param[43] = logs01[1][39]
317
318
  total_param[34] = logs01[1][36]
318
319
  total_param[35] = logs01[1][37]
320
+ total_param[42] = logs01[1][38]
321
+ total_param[43] = logs01[1][39]
322
+ total_param[44] = logs01[1][40]
323
+ total_param[45] = logs01[1][41]
319
324
 
320
325
  return [
321
326
  sample_values, blank_values, corrected_values, degas_values, publish_values,
@@ -399,6 +404,8 @@ def general_adjustment(
399
404
  total_param[32] = [i / (3600 * 24 * 365.242) for i in stand_time_second] # stand year
400
405
 
401
406
  # initial ratios & error display settings
407
+ total_param[95] = logs02[9][irradiation_index] # 38Ar/36Ar air
408
+ total_param[96] = logs02[10][irradiation_index] # %SD
402
409
  total_param[115] = 0
403
410
  total_param[116] = 298.56
404
411
  total_param[117] = 0.31
@@ -624,10 +631,10 @@ class ArArCalcFile:
624
631
  # list(range(1, 26, 2)) irradiation correction constants
625
632
  # list(range(39, 58, 2)) decay constants
626
633
  # list(range(68, 97, 2)) J, MDF, other constants
627
- for column in list(range(1, 26, 2)) + list(range(68, 71, 2)):
634
+ for column in list(range(1, 26, 2)) + list(range(68, 71, 2)): # irradiation constants and J, MDF uncertainties
628
635
  self.content.loc[:, ('pam', column)] = \
629
- (self.content['pam', column].astype("float") / (
630
- self.content['pam', column - 1].astype("float")) * 100).replace(np.nan, 0)
636
+ round(self.content['pam', column].astype("float") / (
637
+ self.content['pam', column - 1].astype("float")) * 100, 6).replace(np.nan, 0)
631
638
 
632
639
  # sample info
633
640
  self.sample_info = {
@@ -97,7 +97,6 @@ def open_file(file_path: str, input_filter: List[Union[str, int, bool]]):
97
97
  'Qtegra Exported XLS': open_qtegra_exported_xls, 'Seq': open_raw_seq}[
98
98
  ['txt', 'excel', 'Qtegra Exported XLS', 'Seq'][int(input_filter[1])]]
99
99
  except KeyError:
100
- print(traceback.format_exc())
101
100
  raise FileNotFoundError("Wrong File.")
102
101
  return handler(file_path, input_filter)
103
102
 
@@ -302,6 +301,7 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
302
301
 
303
302
  # ============ Zero datetime ============
304
303
  timezone = strings_index[7] if strings_index[7] != "" else "utc"
304
+ options.update({'TimeZone': timezone})
305
305
  try:
306
306
  if check_box_index[3]: # date in one string
307
307
  zero_date = datetime_parse(options.get('ZeroYear'), strings_index[5])
@@ -319,10 +319,11 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
319
319
  zero_date.year, zero_date.month, zero_date.day, zero_time.hour, zero_time.minute, zero_time.second)
320
320
  # adjust to UTC
321
321
  zero_datetime = utc_dt(zero_datetime, tz=timezone).isoformat(timespec='seconds')
322
- except (TypeError, ValueError, IndexError):
323
- # print(f"Cannot parse zero datetime")
324
- zero_datetime = datetime(1970, 1, 1, 0, 0, 0).isoformat(timespec='seconds')
325
-
322
+ options.update({'ZeroDT': zero_datetime})
323
+ except (TypeError, ValueError, IndexError) as e:
324
+ print(traceback.format_exc())
325
+ raise ValueError(f"Failed to parse zero datetime: {e}")
326
+ # zero_datetime = datetime(1970, 1, 1, 0, 0, 0).isoformat(timespec='seconds')
326
327
  current_step = [[step_name, zero_datetime, options]]
327
328
 
328
329
  # ============ isotope data ============
@@ -395,6 +396,9 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
395
396
  if not check_box_index[0] or len(step_list) >= 500: # check_box_index[0]: multiple sequences
396
397
  break
397
398
 
399
+ if not step_list:
400
+ raise ValueError("Failed to read the original file. It might be because the names of the experiments or steps were not recognized.")
401
+
398
402
  return step_list
399
403
 
400
404
 
@@ -266,7 +266,7 @@ def calc_degas_cl(sample: Sample):
266
266
  d6 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / a7 / (1 - a6 / a7) ** 2
267
267
  d7 = -(a1 - a2) * (a6) / (a7 - a6) ** 2 - (a3 + a4 - a5) / (a7 - a6) ** 2
268
268
 
269
- v1 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / (1 - a6 / a7)
269
+ v1 = (a1 - a2 + (a3 + a4 - a5) / a7) / (1 - a6 / a7)
270
270
  s1 = (d1**2*s1**2 + d2**2*s2**2 + d3**2*s3**2 + d4**2*s4**2+ d5**2*s5**2 + d6**2*s6**2 + d7**2*s7**2) ** .5
271
271
  s2 = calc.err.mul((v1, s1), (vDecay[i], sDecay[i]))
272
272
  v1 = 0 if (ar36acl[0][i] - v1 < 0 or v1 < 0) and set_negative_zero[i] else v1
@@ -19,6 +19,7 @@ import pickle
19
19
  import traceback
20
20
  import pdf_maker as pm
21
21
  import numpy as np
22
+ from math import log
22
23
  from decimal import Decimal
23
24
 
24
25
  from ..calc import arr, isochron, spectra, err
@@ -63,19 +64,19 @@ def get_cv_from_dict(data: dict, **kwargs):
63
64
  scale = (float(scale[0]), float(scale[1]), float(scale[2]), float(scale[3]))
64
65
  # create plot area based on axis scale
65
66
  plot_area = (kwargs.get("pt_left", 0.15), kwargs.get("pt_bottom", 0.15), kwargs.get("pt_width", 0.8), kwargs.get("pt_height", 0.8))
66
- pt = cv.add_plot_area(name=f"PlotArea{i}", plot_area=plot_area, plot_scale=scale, show_frame=True)
67
+ pt = cv.add_plot_area(name=f"PlotArea{i}", plot_area=plot_area, plot_scale=scale, **data['xAxis'][i])
67
68
  for stick in data['xAxis'][i]['interval']:
68
69
  start = pt.scale_to_points(float(stick), scale[2])
69
70
  end = pt.scale_to_points(float(stick), scale[2])
70
71
  end = (end[0], end[1] - 5)
71
- if pt.line(start=start, end=end, width=1, line_style="solid", y_clip=False, coordinate="pt", z_index=100):
72
+ if pt.line(start=start, end=end, width=data['xAxis'][i]['line_width'], line_style="solid", y_clip=False, coordinate="pt", z_index=100):
72
73
  pt.text(x=start[0], y=end[1] - 15, text=f"{stick}", clip=False, size=int(data['xAxis'][i]['label_size']),
73
74
  coordinate="pt", h_align="middle", z_index=150)
74
75
  for stick in data['yAxis'][i]['interval']:
75
76
  start = pt.scale_to_points(scale[0], float(stick))
76
77
  end = pt.scale_to_points(scale[0], float(stick))
77
78
  end = (end[0] - 5, end[1])
78
- if pt.line(start=start, end=end, width=1, line_style="solid", x_clip=False, coordinate="pt", z_index=100):
79
+ if pt.line(start=start, end=end, width=data['xAxis'][i]['line_width'], line_style="solid", x_clip=False, coordinate="pt", z_index=100):
79
80
  pt.text(x=end[0] - 5, y=end[1], text=f"{stick}", clip=False, size=int(data['yAxis'][i]['label_size']),
80
81
  coordinate="pt", h_align="right", v_align="center", z_index=150)
81
82
  # axis titles
@@ -107,13 +108,13 @@ def get_cv_from_dict(data: dict, **kwargs):
107
108
  start=data[index - 1], end=data[index], width=se.get('line_width', 1),
108
109
  line_style=se.get('line_style', 'solid'), name=se['name'],
109
110
  color=se.get('color', 'black'), clip=True, line_caps=se.get('line_caps', 'none'),
110
- z_index=se.get('z_index', 9))
111
+ z_index=int(se.get('z_index', 9)))
111
112
  if 'scatter' in se['type'] and se['name'] != 'Text':
112
113
  for each in data:
113
114
  pt.scatter(
114
115
  each[0], each[1], fill_color=se.get('fill_color', 'black'), size=se.get('size', 5),
115
116
  stroke_color=se.get('stroke_color', se.get('color', 'black')),
116
- z_index=se.get('z_index', 9)
117
+ z_index=int(se.get('z_index', 9))
117
118
  )
118
119
  if 'scatter' in se['type'] and se['name'] == 'Text' or 'text' in se['type']:
119
120
  for each in data:
@@ -181,6 +182,12 @@ def export_chart_to_pdf(cvs, file_name: str = "", file_path: str = "", **kwargs)
181
182
  -------
182
183
 
183
184
  """
185
+ # capital letter for label
186
+ def get_label(l="", num=0):
187
+ if num // 26 > 0:
188
+ return get_label(get_label(l, num // 26 - 1), num % 26)
189
+ return l + chr(num % 26 + 65)
190
+
184
191
  # write pdf
185
192
  show_label = kwargs.get('show_label', False)
186
193
  num_cols = kwargs.get('num_columns', 2)
@@ -195,21 +202,12 @@ def export_chart_to_pdf(cvs, file_name: str = "", file_path: str = "", **kwargs)
195
202
  file.del_obj(i)
196
203
  file.add_page(size=page_size[kwargs.get('page_size', 'a4').lower()], unit='mm')
197
204
  for page_index, page in enumerate(cvs):
198
-
199
- # for x in range(0, 600, 10):
200
- # file.line(page_index, start=(x, 0), end=(x, 900), style='dash', color='grey')
201
- # for y in range(0, 900, 10):
202
- # file.line(page_index, start=(0, y), end=(800, y), style='dash', color='grey')
203
-
204
- numbers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
205
-
206
205
  for cv_index, cv in enumerate(page):
207
206
  left = 10 + cv_index % num_cols * cv.width()
208
207
  top = 20 + cv_index // num_cols * cv.height()
209
208
  if show_label:
210
- # file.text(page=page_index, x=left + 65, y=810 - top, text=numbers[cv_index])
211
209
  cv._plot_areas[1].text(
212
- x=5, y=95, text=numbers[cv_index],
210
+ x=5, y=95, text=f"({get_label(num=cv_index)})",
213
211
  id=f'text-label-{page_index}-{cv_index}',
214
212
  name=f'text-label-{page_index}-{cv_index}',
215
213
  color='black', size=title_size, axis_index=1, h_align='middle', v_align='center'
@@ -312,7 +310,7 @@ def getRectFromSpectra(data):
312
310
 
313
311
  """
314
312
  data = np.array(data)
315
- return list(map(lambda index: [data[index,0], min(data[index,[1,2]]), np.diff(data[[index,index+1],0])[0], np.diff(data[index,[1,2]])[0]], list(range(len(data) - 1))))
313
+ return list(filter(lambda rect: rect[2] != 0 and rect[3] != 0, map(lambda index: [data[index,0], min(data[index,[1,2]]), abs(data[index+1,0] - data[index,0]), abs(data[index,1] - data[index,2])], list(range(len(data) - 1)))))
316
314
 
317
315
 
318
316
  def _get_additional_text_series(name):
@@ -327,28 +325,36 @@ def _get_additional_text_series(name):
327
325
 
328
326
  def _get_plot_data_age_spectra_series(smp: sample, **options):
329
327
  color = options.get('color', 'black')
330
- sigma = options.get('sigma', 1)
328
+ sigma = options.get('sigma', smp.Info.preference['confidenceLevel'])
329
+ unit = options.get('unit', smp.Info.preference['ageUnit'])
331
330
  xAxis = options.get('xAxis', [{}])
332
331
  yAxis = options.get('yAxis', [{}])
332
+ line_width = options.get('line_width', 1)
333
+ line_caps = options.get('line_caps', 'square')
333
334
  series = []
335
+ # apparent spectra lines
334
336
  age = smp.ApparentAgeValues[2:4]
335
337
  ar = smp.DegasValues[20]
336
- data = spectra.get_data(*age, ar, cumulative=False)
338
+ data = spectra.get_data(*age, ar, cumulative=False, sigma=sigma)
337
339
  series.append({
338
340
  'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
339
- 'color': color, 'fill_color': color, 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
340
- 'data': np.transpose([data[0], data[1]]).tolist(), 'line_caps': 'square',
341
+ 'color': color, 'fill_color': color, 'line_width': line_width, 'line_style': 'solid', 'z_index': 19,
342
+ 'data': np.transpose([data[0], data[1]]).tolist(),
343
+ 'line_caps': line_caps,
344
+ # 'line_caps': 'none',
341
345
  'axis_index': 0,
342
346
  })
343
347
  series.append({
344
348
  'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}', 'name': f'line-{smp.name()}-{get_random_digits()}',
345
- 'color': color, 'fill_color': color, 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
346
- 'data': np.transpose([data[0], data[2]]).tolist(), 'line_caps': 'square',
349
+ 'color': color, 'fill_color': color, 'line_width': line_width, 'line_style': 'solid', 'z_index': 19,
350
+ 'data': np.transpose([data[0], data[2]]).tolist(),
351
+ 'line_caps': line_caps,
352
+ # 'line_caps': 'none',
347
353
  'axis_index': 0,
348
354
  })
355
+ # initial values corrected spectra lines and rect
349
356
  text1 = smp.AgeSpectraPlot.text1
350
357
  text2 = smp.AgeSpectraPlot.text2
351
- sigma = 1
352
358
  set_data = [spectraData2Sgima(smp.AgeSpectraPlot.set1.data, sigma),
353
359
  spectraData2Sgima(smp.AgeSpectraPlot.set2.data, sigma)]
354
360
  for index, text in enumerate([text1, text2]):
@@ -360,54 +366,60 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
360
366
  spectra_fill_data = getRectFromSpectra(plateau_data)
361
367
  series.append({
362
368
  'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
363
- 'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index], 'line_width': 0, 'line_style': 'solid', 'z_index': 9,
364
- 'data': spectra_fill_data, 'line_caps': 'square', 'fill': True,
369
+ 'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index], 'line_width': 0, 'line_style': 'none', 'z_index': 9,
370
+ 'data': spectra_fill_data, 'line_caps': 'none', 'fill': True,
365
371
  'axis_index': 0,
366
372
  })
367
373
  series.append({
368
374
  'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
369
375
  'name': f'line-{smp.name()}-{get_random_digits()}',
370
- 'color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
371
- 'data': plateau_data[:,[0,1]].tolist(), 'line_caps': 'square',
376
+ 'color': ['red', 'blue'][index], 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
377
+ 'data': plateau_data[:,[0,1]].tolist(),
378
+ 'line_caps': line_caps,
379
+ # 'line_caps': 'none',
372
380
  'axis_index': 0,
373
381
  })
374
382
  series.append({
375
383
  'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
376
384
  'name': f'line-{smp.name()}-{get_random_digits()}',
377
- 'color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
378
- 'data': plateau_data[:,[0,2]].tolist(), 'line_caps': 'square',
385
+ 'color': ['red', 'blue'][index], 'line_width': line_width, 'line_style': 'solid', 'z_index': 9,
386
+ 'data': plateau_data[:,[0,2]].tolist(),
387
+ 'line_caps': line_caps,
388
+ # 'line_caps': 'none',
379
389
  'axis_index': 0,
380
390
  })
381
391
  series.append({
382
392
  'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
383
393
  'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index],
384
- 'text': f"WMPA = {res['age']:.2f} ± {(sigma * res['s3']):.2f} Ma<r>"
394
+ 'text': f"WMPA = {res['age']:.2f} ± {(sigma * res['s3']):.2f} {unit} ({sigma}s)<r>"
385
395
  f"MSWD = {res['MSWD']:.2f}, n = {res['Num']:.0f}<r>"
386
- f"<sup>39</sup>Ar = {res['Ar39']:.2f}%",
396
+ f"<sup>39</sup>Ar = {res['Ar39']*100:.2f}%",
387
397
  'size': title_size,
388
- 'data': [text.pos],
389
- 'axis_index': 1,
398
+ # 'data': [text.pos],
399
+ 'data': [[50, 50]],
400
+ 'axis_index': 1, 'z_index': 29,
390
401
  'h_align': "middle",
391
402
  'v_align': "center",
392
403
  })
404
+ # TGA
393
405
  tga = smp.Info.results.age_spectra['TGA']
394
406
  if not np.isnan(tga['age']):
395
407
  series.append({
396
408
  'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
397
409
  'color': color, 'fill_color': color,
398
- 'text': f"TGA = {tga['age']:.2f} ± {(sigma * tga['s3']):.2f} Ma",
410
+ 'text': f"TGA = {tga['age']:.2f} ± {(sigma * tga['s3']):.2f} {unit} ({sigma}s)",
399
411
  'size': title_size,
400
412
  'data': [[50, 3]],
401
413
  'axis_index': 1,
402
414
  'h_align': "middle",
403
415
  'v_align': "bottom",
404
416
  })
405
-
417
+ # title
406
418
  series.append({
407
419
  'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}',
408
420
  'name': f'text-{smp.name()}-{get_random_digits()}', 'color': color,
409
421
  'text': smp.name(), 'size': title_size,
410
- 'data': [[50, 95]], 'axis_index': 1,
422
+ 'data': [[50, 95]], 'axis_index': 1, 'z_index': 29,
411
423
  'h_align': "middle", 'v_align': "center",
412
424
  })
413
425
 
@@ -416,50 +428,60 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
416
428
 
417
429
  def _get_plot_data_age_spectra_axis(smp: sample, **options):
418
430
  color = options.get('color', 'black')
431
+ line_width = options.get('line_width', 1)
419
432
  xAxis, yAxis = [], []
420
433
  age = smp.ApparentAgeValues[2:4]
421
434
  ar = smp.DegasValues[20]
422
435
  data = spectra.get_data(*age, ar, cumulative=False)
423
436
 
424
- y_low_limit, y_up_limit, stick_num, inc = get_axis_scale(np.array(data[1:3]).flatten())
425
- y_extent = [y_low_limit, y_up_limit]
426
- y_interval = [y_low_limit + i * inc for i in range(stick_num + 1)]
427
- y_interval.extend([y_up_limit * 10] * 3)
428
- dp = int(np.log10(abs(y_up_limit - y_low_limit)) - 1)
429
- dp = 0 if dp >= 0 else abs(dp)
430
- print(f"{dp = }")
431
- y_interval = [f"{i:.{dp}f}" for i in y_interval]
432
-
433
- # y_extent = [4, 12]
434
- # y_interval = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']
435
- # y_interval = ['0', '4', '6', '8', '10', '12', '60', '70', '80', '90', '100']
437
+ # y_low_limit, y_up_limit, stick_num, inc = get_axis_scale(np.array(data[1:3]).flatten())
438
+ # y_extent = [y_low_limit, y_up_limit]
439
+ # y_interval = [y_low_limit + i * inc for i in range(stick_num + 1)]
440
+ # y_interval.extend([y_up_limit * 10] * 3)
441
+ # dp = int(np.log10(abs(y_up_limit - y_low_limit)) - 1)
442
+ # dp = 0 if dp >= 0 else abs(dp)
443
+ # y_interval = [f"{i:.{dp}f}" for i in y_interval]
444
+ try:
445
+ y_low_limit = float(smp.AgeSpectraPlot.yaxis.min)
446
+ y_up_limit = float(smp.AgeSpectraPlot.yaxis.max)
447
+ y_extent = [y_low_limit, y_up_limit]
448
+ stick_num = int(smp.AgeSpectraPlot.yaxis.split_number)
449
+ inc = float(smp.AgeSpectraPlot.yaxis.interval)
450
+ y_interval = [y_low_limit + i * inc for i in range(stick_num + 1)]
451
+ dp = int(np.log10(abs(y_up_limit - y_low_limit)) - 1)
452
+ dp = 0 if dp >= 0 else abs(dp)
453
+ y_interval = [f"{i:.{dp}f}" for i in y_interval]
454
+ except (BaseException, Exception):
455
+ y_extent = [0, 250]
456
+ y_interval = ['0', '50', '100', '150', '200', '250', '600', '700', '800', '900', '1000']
436
457
 
437
458
  xAxis.append({
438
459
  'extent': [0, 100], 'interval': [0, 20, 40, 60, 80, 100], 'id': 0, 'show_frame': True,
439
- 'title': 'Cumulative <sup>39</sup>Ar Released (%)', 'name_location': 'middle',
440
- 'line_width': 1, 'line_style': 'solid', 'z_index': 9, 'label_size': label_size, 'title_size': title_size,
460
+ 'title': 'Cumulative <sup>39</sup>Ar released (%)', 'name_location': 'middle',
461
+ 'line_width': line_width, 'line_style': 'solid', 'z_index': 9, 'label_size': label_size, 'title_size': title_size,
441
462
  })
442
463
  xAxis.append({
443
464
  'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
444
465
  'title': '', 'name_location': 'middle',
445
- 'line_width': 1, 'line_style': 'solid', 'z_index': 0, 'label_size': label_size, 'title_size': title_size,
466
+ 'line_width': 0, 'line_style': 'none', 'z_index': 0, 'label_size': label_size, 'title_size': title_size,
446
467
  })
447
468
  yAxis.append({
448
469
  'extent': y_extent, 'interval': y_interval,
449
470
  'id': 0, 'show_frame': True,
450
- 'title': 'Apparent Age (Ma)', 'name_location': 'middle',
451
- 'line_width': 1, 'line_style': 'solid', 'z_index': 9, 'label_size': label_size, 'title_size': title_size,
471
+ 'title': 'Apparent age (Ma)', 'name_location': 'middle',
472
+ 'line_width': line_width, 'line_style': 'solid', 'z_index': 9, 'label_size': label_size, 'title_size': title_size,
452
473
  })
453
474
  yAxis.append({
454
475
  'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
455
476
  'title': '', 'name_location': 'middle',
456
- 'line_width': 1, 'line_style': 'solid', 'z_index': 0, 'label_size': label_size, 'title_size': title_size,
477
+ 'line_width': 0, 'line_style': 'none', 'z_index': 0, 'label_size': label_size, 'title_size': title_size,
457
478
  })
458
479
  return xAxis, yAxis
459
480
 
460
481
 
461
482
  def _get_plot_data_inv_isochron_axis(smp: sample, **options):
462
483
  color = options.get('color', 'black')
484
+ line_width = options.get('line_width', 1)
463
485
  xAxis, yAxis = [], []
464
486
  data = np.array(smp.InvIsochronPlot.data)
465
487
  set1 = smp.InvIsochronPlot.set1.data
@@ -478,10 +500,12 @@ def _get_plot_data_inv_isochron_axis(smp: sample, **options):
478
500
  'interval': interval,
479
501
  'id': 0, 'show_frame': True, 'z_index': 9, 'label_size': label_size, 'title_size': title_size,
480
502
  'title': '<sup>39</sup>Ar<sub>K</sub> / <sup>40</sup>Ar<sup>*</sup>', 'name_location': 'middle',
503
+ 'line_width': line_width,
481
504
  })
482
505
  xAxis.append({
483
506
  'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
484
507
  'title': '', 'name_location': 'middle', 'z_index': 0, 'label_size': label_size, 'title_size': title_size,
508
+ 'line_width': 0,
485
509
  })
486
510
 
487
511
  low_limit, up_limit, stick_num, inc = get_axis_scale(data[2])
@@ -1164,7 +1188,6 @@ class WritingWorkbook:
1164
1188
  ]:
1165
1189
  for index, _ in enumerate(['Set 1', 'Set 2']):
1166
1190
  ar39[index] = res[index].get('Ar39', ar39[index] * 100) / 100
1167
- print(res[index])
1168
1191
  try:
1169
1192
  content.extend([
1170
1193
  [(row + num_step, 0, row + 1 + num_step, 0), _, {'bold': 1, 'align': 'center'}],
@@ -302,17 +302,20 @@ def check_version(smp: Sample):
302
302
  smp.Info.experiment.name = smp.name()
303
303
  smp.Info.experiment.step_num = smp.sequence().size
304
304
 
305
- # 20250404
305
+ # 20250404: # Normalization for steps with different J values
306
306
  doNormalize = True
307
307
  v, sv = [], []
308
- if smp.Info.sample.type.lower() == "unknown":
309
- v, sv = smp.TotalParam[67:69]
310
- sv = np.multiply(v, sv) / 100
311
- elif smp.Info.sample.type.lower() == "air":
312
- v, sv = smp.TotalParam[93:95]
313
- sv = np.multiply(v, sv) / 100
314
- elif smp.Info.sample.type.lower() == "standard":
315
- v, sv = smp.TotalParam[59:61]
308
+ try:
309
+ if smp.Info.sample.type.lower() == "unknown":
310
+ v, sv = smp.TotalParam[67:69]
311
+ sv = np.multiply(v, sv) / 100
312
+ elif smp.Info.sample.type.lower() == "air":
313
+ v, sv = smp.TotalParam[93:95]
314
+ sv = np.multiply(v, sv) / 100
315
+ elif smp.Info.sample.type.lower() == "standard":
316
+ v, sv = smp.TotalParam[59:61]
317
+ except:
318
+ doNormalize = False
316
319
  smp.NormalizeFactor = [
317
320
  [1 if v[0] == each or not doNormalize else v[0] / each for each in v],
318
321
  [0 if v[0] == v[i] or not doNormalize else err.div((v[0], sv[0]), (v[i], sv[i])) for i in range(len(v))]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ararpy
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: A project for Ar-Ar geochronology
5
5
  Home-page: https://github.com/wuyangchn/ararpy.git
6
6
  Author: Yang Wu
@@ -16,7 +16,7 @@ long_description = (here / 'README.md').read_text(encoding='utf-8')
16
16
 
17
17
  setuptools.setup(
18
18
  name='ararpy', #
19
- version='0.1.26', # version
19
+ version='0.1.28', # version
20
20
  author='Yang Wu',
21
21
  author_email='wuycug@hotmail.com',
22
22
  description='A project for Ar-Ar geochronology', # short description
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes