ararpy 0.1.191__py3-none-any.whl → 0.1.195__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ararpy/__init__.py CHANGED
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
16
16
  """ Information """
17
17
 
18
18
  name = 'ararpy'
19
- version = '0.0.1.a4'
19
+ version = '0.1.195'
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" \
ararpy/calc/arr.py CHANGED
@@ -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
@@ -566,7 +575,7 @@ def wtd_mean(a: list, e: list, sf: int = 1, adjust_error: bool = True):
566
575
  k0 = sum(a * wt) / sum(wt) # error weighting
567
576
  k4 = sum((a - k0) ** 2 * wt) # Chi square
568
577
  k3 = k4 / df # MSWD mentioned in Min et al., 2000
569
- if adjust_error:
578
+ if adjust_error and k3 > 1:
570
579
  k1 = (k3 / sum(wt)) ** .5
571
580
  else:
572
581
  k1 = (1 / sum(wt)) ** .5
ararpy/files/calc_file.py CHANGED
@@ -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'])
ararpy/files/raw_file.py CHANGED
@@ -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])
ararpy/files/xls.py CHANGED
@@ -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
 
ararpy/smp/basic.py CHANGED
@@ -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,76 @@ 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 isValid(item):
504
+ valid = True
505
+ if isinstance(item, (float, int)):
506
+ valid = not np.isnan(item)
507
+ return valid and item is not None and item != ""
508
+
509
+ def remove_none(old_params, new_params, row_list, length):
510
+ 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
511
  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
512
+ if isValid(item):
513
+ for row in row_list:
514
+ res[index][row] = item
505
515
  return res
506
516
 
507
517
  n = len(smp.SequenceName)
508
-
509
518
  if n == 0:
510
- raise ValueError(f"The number of sample sequences is undefined.")
519
+ raise ValueError(f"The number of sample sequences is zero")
511
520
 
512
521
  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)
522
+ smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22], rows, n)
523
+ smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48], rows, n)
515
524
  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
525
+ smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20], rows, n)
526
+ smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22], rows, n) # Cl36/38 productivity
527
+ smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29], rows, n)
520
528
  irradiation_time = []
521
529
  duration = []
522
530
  if None not in params[29:-3] and '' not in params[29:-3]:
523
531
  for i in range(len(params[29:-3])):
524
532
  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
533
  irradiation_time.append(params[29:-3][i] + 'D' + str(params[29:-3][i + 1]))
532
534
  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
535
+ smp.TotalParam[27:30] = remove_none(smp.TotalParam[27:30], ['S'.join(irradiation_time), params[-3], sum(duration)], rows, n)
536
536
  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
537
+ smp.TotalParam[30:32] = remove_none(smp.TotalParam[30:32], [params[-5], None], rows, n)
545
538
  try:
546
539
  stand_time_second = [
547
540
  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)]
541
+ *re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(len(smp.TotalParam[30]))]
549
542
  except (BaseException, Exception):
550
543
  print(f'Error in calculate standing duration: {traceback.format_exc()}')
551
- raise
544
+ smp.TotalParam[32] = [None for index in range(n)]
552
545
  else:
553
- smp.TotalParam[32] = [i / (3600 * 24 * 365.242) for i in stand_time_second] # stand year
546
+ 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
547
 
555
548
  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)
549
+ smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], rows, n)
550
+ smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], rows, n)
551
+ smp.TotalParam[97:100] = remove_none(smp.TotalParam[97:100], params[13:16], rows, n)
552
+ smp.TotalParam[115:120] = remove_none(smp.TotalParam[115:120], params[16:21], rows, n)
553
+ smp.TotalParam[126:136] = remove_none(smp.TotalParam[126:136], params[21:31], rows, n)
554
+ # smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], rows, n)
563
555
  smp.TotalParam[100:114] = remove_none(
564
556
  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)
557
+ [['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
566
558
  pref = dict(zip(preference_keys, params[31:35]))
567
559
  smp.Info.preference.update(pref)
568
560
  for key, comp in get_components(smp).items():
@@ -570,7 +562,6 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
570
562
  comp.decimal_places = pref['decimalPlaces']
571
563
  comp.set_coltypes()
572
564
  smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(pref['ageUnit']).capitalize()})"
573
- print(smp.Info.preference)
574
565
 
575
566
  else:
576
567
  raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
ararpy/smp/corr.py CHANGED
@@ -349,7 +349,7 @@ def calc_degas_r(sample: Sample):
349
349
  """
350
350
  ar40ar = calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32])
351
351
  ar40r = calc.arr.sub(ar40ar, sample.DegasValues[26:28])
352
- ar40r[0] = [item if item >= 0 else 0 for item in ar40r[0]]
352
+ ar40r[0] = [0 if item < 0 and sample.TotalParam[101][index] else item for index, item in enumerate(ar40r[0])]
353
353
  sample.DegasValues[24:26] = copy.deepcopy(ar40r)
354
354
  sample.PublishValues[4] = copy.deepcopy(ar40r[0])
355
355
 
ararpy/smp/export.py CHANGED
@@ -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)
@@ -1036,7 +1069,7 @@ class WritingWorkbook:
1036
1069
  material = self.sample.Info.sample.material
1037
1070
  weight = self.sample.Info.sample.weight
1038
1071
  J_value = self.sample.TotalParam[67][0]
1039
- J_error = self.sample.TotalParam[68][0]
1072
+ J_error = self.sample.TotalParam[68][0] * self.sample.TotalParam[67][0] / 100
1040
1073
  sigma = self.sample.Info.preference['confidenceLevel']
1041
1074
  sequence_type = {"StepLaser": "Laser", "StepFurnace": "Temperature", "StepCrusher": "Drop", }.get(method, "Step Value")
1042
1075
  sequence_unit = self.sample.Info.sample.sequence_unit if self.sample.Info.sample.sequence_unit != "" else "Unit"
@@ -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}],
ararpy/smp/initial.py CHANGED
@@ -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']
@@ -265,10 +268,10 @@ def initial_plot_styles(sample: Sample, except_attrs=None):
265
268
  set_attr(plot, key, attr)
266
269
 
267
270
 
268
- def re_set_smp(sample: Sample):
271
+ def re_set_smp(smp: Sample):
269
272
  std = initial(Sample())
270
- basic.get_merged_smp(sample, std)
271
- return sample
273
+ basic.get_merged_smp(smp, std)
274
+ return check_version(smp)
272
275
 
273
276
 
274
277
  def check_version(smp: Sample):
@@ -283,7 +286,11 @@ def check_version(smp: Sample):
283
286
 
284
287
  """
285
288
  if smp.version != samples.VERSION:
286
- re_set_smp(smp)
289
+ std = initial(Sample())
290
+ basic.get_merged_smp(smp, std)
291
+ # if int(smp.version) <= 20250328: # Experiment info
292
+ smp.Info.experiment.name = smp.name()
293
+ smp.Info.experiment.step_num = smp.sequence().size
287
294
  return smp
288
295
 
289
296
 
@@ -329,11 +336,8 @@ def from_arr_files(file_path, sample_name: str = ""):
329
336
  def renamed_load(file_obj):
330
337
  return RenameUnpickler(file_obj).load()
331
338
 
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}")
339
+ with open(file_path, 'rb') as f:
340
+ sample = renamed_load(f)
337
341
  # Check arr version
338
342
  # recalculation will not be applied automatically
339
343
  return check_version(sample)
@@ -353,7 +357,7 @@ def from_calc_files(file_path: str, **kwargs):
353
357
  """
354
358
  file = calc_file.ArArCalcFile(file_path=file_path, **kwargs).open()
355
359
  sample = create_sample_from_df(file.get_content(), file.get_smp_info())
356
- return sample
360
+ return check_version(sample)
357
361
 
358
362
 
359
363
  # create
@@ -372,7 +376,7 @@ def from_full_files(file_path: str, sample_name: str = None):
372
376
  sample_name = str(os.path.split(file_path)[-1]).split('.')[0]
373
377
  content, sample_info = calc_file.open_full_xls(file_path, sample_name)
374
378
  sample = create_sample_from_dict(content=content, smp_info=sample_info)
375
- return sample
379
+ return check_version(sample)
376
380
 
377
381
 
378
382
  # create
@@ -450,4 +454,4 @@ def from_raw_data(raw: RawData, mapping: Optional[List[dict]] = None) -> Sample:
450
454
 
451
455
  # sample.TotalParam[31] = [raw.get_sequence(row['unknown'], flag='name').datetime for row in mapping]
452
456
 
453
- return sample
457
+ return check_version(sample)
ararpy/smp/sample.py CHANGED
@@ -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.195
4
4
  Summary: A project for Ar-Ar geochronology
5
5
  Home-page: https://github.com/wuyangchn/ararpy.git
6
6
  Author: Yang Wu
@@ -1,8 +1,8 @@
1
- ararpy/__init__.py,sha256=abmIxFaRq9m7mUI66xHbMGD2wRdzV9v8FAgvlViIlTc,6733
1
+ ararpy/__init__.py,sha256=kHlsop1f9Gs6d_F7G0JhTvhjwahHtgf73991YlqIAWs,6858
2
2
  ararpy/test.py,sha256=4F46-JJ1Ge12HGae0qO44Qc6kiEMHBgn2MsY_5LlHDo,3973
3
3
  ararpy/calc/__init__.py,sha256=kUjRuLE8TLuKOv3i976RnGJoEMj23QBZDu37LWs81U4,322
4
4
  ararpy/calc/age.py,sha256=POBF_UxfXM_GCfXR_sTE__-fOvYZleNXXSuR_SIrFrI,5782
5
- ararpy/calc/arr.py,sha256=w31bn6MXF8I8qPXYo5kI-TfMKCYspx1rZ5g_UpwwSd8,14939
5
+ ararpy/calc/arr.py,sha256=vrjerWuP-2VlMshoOPyOYvBnbHifkhdRISYfOD06ZZk,15149
6
6
  ararpy/calc/basic.py,sha256=uJCCUFaPd9zvfkggrdbFYSGLl2pt7UJ7ENgXanzHy68,4036
7
7
  ararpy/calc/corr.py,sha256=HnCbf_84gKD6vMX7PflZym-I1MezRKfNHYfEtkDCCaI,18598
8
8
  ararpy/calc/err.py,sha256=63LtprqjemlIb1QGDst4Ggcv5KMSDHdlAIL-nyQs1eA,2691
@@ -35,32 +35,32 @@ ararpy/examples/sample-default.smp,sha256=YNkoQGgPrsL_fXS7ZHxfRtLQWekCDqT9czS6vB
35
35
  ararpy/files/__init__.py,sha256=l5B5ZQ01WdtvjjN0aMkyAFNgpwANdM_1I0tQbqnRuEY,69
36
36
  ararpy/files/arr_file.py,sha256=KqksGlEA6nmMQofTgi7v45flscQZVtefxaNCKrV3Am4,837
37
37
  ararpy/files/basic.py,sha256=nc7Hgo_qLSkdmtKzZmd5SQ8Jy0dhW46ly4gh-oisUDs,2095
38
- ararpy/files/calc_file.py,sha256=Mww0R1RH3BpTCo6EetW9jikd19G6-Ljhgak5PXccRfA,28341
38
+ ararpy/files/calc_file.py,sha256=nqv_VfbOzz8ejcnjNoHJafGiYldhYSOLusUGtuZ8jR0,28207
39
39
  ararpy/files/new_file.py,sha256=efblARIBROVLWS2w3-98BxLX5VZ8grRpiTkJFtf_rAk,214
40
- ararpy/files/raw_file.py,sha256=A0DnCn7dL5eUZTgEwevlDgLsEMWrRmtuBzzPlWoBxAQ,22302
41
- ararpy/files/xls.py,sha256=8ibT4ZRY2grK34ikKm1pDmlWFlVTgDL7vSMO6mphzrY,702
40
+ ararpy/files/raw_file.py,sha256=5hnZMS7r78lA0ZXrBEN5SWVurQyl0QsHOI9rJz5BQv8,22302
41
+ ararpy/files/xls.py,sha256=DVcZ_yRnc19p-m4leGGjt-YPDpSa2udYKmGyrM0qub0,640
42
42
  ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py,sha256=baDM437tu6hsPv0uYfod0TREXlPd6kvMBFT1S9ZZlkk,3024
43
43
  ararpy/smp/__init__.py,sha256=k6_fa27UJsQK7K7oC5GYlwMo6l0Xd8af3QtOrZz2XJk,478
44
- ararpy/smp/basic.py,sha256=1zsBznVojY-SFAjq_1tkHxvpI9-mD_uotcrd9aDd6n4,22923
44
+ ararpy/smp/basic.py,sha256=k9Vk_LP6P9HO68gMvPQ-adkvaVXEobg1FY-rF5YG7HQ,22588
45
45
  ararpy/smp/calculation.py,sha256=LCFJWjLVLEKEQ5b7RFUIxsMahEzgLdodW4kCYXV5Z34,2919
46
46
  ararpy/smp/consts.py,sha256=XIdjdz8cYxspG2jMnoItdlUsxr3hKbNFJjMZJh1bpzw,393
47
- ararpy/smp/corr.py,sha256=1MDH41TsBVyuyI45mqaqP2IvEm_jAUMZgR0MG7uNiu4,25598
47
+ ararpy/smp/corr.py,sha256=D3Ac2iUq3FjzKZR8yhnMLpG__YVEbtyVVfly873m6xc,25649
48
48
  ararpy/smp/diffusion_funcs.py,sha256=4-PMMIZWzjk2HOYYWNgSp4GmApygp1MmOxJ2g3xrqWc,175049
49
- ararpy/smp/export.py,sha256=V_7BsWAQq0I8no3ME62Tva-8DwlCa7LP3xuyz5oYE1Y,113455
49
+ ararpy/smp/export.py,sha256=s89L5B1aHoCeJIjcw6nXA6NtV0j_5XXaWnOETWnomCs,115043
50
50
  ararpy/smp/info.py,sha256=iKUELm-BuUduDlJKC1d8tKKNHbwwbNmhUg2pi6bcBvA,489
51
- ararpy/smp/initial.py,sha256=bB_bJcUx8DkjXQsM77jgD68pWK-4KFr9sjobCgSNN6w,16064
51
+ ararpy/smp/initial.py,sha256=x4zBFXnNKFzuQEWrfBp9Z7LMHxtzr9ASBf-Dnqc_IEA,16304
52
52
  ararpy/smp/json.py,sha256=BTZCjVN0aj9epc700nwkYEYMKN2lHBYo-pLmtnz5oHY,2300
53
53
  ararpy/smp/plots.py,sha256=u4gUSTfLO6rErQDp3N0hyBf2uc-8CUfITlAtnpN3DG8,31722
54
54
  ararpy/smp/raw.py,sha256=51n-rrbW2FqeZHQyevuG7iObPLGvIBzTe414QDVM1FE,6523
55
- ararpy/smp/sample.py,sha256=6ly0Y9OKtrAADm6yx0nOf4rwjRyK5DPF6DYenb_dda4,55702
55
+ ararpy/smp/sample.py,sha256=Mt6SC8p0AOiuafvwsTsW3IM4BDfV2GL2yunTvffELvM,55853
56
56
  ararpy/smp/style.py,sha256=Z4exOAdtvw5xwDf6nyIjPxuvww2U5JK6H_Ql02DBSyM,7030
57
57
  ararpy/smp/table.py,sha256=9bNAOqAIOc0nSC3LNeqjJKUYSJSM28Ji3o9VimwMU8A,6645
58
58
  ararpy/thermo/__init__.py,sha256=6VBuqTRFl403PVqOuMkVrut0nKaQsAosBmfW91X1dMg,263
59
59
  ararpy/thermo/arrhenius.py,sha256=Ass1ichHfqIAtpv8eLlgrUc1UOb3Urh1qzr1E3gLB4U,233
60
60
  ararpy/thermo/atomic_level_random_walk.py,sha256=Q97zfe2h2RaxADkoBAqd0uEiP16BFOajrTmXHMkL2EQ,25502
61
61
  ararpy/thermo/basic.py,sha256=nBGHI9uK7VdJwThwBIOcKAzdnYqPyQseFoY6s4zKizk,11504
62
- ararpy-0.1.191.dist-info/licenses/LICENSE,sha256=cvG5t_C1qY_zUyJI7sNOa7gCArdngNPaOrfujl2LYuc,1085
63
- ararpy-0.1.191.dist-info/METADATA,sha256=MMszQhjI3GBNB83U8dhpQFnvVPZ72q7p2qHgwahMbjA,24517
64
- ararpy-0.1.191.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
65
- ararpy-0.1.191.dist-info/top_level.txt,sha256=9iTpsPCYuRYq09yQTk9d2lqB8JtTEOmbN-IcGB-K3vY,7
66
- ararpy-0.1.191.dist-info/RECORD,,
62
+ ararpy-0.1.195.dist-info/licenses/LICENSE,sha256=cvG5t_C1qY_zUyJI7sNOa7gCArdngNPaOrfujl2LYuc,1085
63
+ ararpy-0.1.195.dist-info/METADATA,sha256=GVX2BTS_XSVYOwfWyGP1wcRbtly3ESqicOA-g_Afxao,24517
64
+ ararpy-0.1.195.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
65
+ ararpy-0.1.195.dist-info/top_level.txt,sha256=9iTpsPCYuRYq09yQTk9d2lqB8JtTEOmbN-IcGB-K3vY,7
66
+ ararpy-0.1.195.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5