ararpy 0.1.18__py3-none-any.whl → 0.1.20__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/smp/export.py CHANGED
@@ -12,6 +12,7 @@ from re import findall
12
12
  from xlsxwriter.workbook import Workbook
13
13
  from xlsxwriter.worksheet import Worksheet
14
14
  from xlsxwriter.chartsheet import Chartsheet
15
+ from xlsxwriter.format import Format
15
16
  import os
16
17
  import sys
17
18
  import pickle
@@ -37,8 +38,8 @@ except ModuleNotFoundError:
37
38
  SETTINGS_ROOT = ""
38
39
 
39
40
 
40
- def to_excel(file_path: str):
41
- 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)
42
43
  excel.get_xls()
43
44
 
44
45
 
@@ -296,6 +297,24 @@ def get_plot_series_data(smp: Sample, diagram: str = 'age spectra', **options):
296
297
  return series
297
298
 
298
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
+
299
318
  def _get_additional_text_series(name):
300
319
  return {
301
320
  'type': 'text', 'id': f'text-{name}-{get_random_digits()}',
@@ -329,22 +348,42 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
329
348
  })
330
349
  text1 = smp.AgeSpectraPlot.text1
331
350
  text2 = smp.AgeSpectraPlot.text2
351
+ sigma = 1
352
+ set_data = [spectraData2Sgima(smp.AgeSpectraPlot.set1.data, sigma),
353
+ spectraData2Sgima(smp.AgeSpectraPlot.set2.data, sigma)]
332
354
  for index, text in enumerate([text1, text2]):
333
- 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']):
334
357
  selection = np.array(smp.Info.results.selection[index]['data']) * 2 + 1
335
- 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)
336
361
  series.append({
337
362
  'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
338
- 'color': 'none', 'fill_color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
339
- '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',
340
379
  'axis_index': 0,
341
380
  })
342
381
  series.append({
343
382
  'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
344
383
  'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index],
345
- 'text': f"WMPA = {smp.Info.results.age_spectra[index]['age']:.2f} ± {(sigma * smp.Info.results.age_spectra[index]['s3']):.2f} Ma<r>"
346
- f"MSWD = {smp.Info.results.age_spectra[index]['MSWD']:.2f}, n = {smp.Info.results.age_spectra[index]['Num']:.0f}<r>"
347
- 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}%",
348
387
  'size': title_size,
349
388
  'data': [text.pos],
350
389
  'axis_index': 1,
@@ -385,10 +424,15 @@ def _get_plot_data_age_spectra_axis(smp: sample, **options):
385
424
  y_low_limit, y_up_limit, stick_num, inc = get_axis_scale(np.array(data[1:3]).flatten())
386
425
  y_extent = [y_low_limit, y_up_limit]
387
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]
388
432
 
389
- y_extent = [4, 12]
390
- y_interval = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']
391
- 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']
392
436
 
393
437
  xAxis.append({
394
438
  'extent': [0, 100], 'interval': [0, 20, 40, 60, 80, 100], 'id': 0, 'show_frame': True,
@@ -750,22 +794,17 @@ class WritingWorkbook:
750
794
  self.axis_font_bold = False
751
795
  self.axis_num_font_size = 10
752
796
  self.line_width = 1.25
797
+ self.default_fmt_prop = {
798
+ 'font_name': 'Times New Roman', "font_size": 10, 'num_format': '0.000000',
799
+ 'align': 'center', 'valign': 'vcenter',
800
+ }
801
+ self.formats = {'default': Format({'font_name': 'Times New Roman', "font_size": 10, })}
753
802
 
754
803
  for key, value in kwargs.items():
755
804
  setattr(self, key, value)
756
805
 
757
806
  if self.template_filepath is not None:
758
807
  self.read_template()
759
- if self.style is None:
760
- self.style = {
761
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
762
- 'bg_color': '#FFFFFF', # back ground
763
- 'font_color': '#000000', 'align': 'left',
764
- 'top': 1, 'left': 1, 'right': 1, 'bottom': 1 # border width
765
- }
766
-
767
- def spectraData2Sgima(self, data, sigma=2):
768
- 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))
769
808
 
770
809
  def read_template(self):
771
810
  # print(self.template_filepath)
@@ -774,7 +813,8 @@ class WritingWorkbook:
774
813
  def get_xls(self):
775
814
  # TypeError: NAN/INF not supported in write_number() without 'nan_inf_to_errors' Workbook() option
776
815
  xls = Workbook(self.filepath, {"nan_inf_to_errors": True})
777
- style = xls.add_format(self.style)
816
+
817
+ style = xls.add_format(self.default_fmt_prop)
778
818
 
779
819
  sigma = int(self.sample.Info.preference['confidenceLevel'])
780
820
 
@@ -802,9 +842,9 @@ class WritingWorkbook:
802
842
 
803
843
  # Data for age spectra
804
844
  try:
805
- spectra_data = arr.transpose(self.spectraData2Sgima(self.sample.AgeSpectraPlot.data, sigma))
806
- spectra_set1_data = arr.transpose(self.spectraData2Sgima(self.sample.AgeSpectraPlot.set1.data, sigma)) or [[]] * 3
807
- 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
808
848
  sht_reference.write_column(f"A{start_row}", spectra_data[0], style)
809
849
  sht_reference.write_column(f"B{start_row}", spectra_data[1], style)
810
850
  sht_reference.write_column(f"C{start_row}", spectra_data[2], style)
@@ -987,227 +1027,7 @@ class WritingWorkbook:
987
1027
  pass
988
1028
 
989
1029
  # write result sheet
990
- sht_result = xls.add_worksheet('Results')
991
- title_fmt = xls.add_format({
992
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': True,
993
- 'bg_color': '#ccffff', 'font_color': '#0000ff', 'valign': 'vcenter', 'align': 'center',
994
- 'top': 0, 'bottom': 0 # border width
995
- })
996
- title_fmt_2 = xls.add_format({
997
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': True,
998
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'left',
999
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1000
- })
1001
- two_decimal_fmt = xls.add_format({
1002
- 'num_format': '0.00',
1003
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1004
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1005
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1006
- })
1007
- five_decimal_fmt = xls.add_format({
1008
- 'num_format': '0.00000',
1009
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1010
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1011
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1012
- })
1013
- error_fmt = xls.add_format({
1014
- 'num_format': '± 0.00',
1015
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1016
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1017
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1018
- })
1019
- five_error_fmt = xls.add_format({
1020
- 'num_format': '± 0.00000',
1021
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1022
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1023
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1024
- })
1025
- percent_fmt = xls.add_format({
1026
- 'num_format': '± 0.00%',
1027
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1028
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1029
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1030
- })
1031
- int_fmt = xls.add_format({
1032
- 'num_format': '0',
1033
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1034
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
1035
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1036
- })
1037
- string_fmt = xls.add_format({
1038
- 'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
1039
- 'font_color': '#000000', 'valign': 'vcenter', 'align': 'right', 'text_wrap': False,
1040
- 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
1041
- })
1042
- # two_decimal_fmt.set_text_wrap()
1043
- sht_result.set_column(0, 21, width=8.5) # column width
1044
- sht_result.set_column(10, 11, width=3) # column width
1045
- sht_result.merge_range(0, 0, 1, 9, 'Sample Information', title_fmt)
1046
- title_list = [
1047
- [7, 0, 8, 0, 'Result'], [7, 1, 8, 1, ''], [7, 2, 8, 2, '40(r)/39(k)'], [7, 3, 8, 3, f'{sigma}σ'],
1048
- [7, 5, 8, 5, f'{sigma}σ'],
1049
- [7, 6, 8, 6, 'MSWD'], [7, 7, 8, 7, '39Ar(K)'], [7, 8, 8, 8, 'Ca/K'], [7, 9, 8, 9, f'{sigma}σ'],
1050
- [7, 12, 8, 12, 'Result'], [7, 13, 8, 13, ''], [7, 14, 8, 14, '40(r)/39(k)'], [7, 15, 8, 15, f'{sigma}σ'],
1051
- [7, 16, 8, 16, 'Age'], [7, 17, 8, 17, f'{sigma}σ'],
1052
- [7, 18, 8, 18, 'MSWD'], [7, 20, 8, 20, 'Ca/K'], [7, 21, 8, 21, f'{sigma}σ'],
1053
- ]
1054
- data_list = [
1055
- [3, 0, 3, 2, f"Sample = {self.sample.Info.sample.name}"],
1056
- [3, 3, 3, 5, f"Material = {self.sample.Info.sample.material}"],
1057
- [3, 6, 3, 8, f"Irradiation = {self.sample.TotalParam[28][0]}"],
1058
- [4, 0, 4, 2, f"Analyst = {self.sample.Info.laboratory.analyst}"],
1059
- [4, 3, 4, 5, f"Researcher = {self.sample.Info.researcher.name}"],
1060
- [4, 6, 4, 8,
1061
- f"J = {self.sample.TotalParam[67][0]} ± {round(self.sample.TotalParam[68][0] * self.sample.TotalParam[67][0] / 100, len(str(self.sample.TotalParam[67][0])))}"],
1062
- ]
1063
- for each in title_list:
1064
- sht_result.merge_range(*each, title_fmt)
1065
- sht_result.write_column(7, 4, ['Age', f'[{self.sample.Info.preference["ageUnit"]}]'], title_fmt)
1066
- sht_result.write_column(7, 19, ['³⁹Ar[K]', '[%, n]'], title_fmt)
1067
- for each in data_list:
1068
- sht_result.merge_range(*each, two_decimal_fmt)
1069
-
1070
- def _write_results(sht: Worksheet, start_row: int, start_col: int, title: str, data: list):
1071
- if len(data) < 13:
1072
- return
1073
- sht.merge_range(start_row, start_col, start_row + 1, start_col + 1, title, title_fmt_2)
1074
- sht.merge_range(start_row, start_col + 2, start_row + 1, start_col + 2, data[0], five_decimal_fmt)
1075
- sht.write_number(start_row, start_col + 3, data[1], five_error_fmt)
1076
- sht.write_number(start_row + 1, start_col + 3, data[2], percent_fmt)
1077
- sht.merge_range(start_row, start_col + 4, start_row + 1, start_col + 4, data[3], two_decimal_fmt)
1078
- sht.write_number(start_row, start_col + 5, data[4], error_fmt)
1079
- sht.write_number(start_row + 1, start_col + 5, data[5], percent_fmt)
1080
- sht.write_column(start_row + 2, start_col + 4, ['internal error', 'total external error'], string_fmt)
1081
- sht.write_column(start_row + 2, start_col + 5, data[6:8], error_fmt)
1082
- sht.merge_range(start_row, start_col + 6, start_row + 1, start_col + 6, data[8], two_decimal_fmt)
1083
- sht.write_number(start_row, start_col + 7, data[9], percent_fmt)
1084
- sht.write_number(start_row + 1, start_col + 7, data[10], int_fmt)
1085
- sht.merge_range(start_row, start_col + 8, start_row + 1, start_col + 8, data[11], five_decimal_fmt)
1086
- sht.write_number(start_row, start_col + 9, data[12], five_error_fmt)
1087
- sht.write_number(start_row + 1, start_col + 9, data[13], percent_fmt)
1088
-
1089
- # TGA
1090
- try:
1091
- age_res = self.sample.Info.results.age_spectra['TGA']
1092
- total_ca = [sum(self.sample.DegasValues[8]), err.add(*self.sample.DegasValues[9])]
1093
- total_k = [sum(self.sample.DegasValues[20]), err.add(*self.sample.DegasValues[21])]
1094
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1095
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1096
- _write_results(
1097
- sht_result, 10, 0, 'Total Age',
1098
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1099
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1100
- age_res['MSWD'], age_res['Ar39'] / 100,
1101
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1102
- )
1103
- _write_results(
1104
- sht_result, 10, 12, 'Total Age',
1105
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1106
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1107
- age_res['MSWD'], age_res['Ar39'] / 100,
1108
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1109
- )
1110
- except TypeError:
1111
- print(traceback.format_exc())
1112
- pass
1113
-
1114
- # age spectra, weighted mean age with 296
1115
- try:
1116
- age_res = self.sample.Info.results.age_spectra[0]
1117
- seq = self.sample.SelectedSequence1
1118
- total_ca = [sum(np.array(self.sample.DegasValues[8])[seq]), err.add(*np.array(self.sample.DegasValues[9])[seq])]
1119
- total_k = [sum(np.array(self.sample.DegasValues[20])[seq]), err.add(*np.array(self.sample.DegasValues[21])[seq])]
1120
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1121
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1122
- _write_results(
1123
- sht_result, 15, 0, f'Set 1 Plateau with air ratio {self.sample.TotalParam[0][0]}',
1124
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1125
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1126
- age_res['MSWD'], age_res['Ar39'] / 100,
1127
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1128
- )
1129
- except (IndexError, TypeError, ZeroDivisionError):
1130
- print(traceback.format_exc())
1131
- pass
1132
- try:
1133
- age_res = self.sample.Info.results.age_spectra[1]
1134
- seq = self.sample.SelectedSequence2
1135
- total_ca = [sum(np.array(self.sample.DegasValues[8])[seq]), err.add(*np.array(self.sample.DegasValues[9])[seq])]
1136
- total_k = [sum(np.array(self.sample.DegasValues[20])[seq]), err.add(*np.array(self.sample.DegasValues[21])[seq])]
1137
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1138
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1139
- _write_results(
1140
- sht_result, 15, 12, f'Set 2 Plateau with air ratio {self.sample.TotalParam[0][0]}',
1141
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1142
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1143
- age_res['MSWD'], age_res['Ar39'] / 100,
1144
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1145
- )
1146
- except (IndexError, TypeError, ZeroDivisionError):
1147
- print(traceback.format_exc())
1148
- pass
1149
-
1150
- # age spectra, weighted mean age with inverse intercept
1151
- try:
1152
- age_res = self.sample.Info.results.age_plateau[0]
1153
- seq = self.sample.SelectedSequence1
1154
- total_ca = [sum(np.array(self.sample.DegasValues[8])[seq]), err.add(*np.array(self.sample.DegasValues[9])[seq])]
1155
- total_k = [sum(np.array(self.sample.DegasValues[20])[seq]), err.add(*np.array(self.sample.DegasValues[21])[seq])]
1156
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1157
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1158
- _write_results(
1159
- sht_result, 20, 0, 'Set 1 Plateau with intercept correction',
1160
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1161
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1162
- age_res['MSWD'], age_res['Ar39'] / 100,
1163
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1164
- )
1165
- except (IndexError, TypeError, ZeroDivisionError):
1166
- print(traceback.format_exc())
1167
- pass
1168
- try:
1169
- age_res = self.sample.Info.results.age_plateau[1]
1170
- seq = self.sample.SelectedSequence2
1171
- total_ca = [sum(np.array(self.sample.DegasValues[8])[seq]), err.add(*np.array(self.sample.DegasValues[9])[seq])]
1172
- total_k = [sum(np.array(self.sample.DegasValues[20])[seq]), err.add(*np.array(self.sample.DegasValues[21])[seq])]
1173
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1174
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1175
- _write_results(
1176
- sht_result, 20, 12, 'Set 2 Plateau with intercept correction',
1177
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1178
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1179
- age_res['MSWD'], age_res['Ar39'] / 100,
1180
- age_res['Num'], cak, scak * sigma, abs(scak * sigma / cak)]
1181
- )
1182
- except (IndexError, TypeError, ZeroDivisionError):
1183
- print(traceback.format_exc())
1184
- pass
1185
-
1186
- # Isochron
1187
- for row_index, figure in enumerate(['figure_2', 'figure_3', 'figure_4', 'figure_5', 'figure_6', 'figure_7']):
1188
- for col_index, set in enumerate(['set1', 'set2']):
1189
- try:
1190
- ar39 = self.sample.Info.results.age_plateau[col_index]['Ar39']
1191
- num = self.sample.Info.results.age_plateau[col_index]['Num']
1192
- age_res = self.sample.Info.results.isochron[figure][col_index]
1193
- seq = [self.sample.SelectedSequence1, self.sample.SelectedSequence2][col_index]
1194
- total_ca = [sum(np.array(self.sample.DegasValues[8])[seq]),
1195
- err.add(*np.array(self.sample.DegasValues[9])[seq])]
1196
- total_k = [sum(np.array(self.sample.DegasValues[20])[seq]),
1197
- err.add(*np.array(self.sample.DegasValues[21])[seq])]
1198
- cak = total_ca[0] / total_k[0] / self.sample.TotalParam[20][0]
1199
- scak = err.div(total_ca, total_k, [self.sample.TotalParam[20][0], self.sample.TotalParam[21][0] * self.sample.TotalParam[20][0] / 100])
1200
- _name = ['Normal Ioschron', 'Inverse Isochron', 'K-Cl-Ar Plot 1', 'K-Cl-Ar Plot 2', 'K-Cl-Ar Plot 3', '3D plot'][row_index]
1201
- _write_results(
1202
- sht_result, 25 + row_index * 5, 0 + col_index * 12, f'{["Set 1", "Set 2"][col_index]} {_name}',
1203
- [age_res['F'], age_res['sF'] * sigma, abs(age_res['sF'] * sigma / age_res['F']), age_res['age'],
1204
- age_res['s1'] * sigma, abs(age_res['s1'] * sigma / age_res['age']), age_res['s2'] * sigma, age_res['s3'] * sigma,
1205
- age_res['MSWD'], ar39 / 100,
1206
- num, cak, scak * sigma, abs(scak * sigma / cak)]
1207
- )
1208
- except (IndexError, TypeError, ZeroDivisionError):
1209
- print(traceback.format_exc())
1210
- continue
1030
+ sht_summary = self.write_sht_summary("Summary", xls)
1211
1031
 
1212
1032
  # write tables and charts
1213
1033
  for sht_name, [prop_name, sht_type, row, col, _, smp_attr_name, header_name] in self.template.sheet():
@@ -1223,13 +1043,166 @@ class WritingWorkbook:
1223
1043
  except (BaseException, Exception):
1224
1044
  print(traceback.format_exc())
1225
1045
  return None
1046
+
1226
1047
  xls.get_worksheet_by_name("Reference").hide()
1227
- xls.get_worksheet_by_name("Isochrons").hidden = 0 # unhiden isochrons worksheet
1228
- xls.get_worksheet_by_name("Results").activate()
1048
+ # xls.get_worksheet_by_name("Isochrons").hidden = 0 # unhiden isochrons worksheet
1049
+ xls.get_worksheet_by_name("Summary").activate()
1229
1050
  xls.close()
1230
1051
  print('导出完毕,文件路径:%s' % self.filepath)
1231
1052
  return True
1232
1053
 
1054
+ def set_cell_format(self):
1055
+ pass
1056
+
1057
+ def get_cell_format(self, class_name):
1058
+ return self.formats.get(class_name, self.formats['default'])
1059
+
1060
+ def write_sht_summary(self, sht_name, xls):
1061
+ sht = xls.add_worksheet(sht_name)
1062
+ sht.hide_gridlines(2) # 0 = show grids, 1 = hide print grid, else = hide print and screen grids
1063
+ sht.set_column(0, 21, width=12) # column width
1064
+ sht.set_column(0, 0, width=16) # column width
1065
+ sht.set_column(2, 2, width=8.5) # column width
1066
+
1067
+ method = f"{self.sample.Info.sample.method}"
1068
+ name = self.sample.Info.sample.name
1069
+ material = self.sample.Info.sample.material
1070
+ weight = self.sample.Info.sample.weight
1071
+ J_value = self.sample.TotalParam[67][0]
1072
+ J_error = self.sample.TotalParam[68][0] * self.sample.TotalParam[67][0] / 100
1073
+ sigma = self.sample.Info.preference['confidenceLevel']
1074
+ sequence_type = {"StepLaser": "Laser", "StepFurnace": "Temperature", "StepCrusher": "Drop", }.get(method, "Step Value")
1075
+ sequence_unit = self.sample.Info.sample.sequence_unit if self.sample.Info.sample.sequence_unit != "" else "Unit"
1076
+ age_unit = self.sample.Info.preference['ageUnit']
1077
+ num_step = len(self.sample.SequenceName)
1078
+ set1_ratio = [self.sample.Info.results.isochron['figure_3'][0]['initial'], self.sample.Info.results.isochron['figure_2'][0]['initial'], self.sample.TotalParam[116][0]][int(self.sample.TotalParam[115][0])]
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])]
1080
+
1081
+ content = [
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'}],
1103
+ [(4, 0, 1), self.sample.SequenceName, {'align': 'left'}],
1104
+ [(4, 1, 1), self.sample.SequenceValue, {'num_format': 'General'}],
1105
+ [(4, 2, 1), list(map(lambda x: int(x) if str(x).isnumeric() else "", self.sample.IsochronMark)), {'num_format': 'General'}],
1106
+ [(4, 3, 1), self.sample.DegasValues[0], {}],
1107
+ [(4, 4, 1), self.sample.DegasValues[8], {}],
1108
+ [(4, 5, 1), self.sample.DegasValues[10], {}],
1109
+ [(4, 6, 1), self.sample.DegasValues[20], {}],
1110
+ [(4, 7, 1), self.sample.DegasValues[24], {}],
1111
+ [(4, 8, 1), self.sample.IsochronValues[6], {}],
1112
+ [(4, 9, 1), self.sample.IsochronValues[8], {}],
1113
+ [(4, 10, 1), self.sample.ApparentAgeValues[2], {}],
1114
+ [(4, 11, 1), list(map(lambda x: 2*x, self.sample.ApparentAgeValues[3])), {'num_format': '± ' + self.default_fmt_prop['num_format']}],
1115
+ [(4, 12, 1), self.sample.ApparentAgeValues[6], {}],
1116
+ [(4, 13, 1), self.sample.ApparentAgeValues[7], {}],
1117
+ [(4, 14, 1), self.sample.PublishValues[9], {}],
1118
+ [(4 + num_step, 0, 0), [''] * 15, {'bold': 1, 'top': 1}],
1119
+
1120
+ [(5 + num_step, 0), "Table 2. 40Ar/39Ar age summary", {'bold': 1, 'align': 'left'}],
1121
+ [(6 + num_step, 0, 7 + num_step, 0), "Group", {'bold': 1, 'top': 1}],
1122
+ [(6 + num_step, 1, 7 + num_step, 1), "40Arr/39K", {'bold': 1, 'top': 1}],
1123
+ [(6 + num_step, 2, 7 + num_step, 2), f"± {sigma} σ", {'bold': 1, 'top': 1}],
1124
+ [(6 + num_step, 3), "Age", {'bold': 1, 'top': 1}],
1125
+ [(7 + num_step, 3), f"({age_unit})", {'bold': 1, 'top': 0}],
1126
+ [(6 + num_step, 4), f"Analytical", {'bold': 1, 'top': 1, 'align': 'left'}],
1127
+ [(7 + num_step, 4), f"± {sigma} σ", {'bold': 1, 'top': 0, 'align': 'left'}],
1128
+ [(6 + num_step, 5), f"Internal", {'bold': 1, 'top': 1, 'align': 'left'}],
1129
+ [(7 + num_step, 5), f"± {sigma} σ", {'bold': 1, 'top': 0, 'align': 'left'}],
1130
+ [(6 + num_step, 6), f"Full external", {'bold': 1, 'top': 1, 'align': 'left'}],
1131
+ [(7 + num_step, 6), f"± {sigma} σ", {'bold': 1, 'top': 0, 'align': 'left'}],
1132
+ [(6 + num_step, 7, 7 + num_step, 7), f"MSWD", {'bold': 1, 'top': 1}],
1133
+ [(6 + num_step, 8, 7 + num_step, 8), f"39ArK", {'bold': 1, 'top': 1}],
1134
+ [(8 + num_step, 0), f"Total gas age", {'bold': 1, 'top': 6, 'italic': 1, 'align': 'left'}],
1135
+ [(8 + num_step, 1, 0), [''] * 8, {'top': 6}],
1136
+ [(9 + num_step, 0, 10 + num_step, 0), f"Total", {'bold': 1, 'align': 'center'}],
1137
+ [(12 + num_step, 0), f"40Ar/36Ar ratio ({self.sample.TotalParam[0][0]:.2f}) corrected plateau ages", {'bold': 1, 'italic': 1, 'align': 'left'}],
1138
+ [(18 + num_step, 0), f"{['Intercept of inverse isochron', 'Intercept of normal isochron', 'Inputted argon ratio'][int(self.sample.TotalParam[115][0])]} "
1139
+ f"(set 1 {set1_ratio} and set 2 {set2_ratio}) corrected plateau ages", {'bold': 1, 'italic': 1, 'align': 'left'}],
1140
+ [(24 + num_step, 0), f"Inverse isochron ages", {'bold': 1, 'italic': 1, 'align': 'left'}],
1141
+ [(30 + num_step, 0), f"Three-dimension ages", {'bold': 1, 'italic': 1, 'align': 'left'}],
1142
+ ]
1143
+
1144
+ tga_res = self.sample.Info.results.age_spectra['TGA']
1145
+ content.extend([
1146
+ [(9 + num_step, 1, 10 + num_step, 1), tga_res['F'], {'num_format': '0.00000'}],
1147
+ [(9 + num_step, 2, 10 + num_step, 2), tga_res['sF'], {'num_format': '0.00000'}],
1148
+ [(9 + num_step, 3, 10 + num_step, 3), tga_res['age'], {'num_format': '0.00'}],
1149
+ [(9 + num_step, 4), tga_res['s1'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1150
+ [(9 + num_step, 5), tga_res['s2'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1151
+ [(9 + num_step, 6), tga_res['s3'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1152
+ [(10 + num_step, 4), tga_res['s1'] * sigma / abs(tga_res['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1153
+ [(10 + num_step, 5), tga_res['s1'] * sigma / abs(tga_res['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1154
+ [(10 + num_step, 6), tga_res['s1'] * sigma / abs(tga_res['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1155
+ [(9 + num_step, 7, 10 + num_step, 7), tga_res['MSWD'], {'num_format': '0.00'}],
1156
+ [(9 + num_step, 8, 10 + num_step, 8), tga_res['Ar39'] / 100, {'num_format': '0.00%'}],
1157
+ ])
1158
+
1159
+ row = 13
1160
+ ar39 = [0, 0]
1161
+ for res in [
1162
+ self.sample.Info.results.age_spectra, self.sample.Info.results.age_plateau,
1163
+ self.sample.Info.results.isochron['figure_3'], self.sample.Info.results.isochron['figure_7']
1164
+ ]:
1165
+ for index, _ in enumerate(['Set 1', 'Set 2']):
1166
+ ar39[index] = res[index].get('Ar39', ar39[index] * 100) / 100
1167
+ print(res[index])
1168
+ try:
1169
+ content.extend([
1170
+ [(row + num_step, 0, row + 1 + num_step, 0), _, {'bold': 1, 'align': 'center'}],
1171
+ [(row + num_step, 1, row + 1 + num_step, 1), res[index]['F'], {'num_format': '0.00000'}],
1172
+ [(row + num_step, 2, row + 1 + num_step, 2), res[index]['sF'], {'num_format': '0.00000'}],
1173
+ [(row + num_step, 3, row + 1 + num_step, 3), res[index]['age'], {'num_format': '0.00'}],
1174
+ [(row + num_step, 4), res[index]['s1'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1175
+ [(row + num_step, 5), res[index]['s2'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1176
+ [(row + num_step, 6), res[index]['s3'] * sigma, {'num_format': '± 0.00', 'align': 'left'}],
1177
+ [(row + 1 + num_step, 4), res[index]['s1'] * sigma / abs(res[index]['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1178
+ [(row + 1 + num_step, 5), res[index]['s1'] * sigma / abs(res[index]['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1179
+ [(row + 1 + num_step, 6), res[index]['s1'] * sigma / abs(res[index]['age']), {'num_format': '± 0.00%', 'align': 'left'}],
1180
+ [(row + num_step, 7, row + 1 + num_step, 7), res[index]['MSWD'], {'num_format': '0.00'}],
1181
+ [(row + num_step, 8, row + 1 + num_step, 8), ar39[index], {'num_format': '0.00%'}],
1182
+ ])
1183
+ except ZeroDivisionError:
1184
+ pass
1185
+ row += 2
1186
+ row += 2
1187
+ content.append([(row - 2 + num_step, 0, 0), [''] * 9, {'top': 1}])
1188
+
1189
+ for pos, value, _prop in content:
1190
+ prop = self.default_fmt_prop.copy()
1191
+ prop.update(_prop)
1192
+ fmt = Format(prop, xls.xf_format_indices, xls.dxf_format_indices)
1193
+ xls.formats.append(fmt)
1194
+ if isinstance(value, (list, np.ndarray)) and len(pos) == 3:
1195
+ [sht.write_row, sht.write_column][pos[2]](*pos[:2], value, fmt)
1196
+ elif len(pos) == 2:
1197
+ isnumeric = isinstance(value, (float, int)) and not np.isnan(value) and not np.isinf(value)
1198
+ [sht.write_string, sht.write_number][isnumeric](*pos, value if isnumeric else str(value), fmt)
1199
+ elif len(pos) == 4:
1200
+ isnumeric = isinstance(value, (float, int)) and not np.isnan(value) and not np.isinf(value)
1201
+ sht.merge_range(*pos, value if isnumeric else str(value), fmt)
1202
+
1203
+ return sht
1204
+
1205
+
1233
1206
  def write_sht_table(self, sht_name, prop_name, sht_type, row, col, _, smp_attr_name, header_name, style, xls, sigma=1):
1234
1207
  sht = xls.add_worksheet(sht_name)
1235
1208
  data = arr.transpose(getattr(self.sample, smp_attr_name, None).data)
@@ -1427,7 +1400,7 @@ class WritingWorkbook:
1427
1400
 
1428
1401
  return chart
1429
1402
 
1430
- def get_chart_age_spectra(self, xls: Workbook, sht: Chartsheet, data_area: list, axis_range: list, age_unit = 'Ma'):
1403
+ def get_chart_age_spectra(self, xls: Workbook, sht: Chartsheet, data_area: list, axis_range: list, age_unit='Ma'):
1431
1404
  # ==============SpectraDiagram===============
1432
1405
  [xMin, xMax, yMin, yMax] = axis_range
1433
1406
  # Initializing a chart