ararpy 0.1.191__tar.gz → 0.1.193__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.191 → ararpy-0.1.193}/PKG-INFO +1 -1
  2. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/__init__.py +4 -2
  3. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/arr.py +9 -0
  4. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/calc_file.py +2 -5
  5. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/raw_file.py +1 -1
  6. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/xls.py +1 -2
  7. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/basic.py +29 -44
  8. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/export.py +81 -48
  9. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/initial.py +9 -6
  10. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/sample.py +6 -3
  11. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy.egg-info/PKG-INFO +1 -1
  12. {ararpy-0.1.191 → ararpy-0.1.193}/setup.py +1 -1
  13. {ararpy-0.1.191 → ararpy-0.1.193}/LICENSE +0 -0
  14. {ararpy-0.1.191 → ararpy-0.1.193}/README.md +0 -0
  15. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/__init__.py +0 -0
  16. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/age.py +0 -0
  17. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/basic.py +0 -0
  18. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/corr.py +0 -0
  19. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/err.py +0 -0
  20. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/histogram.py +0 -0
  21. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/isochron.py +0 -0
  22. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/jvalue.py +0 -0
  23. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/plot.py +0 -0
  24. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/raw_funcs.py +0 -0
  25. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/regression.py +0 -0
  26. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/calc/spectra.py +0 -0
  27. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/022_VU124-M11a.ahd +0 -0
  28. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/20WHA0103.age +0 -0
  29. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/22WHA0078.xls +0 -0
  30. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/22WHA0433.age +0 -0
  31. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/22WHA0433.arr +0 -0
  32. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/22WHA0433.full.xls +0 -0
  33. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/24WHN0001-51-592.XLS +0 -0
  34. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/AHD.input-filter +0 -0
  35. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/ArAr.calc +0 -0
  36. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/ArArCALC.age +0 -0
  37. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/NGX-600 - Copy.TXT +0 -0
  38. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/NGX-600.TXT +0 -0
  39. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/NGX-XLS.input-filter +0 -0
  40. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/Qtegra-exported-xls.input-filter +0 -0
  41. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/S01-239.csv +0 -0
  42. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/WH01.irra +0 -0
  43. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/WHA.pdf +0 -0
  44. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/raw_example.xls +0 -0
  45. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/examples/sample-default.smp +0 -0
  46. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/__init__.py +0 -0
  47. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/arr_file.py +0 -0
  48. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/basic.py +0 -0
  49. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/files/new_file.py +0 -0
  50. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +0 -0
  51. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/__init__.py +0 -0
  52. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/calculation.py +0 -0
  53. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/consts.py +0 -0
  54. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/corr.py +0 -0
  55. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/diffusion_funcs.py +0 -0
  56. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/info.py +0 -0
  57. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/json.py +0 -0
  58. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/plots.py +0 -0
  59. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/raw.py +0 -0
  60. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/style.py +0 -0
  61. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/smp/table.py +0 -0
  62. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/test.py +0 -0
  63. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/thermo/__init__.py +0 -0
  64. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/thermo/arrhenius.py +0 -0
  65. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/thermo/atomic_level_random_walk.py +0 -0
  66. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy/thermo/basic.py +0 -0
  67. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy.egg-info/SOURCES.txt +0 -0
  68. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy.egg-info/dependency_links.txt +0 -0
  69. {ararpy-0.1.191 → ararpy-0.1.193}/ararpy.egg-info/top_level.txt +0 -0
  70. {ararpy-0.1.191 → ararpy-0.1.193}/setup.cfg +0 -0
  71. {ararpy-0.1.191 → ararpy-0.1.193}/tests/test.py +0 -0
  72. {ararpy-0.1.191 → ararpy-0.1.193}/tests/test2.py +0 -0
  73. {ararpy-0.1.191 → ararpy-0.1.193}/tests/test_error_correlation.py +0 -0
  74. {ararpy-0.1.191 → ararpy-0.1.193}/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.191
3
+ Version: 0.1.193
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,10 +16,10 @@ from . import calc, smp, files, thermo, test
16
16
  """ Information """
17
17
 
18
18
  name = 'ararpy'
19
- version = '0.0.1.a4'
19
+ version = '0.1.193'
20
20
  __version__ = version
21
21
  full_version = version
22
- last_update = '2024-01-04'
22
+ last_update = '2024-03-28'
23
23
 
24
24
  """ ArArPy Functions """
25
25
 
@@ -116,6 +116,8 @@ Sample.plot_cl_3 = lambda _smp: smp.calculation.recalculate(
116
116
  Sample.plot_3D = lambda _smp: smp.calculation.recalculate(
117
117
  _smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_7'])
118
118
 
119
+ Sample.to_excel = lambda _smp, file_path, *args, **kwargs: smp.export.to_excel(_smp, file_path=file_path, *args, **kwargs)
120
+
119
121
  Sample.show_data = lambda _smp: \
120
122
  f"Sample Name: \n\t{_smp.name()}\n" \
121
123
  f"Doi: \n\t{_smp.doi()}\n" \
@@ -514,6 +514,15 @@ def transpose(obj, ignore: bool = True):
514
514
  raise ValueError
515
515
 
516
516
 
517
+ def remove_empty(a: list):
518
+ index = 0
519
+ for i in range(len(a)):
520
+ if not is_empty(a[-(i + 1)]):
521
+ index = len(a) - i
522
+ break
523
+ return transpose(a[:index])
524
+
525
+
517
526
  def get_item(obj: list, loc: (list, tuple, int), default: Union[str, int, float, bool] = None,
518
527
  base: Union[int, tuple, list] = 0) -> Union[str, int, float, bool]:
519
528
  """ Get item from a n-dimension list
@@ -49,8 +49,7 @@ def read_calc_file(file_path: str):
49
49
  book_contents[each_sheet] = sheet_contents
50
50
  os.remove(decrypt_file_path)
51
51
  except Exception as e:
52
- print(traceback.format_exc())
53
- return False
52
+ raise
54
53
  else:
55
54
  return book_contents
56
55
 
@@ -420,7 +419,7 @@ def open_full_xls(file_path: str, sample_name: str = ''):
420
419
  try:
421
420
  res = xls.open_xls(file_path)
422
421
  except (Exception, BaseException) as e:
423
- return e
422
+ raise
424
423
  start_row = 5
425
424
  rows_num = len(res['Sample Parameters']) - 5
426
425
 
@@ -583,8 +582,6 @@ class ArArCalcFile:
583
582
 
584
583
  def open(self):
585
584
  book_contents = read_calc_file(self.file_path)
586
- if not book_contents:
587
- raise ValueError('Fail to open the file')
588
585
  # create data frames for book values
589
586
  content = pd.DataFrame(book_contents['Data Tables'])
590
587
  logs01 = pd.DataFrame(book_contents['Logs01'])
@@ -274,7 +274,7 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
274
274
  raise ValueError(f"Step name not found")
275
275
  except (TypeError, ValueError, IndexError):
276
276
  # When parsing the step name fails, the end of the file has been reached
277
- break
277
+ raise
278
278
 
279
279
  # other information
280
280
  options = get_sample_info(file_contents, optional_info_index, default="", base=[1, 1 - idx, 1])
@@ -20,8 +20,7 @@ def open_xls(filepath: str):
20
20
  sheet = wb.sheet_by_name(sheet_name)
21
21
  res[sheet_name] = [[sheet.cell(row, col).value for col in range(sheet.ncols)] for row in range(sheet.nrows)]
22
22
  except biffh.XLRDError as e:
23
- print('Error in opening excel file: %s' % str(e))
24
- return e
23
+ raise
25
24
  else:
26
25
  return res
27
26
 
@@ -477,7 +477,7 @@ def get_diff_smp(backup: (dict, Sample), smp: (dict, Sample)):
477
477
  # =======================
478
478
  # Set parameters
479
479
  # =======================
480
- def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None):
480
+ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None, rows: Optional[List] =None):
481
481
  """
482
482
  Parameters
483
483
  ----------
@@ -485,84 +485,70 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
485
485
  params
486
486
  flag : optional, should be one of 'calc', 'irra', and 'smp'. If it is not given,
487
487
  the text of the extension without a dot will be used
488
+ rows
488
489
 
489
490
  Returns
490
491
  -------
491
492
 
492
493
  """
494
+ if rows is None:
495
+ rows = []
496
+ rows = list(set(rows))
497
+
493
498
  if isinstance(params, str) and os.path.isfile(params):
494
499
  if flag is None:
495
500
  flag = params.split(".")[-1]
496
501
  return set_params(smp, read_params(params), flag=flag)
497
502
 
498
- def remove_none(old_params, new_params, rows, length):
499
- res = [[] for _ in range(length)]
503
+ def remove_none(old_params, new_params, row_list, length):
504
+ res = [[old_params[i][j] if j < len(old_params[i]) else None for j in range(max(len(old_params[i]), length))] for i in range(len(old_params))]
500
505
  for index, item in enumerate(new_params):
501
- if item is None:
502
- res[index] = old_params[index]
503
- else:
504
- res[index] = [item] * rows
506
+ if item is not None:
507
+ for row in row_list:
508
+ res[index][row] = item
505
509
  return res
506
510
 
507
511
  n = len(smp.SequenceName)
508
-
509
512
  if n == 0:
510
- raise ValueError(f"The number of sample sequences is undefined.")
513
+ raise ValueError(f"The number of sample sequences is zero")
511
514
 
512
515
  if flag == 'calc':
513
- smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22], n, 56 - 34)
514
- smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48], n, 97 - 71)
516
+ smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22], rows, n)
517
+ smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48], rows, n)
515
518
  elif flag == 'irra':
516
- smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20], n, 20 - 0)
517
- smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22], n, 57 - 55) # Cl36/38 productivity
518
- smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29], n, 27 - 20)
519
- # smp.TotalParam[26] = [params[26]] * n
519
+ smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20], rows, n)
520
+ smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22], rows, n) # Cl36/38 productivity
521
+ smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29], rows, n)
520
522
  irradiation_time = []
521
523
  duration = []
522
524
  if None not in params[29:-3] and '' not in params[29:-3]:
523
525
  for i in range(len(params[29:-3])):
524
526
  if i % 2 == 0:
525
- # [d, t] = params[29:-3][i].split('T')
526
- # [t1, t2] = t.split(':')
527
- # irradiation_time.append(d + '-' + t1 + '-' + t2 + 'D' + str(params[29:-3][i + 1]))
528
- text = params[29:-3][i]
529
- for char in ['T', ':']:
530
- text = text.replace(char, '-')
531
527
  irradiation_time.append(params[29:-3][i] + 'D' + str(params[29:-3][i + 1]))
532
528
  duration.append(float(params[29:-3][i + 1]))
533
- smp.TotalParam[27] = ['S'.join(irradiation_time)] * n
534
- smp.TotalParam[28] = [params[-3]] * n
535
- smp.TotalParam[29] = [sum(duration)] * n
529
+ smp.TotalParam[27:30] = remove_none(smp.TotalParam[27:30], ['S'.join(irradiation_time), params[-3], sum(duration)], rows, n)
536
530
  if params[-5] != '':
537
- # [a, b] = params[-5].split('T')
538
- # [b, c] = b.split(':')
539
- # smp.TotalParam[30] = [a + '-' + b + '-' + c] * n
540
- text = params[-5]
541
- for char in ['T', ':']:
542
- text = text.replace(char, '-')
543
- # smp.TotalParam[30] = [text] * n
544
- smp.TotalParam[30] = [params[-5]] * n
531
+ smp.TotalParam[30:32] = remove_none(smp.TotalParam[30:32], [params[-5], None], rows, n)
545
532
  try:
546
533
  stand_time_second = [
547
534
  calc.basic.get_datetime(*re.findall(r"\d+", smp.TotalParam[31][i])) - calc.basic.get_datetime(
548
- *re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(n)]
535
+ *re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(len(smp.TotalParam[30]))]
549
536
  except (BaseException, Exception):
550
537
  print(f'Error in calculate standing duration: {traceback.format_exc()}')
551
- raise
538
+ smp.TotalParam[32] = [None for index in range(n)]
552
539
  else:
553
- smp.TotalParam[32] = [i / (3600 * 24 * 365.242) for i in stand_time_second] # stand year
540
+ smp.TotalParam[32] = [item / (3600 * 24 * 365.242) if index in rows else smp.TotalParam[32][index] for index, item in enumerate(stand_time_second)] # stand year
554
541
 
555
542
  elif flag == 'smp':
556
- print(dict(zip([i for i in range(len(params))], params)))
557
- smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], n, 71 - 67)
558
- smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], n, 67 - 58)
559
- smp.TotalParam[97:100] = remove_none(smp.TotalParam[97:100], params[13:16], n, 100 - 97)
560
- smp.TotalParam[115:120] = remove_none(smp.TotalParam[115:120], params[16:21], n, 120 - 115)
561
- smp.TotalParam[126:136] = remove_none(smp.TotalParam[126:136], params[21:31], n, 136 - 126)
562
- # smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], n, 123 - 120)
543
+ smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], rows, n)
544
+ smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], rows, n)
545
+ smp.TotalParam[97:100] = remove_none(smp.TotalParam[97:100], params[13:16], rows, n)
546
+ smp.TotalParam[115:120] = remove_none(smp.TotalParam[115:120], params[16:21], rows, n)
547
+ smp.TotalParam[126:136] = remove_none(smp.TotalParam[126:136], params[21:31], rows, n)
548
+ # smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], rows, n)
563
549
  smp.TotalParam[100:114] = remove_none(
564
550
  smp.TotalParam[100:114],
565
- [['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], n, 114 - 100)
551
+ [['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
566
552
  pref = dict(zip(preference_keys, params[31:35]))
567
553
  smp.Info.preference.update(pref)
568
554
  for key, comp in get_components(smp).items():
@@ -570,7 +556,6 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
570
556
  comp.decimal_places = pref['decimalPlaces']
571
557
  comp.set_coltypes()
572
558
  smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(pref['ageUnit']).capitalize()})"
573
- print(smp.Info.preference)
574
559
 
575
560
  else:
576
561
  raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
@@ -38,8 +38,8 @@ except ModuleNotFoundError:
38
38
  SETTINGS_ROOT = ""
39
39
 
40
40
 
41
- def to_excel(file_path: str):
42
- excel = WritingWorkbook(filepath=file_path)
41
+ def to_excel(smp: Sample, file_path: str, *args, **kwargs):
42
+ excel = WritingWorkbook(sample=smp, filepath=file_path, *args, **kwargs)
43
43
  excel.get_xls()
44
44
 
45
45
 
@@ -297,6 +297,24 @@ def get_plot_series_data(smp: Sample, diagram: str = 'age spectra', **options):
297
297
  return series
298
298
 
299
299
 
300
+ def spectraData2Sgima(data, sigma=2):
301
+ return list(map(lambda row: [row[0], (row[1] - row[2]) / 2 * (sigma - 1) + row[1], (row[2] - row[1]) / 2 * (sigma - 1) + row[2]], data))
302
+
303
+
304
+ def getRectFromSpectra(data):
305
+ """
306
+ Parameters
307
+ ----------
308
+ data: [x, y1, y2]
309
+
310
+ Returns
311
+ -------
312
+
313
+ """
314
+ 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))))
316
+
317
+
300
318
  def _get_additional_text_series(name):
301
319
  return {
302
320
  'type': 'text', 'id': f'text-{name}-{get_random_digits()}',
@@ -330,22 +348,42 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
330
348
  })
331
349
  text1 = smp.AgeSpectraPlot.text1
332
350
  text2 = smp.AgeSpectraPlot.text2
351
+ sigma = 1
352
+ set_data = [spectraData2Sgima(smp.AgeSpectraPlot.set1.data, sigma),
353
+ spectraData2Sgima(smp.AgeSpectraPlot.set2.data, sigma)]
333
354
  for index, text in enumerate([text1, text2]):
334
- if not np.isnan(smp.Info.results.age_spectra[index]['age']):
355
+ res = smp.Info.results.age_plateau[index]
356
+ if not np.isnan(res['age']):
335
357
  selection = np.array(smp.Info.results.selection[index]['data']) * 2 + 1
336
- set_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))
358
+ plateau_data = np.array(set_data[index])
359
+ # 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))
360
+ spectra_fill_data = getRectFromSpectra(plateau_data)
337
361
  series.append({
338
362
  'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
339
- 'color': 'none', 'fill_color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
340
- 'data': set_data, 'line_caps': 'square', 'fill': True,
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,
365
+ 'axis_index': 0,
366
+ })
367
+ series.append({
368
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
369
+ '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',
372
+ 'axis_index': 0,
373
+ })
374
+ series.append({
375
+ 'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
376
+ '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',
341
379
  'axis_index': 0,
342
380
  })
343
381
  series.append({
344
382
  'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
345
383
  'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index],
346
- 'text': f"WMPA = {smp.Info.results.age_spectra[index]['age']:.2f} ± {(sigma * smp.Info.results.age_spectra[index]['s3']):.2f} Ma<r>"
347
- f"MSWD = {smp.Info.results.age_spectra[index]['MSWD']:.2f}, n = {smp.Info.results.age_spectra[index]['Num']:.0f}<r>"
348
- f"<sup>39</sup>Ar = {smp.Info.results.age_spectra[index]['Ar39']:.2f}%",
384
+ 'text': f"WMPA = {res['age']:.2f} ± {(sigma * res['s3']):.2f} Ma<r>"
385
+ f"MSWD = {res['MSWD']:.2f}, n = {res['Num']:.0f}<r>"
386
+ f"<sup>39</sup>Ar = {res['Ar39']:.2f}%",
349
387
  'size': title_size,
350
388
  'data': [text.pos],
351
389
  'axis_index': 1,
@@ -386,10 +424,15 @@ def _get_plot_data_age_spectra_axis(smp: sample, **options):
386
424
  y_low_limit, y_up_limit, stick_num, inc = get_axis_scale(np.array(data[1:3]).flatten())
387
425
  y_extent = [y_low_limit, y_up_limit]
388
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]
389
432
 
390
- y_extent = [4, 12]
391
- y_interval = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']
392
- y_interval = ['0', '4', '6', '8', '10', '12', '60', '70', '80', '90', '100']
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']
393
436
 
394
437
  xAxis.append({
395
438
  'extent': [0, 100], 'interval': [0, 20, 40, 60, 80, 100], 'id': 0, 'show_frame': True,
@@ -762,16 +805,6 @@ class WritingWorkbook:
762
805
 
763
806
  if self.template_filepath is not None:
764
807
  self.read_template()
765
- if self.style is None:
766
- self.style = {
767
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
768
- 'bg_color': '#FFFFFF', # back ground
769
- 'font_color': '#000000', 'align': 'left',
770
- 'top': 1, 'left': 1, 'right': 1, 'bottom': 1 # border width
771
- }
772
-
773
- def spectraData2Sgima(self, data, sigma=2):
774
- return list(map(lambda row: [row[0], (row[1] - row[2]) / 2 * (sigma - 1) + row[1], (row[2] - row[1]) / 2 * (sigma - 1) + row[2]], data))
775
808
 
776
809
  def read_template(self):
777
810
  # print(self.template_filepath)
@@ -781,7 +814,7 @@ class WritingWorkbook:
781
814
  # TypeError: NAN/INF not supported in write_number() without 'nan_inf_to_errors' Workbook() option
782
815
  xls = Workbook(self.filepath, {"nan_inf_to_errors": True})
783
816
 
784
- style = xls.add_format(self.style)
817
+ style = xls.add_format(self.default_fmt_prop)
785
818
 
786
819
  sigma = int(self.sample.Info.preference['confidenceLevel'])
787
820
 
@@ -809,9 +842,9 @@ class WritingWorkbook:
809
842
 
810
843
  # Data for age spectra
811
844
  try:
812
- spectra_data = arr.transpose(self.spectraData2Sgima(self.sample.AgeSpectraPlot.data, sigma))
813
- spectra_set1_data = arr.transpose(self.spectraData2Sgima(self.sample.AgeSpectraPlot.set1.data, sigma)) or [[]] * 3
814
- spectra_set2_data = arr.transpose(self.spectraData2Sgima(self.sample.AgeSpectraPlot.set2.data, sigma)) or [[]] * 3
845
+ spectra_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.data, sigma))
846
+ spectra_set1_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.set1.data, sigma)) or [[]] * 3
847
+ spectra_set2_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.set2.data, sigma)) or [[]] * 3
815
848
  sht_reference.write_column(f"A{start_row}", spectra_data[0], style)
816
849
  sht_reference.write_column(f"B{start_row}", spectra_data[1], style)
817
850
  sht_reference.write_column(f"C{start_row}", spectra_data[2], style)
@@ -1046,27 +1079,27 @@ class WritingWorkbook:
1046
1079
  set2_ratio = [self.sample.Info.results.isochron['figure_3'][1]['initial'], self.sample.Info.results.isochron['figure_2'][1]['initial'], self.sample.TotalParam[118][0]][int(self.sample.TotalParam[115][0])]
1047
1080
 
1048
1081
  content = [
1049
- [(0, 0, 0, 14), f"Table 1. 40Ar/39Ar dating results", {'bold': 1, 'top': 1, 'bottom': 1, 'align': 'left'}],
1050
- [(1, 0, 2, 0), f"Step", {'bold': 1}],
1051
- [(1, 1), f"{sequence_type}", {'bold': 1}],
1052
- [(2, 1), f"({sequence_unit})", {'bold': 1}],
1053
- [(1, 2, 2, 2), f"Set", {'bold': 1}],
1054
- [(1, 3, 2, 3), f"36Arair", {'bold': 1}],
1055
- [(1, 4, 2, 4), f"36ArCa", {'bold': 1}],
1056
- [(1, 5, 2, 5), f"36ArCl", {'bold': 1}],
1057
- [(1, 6, 2, 6), f"36ArK", {'bold': 1}],
1058
- [(1, 7, 2, 7), f"36Ar*", {'bold': 1}],
1059
- [(1, 8, 2, 8), f"39Ar/40Ar", {'bold': 1}],
1060
- [(1, 9, 2, 9), f"36Ar/40Ar", {'bold': 1}],
1061
- [(1, 10), f"Apparent Age", {'bold': 1}],
1062
- [(1, 11), f"± {sigma} σ", {'bold': 1}],
1063
- [(2, 10, 2, 11), f"({age_unit})", {'bold': 1}],
1064
- [(1, 12), f"40Ar*", {'bold': 1}],
1065
- [(2, 12), f"(%)", {'bold': 1}],
1066
- [(1, 13), f"39ArK", {'bold': 1}],
1067
- [(2, 13), f"(%)", {'bold': 1}],
1068
- [(1, 14, 2, 14), f"Ca/K", {'bold': 1}],
1069
- [(3, 0, 3, 14), f"Sample {name} ({material}){' by ' if method != '' else ''}{method}, weight = {weight} mg, J = {J_value} ± {J_error}", {'bold': 1, 'italic': 1, 'top': 6, 'align': 'left'}],
1082
+ [(0, 0), f"Table 1. 40Ar/39Ar dating results", {'bold': 1, 'top': 1, 'align': 'left'}],
1083
+ [(1, 0, 2, 0), f"Step", {'bold': 1, 'top': 1, 'bottom': 6}],
1084
+ [(1, 1), f"{sequence_type}", {'bold': 1, 'top': 1}],
1085
+ [(2, 1), f"({sequence_unit})", {'bold': 1, 'bottom': 6}],
1086
+ [(1, 2, 2, 2), f"Set", {'bold': 1, 'top': 1, 'bottom': 6}],
1087
+ [(1, 3, 2, 3), f"36Arair", {'bold': 1, 'top': 1, 'bottom': 6}],
1088
+ [(1, 4, 2, 4), f"37ArCa", {'bold': 1, 'top': 1, 'bottom': 6}],
1089
+ [(1, 5, 2, 5), f"38ArCl", {'bold': 1, 'top': 1, 'bottom': 6}],
1090
+ [(1, 6, 2, 6), f"39ArK", {'bold': 1, 'top': 1, 'bottom': 6}],
1091
+ [(1, 7, 2, 7), f"40Ar*", {'bold': 1, 'top': 1, 'bottom': 6}],
1092
+ [(1, 8, 2, 8), f"39Ar/40Ar", {'bold': 1, 'top': 1, 'bottom': 6}],
1093
+ [(1, 9, 2, 9), f"36Ar/40Ar", {'bold': 1, 'top': 1, 'bottom': 6}],
1094
+ [(1, 10), f"Apparent Age", {'bold': 1, 'top': 1}],
1095
+ [(1, 11), f"± {sigma} σ", {'bold': 1, 'top': 1}],
1096
+ [(2, 10, 2, 11), f"({age_unit})", {'bold': 1, 'bottom': 6}],
1097
+ [(1, 12), f"40Ar*", {'bold': 1, 'top': 1}],
1098
+ [(2, 12), f"(%)", {'bold': 1, 'bottom': 6}],
1099
+ [(1, 13), f"39ArK", {'bold': 1, 'top': 1}],
1100
+ [(2, 13), f"(%)", {'bold': 1, 'bottom': 6}],
1101
+ [(1, 14, 2, 14), f"Ca/K", {'bold': 1, 'top': 1, 'bottom': 6}],
1102
+ [(3, 0), f"Sample {name} ({material}){' by ' if method != '' else ''}{method}, weight = {weight} mg, J = {J_value} ± {J_error}", {'bold': 1, 'italic': 1, 'align': 'left'}],
1070
1103
  [(4, 0, 1), self.sample.SequenceName, {'align': 'left'}],
1071
1104
  [(4, 1, 1), self.sample.SequenceValue, {'num_format': 'General'}],
1072
1105
  [(4, 2, 1), list(map(lambda x: int(x) if str(x).isnumeric() else "", self.sample.IsochronMark)), {'num_format': 'General'}],
@@ -1084,7 +1117,7 @@ class WritingWorkbook:
1084
1117
  [(4, 14, 1), self.sample.PublishValues[9], {}],
1085
1118
  [(4 + num_step, 0, 0), [''] * 15, {'bold': 1, 'top': 1}],
1086
1119
 
1087
- [(5 + num_step, 0, 5 + num_step, 8), "Table 2. 40Ar/39Ar age summary", {'bold': 1, 'align': 'left'}],
1120
+ [(5 + num_step, 0), "Table 2. 40Ar/39Ar age summary", {'bold': 1, 'align': 'left'}],
1088
1121
  [(6 + num_step, 0, 7 + num_step, 0), "Group", {'bold': 1, 'top': 1}],
1089
1122
  [(6 + num_step, 1, 7 + num_step, 1), "40Arr/39K", {'bold': 1, 'top': 1}],
1090
1123
  [(6 + num_step, 2, 7 + num_step, 2), f"± {sigma} σ", {'bold': 1, 'top': 1}],
@@ -183,7 +183,10 @@ def initial(smp: Sample):
183
183
  reference=ArArBasic(
184
184
  name='REFERENCE', journal='JOURNAL', doi='DOI'
185
185
  ),
186
- preference=copy.deepcopy(PREFERENCE_RES)
186
+ preference=copy.deepcopy(PREFERENCE_RES),
187
+ experiment=ArArBasic(
188
+ name='', mass_spec='', collectors='', step_num=0
189
+ ),
187
190
  ))
188
191
 
189
192
  decimal_places = PREFERENCE_RES['decimalPlaces']
@@ -284,6 +287,9 @@ def check_version(smp: Sample):
284
287
  """
285
288
  if smp.version != samples.VERSION:
286
289
  re_set_smp(smp)
290
+ if int(smp.version) <= 20250328: # Experiment info
291
+ smp.Info.experiment.name = smp.name()
292
+ smp.Info.experiment.step_num = smp.sequence().size
287
293
  return smp
288
294
 
289
295
 
@@ -329,11 +335,8 @@ def from_arr_files(file_path, sample_name: str = ""):
329
335
  def renamed_load(file_obj):
330
336
  return RenameUnpickler(file_obj).load()
331
337
 
332
- try:
333
- with open(file_path, 'rb') as f:
334
- sample = renamed_load(f)
335
- except (Exception, BaseException):
336
- raise ValueError(f"Fail to open arr file: {file_path}")
338
+ with open(file_path, 'rb') as f:
339
+ sample = renamed_load(f)
337
340
  # Check arr version
338
341
  # recalculation will not be applied automatically
339
342
  return check_version(sample)
@@ -743,7 +743,7 @@ DEFAULT_PLOT_STYLES = {
743
743
  },
744
744
  }
745
745
 
746
- VERSION = '20250321'
746
+ VERSION = '20250328'
747
747
 
748
748
  NAMED_DICT = {
749
749
  "unknown": {"header": SAMPLE_INTERCEPT_HEADERS.copy()},
@@ -847,8 +847,9 @@ class Sample:
847
847
  # self.__version = '20240730' # change parameter table for thermo calculation
848
848
  # self.__version = '20241028' # gain correction
849
849
  # self.__version = '20250102' # gain correction to blanks
850
+ # self.__version = '20250301' # update sample info
850
851
  # self.__version = '20250321' # error sigma adjustment
851
- self.__version = '20250301' # update sample info
852
+ self.__version = '20250328' # Experiment info
852
853
 
853
854
  @property
854
855
  def version(self):
@@ -930,7 +931,7 @@ class Sample:
930
931
 
931
932
  def show_data(self): ...
932
933
 
933
- def set_params(self, params: Union[List, str], flag: Optional[str] = None): ...
934
+ def set_params(self, params: Union[List, str], flag: Optional[str] = None, rows: Optional[List] = None): ...
934
935
 
935
936
  def set_info(self, info: dict): ...
936
937
 
@@ -938,6 +939,8 @@ class Sample:
938
939
 
939
940
  def to_pdf(self, file_path: str, figure: str = "figure_3"): ...
940
941
 
942
+ def to_excel(self, file_path: str, *args, **kwargs): ...
943
+
941
944
 
942
945
  class Table:
943
946
  def __init__(self, id='', name='Table', colcount=None, rowcount=None, header=None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ararpy
3
- Version: 0.1.191
3
+ Version: 0.1.193
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.191', # version
19
+ version='0.1.193', # 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