ararpy 0.1.15__py3-none-any.whl → 0.1.18__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
@@ -20,7 +20,7 @@ import pdf_maker as pm
20
20
  import numpy as np
21
21
  from decimal import Decimal
22
22
 
23
- from ..calc import arr, isochron, spectra
23
+ from ..calc import arr, isochron, spectra, err
24
24
  from ..calc.basic import get_random_digits
25
25
  from ..calc.plot import get_axis_scale
26
26
  from . import basic, sample, consts
@@ -764,6 +764,9 @@ class WritingWorkbook:
764
764
  'top': 1, 'left': 1, 'right': 1, 'bottom': 1 # border width
765
765
  }
766
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
+
767
770
  def read_template(self):
768
771
  # print(self.template_filepath)
769
772
  self.template = CustomUnpickler(open(self.template_filepath, 'rb')).load()
@@ -773,6 +776,8 @@ class WritingWorkbook:
773
776
  xls = Workbook(self.filepath, {"nan_inf_to_errors": True})
774
777
  style = xls.add_format(self.style)
775
778
 
779
+ sigma = int(self.sample.Info.preference['confidenceLevel'])
780
+
776
781
  sht_reference = xls.add_worksheet("Reference") # Data used to plot
777
782
  sht_reference.hide_gridlines(2) # 0 = show grids, 1 = hide print grid, else = hide print and screen grids
778
783
  start_row = 3
@@ -797,9 +802,9 @@ class WritingWorkbook:
797
802
 
798
803
  # Data for age spectra
799
804
  try:
800
- spectra_data = arr.transpose(self.sample.AgeSpectraPlot.data)
801
- spectra_set1_data = arr.transpose(self.sample.AgeSpectraPlot.set1.data) or [[]] * 3
802
- spectra_set2_data = arr.transpose(self.sample.AgeSpectraPlot.set2.data) or [[]] * 3
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
803
808
  sht_reference.write_column(f"A{start_row}", spectra_data[0], style)
804
809
  sht_reference.write_column(f"B{start_row}", spectra_data[1], style)
805
810
  sht_reference.write_column(f"C{start_row}", spectra_data[2], style)
@@ -981,33 +986,70 @@ class WritingWorkbook:
981
986
  except IndexError:
982
987
  pass
983
988
 
989
+ # write result sheet
984
990
  sht_result = xls.add_worksheet('Results')
985
- title_style = xls.add_format({
991
+ title_fmt = xls.add_format({
986
992
  'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': True,
987
- 'bg_color': '#ccffff', 'font_color': '#0000ff', 'align': 'vcenter',
988
- 'top': 2, 'bottom': 2 # border width
993
+ 'bg_color': '#ccffff', 'font_color': '#0000ff', 'valign': 'vcenter', 'align': 'center',
994
+ 'top': 0, 'bottom': 0 # border width
989
995
  })
990
- title_style_2 = xls.add_format({
996
+ title_fmt_2 = xls.add_format({
991
997
  'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': True,
992
- 'font_color': '#000000', 'align': 'vcenter', 'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
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
993
1024
  })
994
- data_style = xls.add_format({
1025
+ percent_fmt = xls.add_format({
1026
+ 'num_format': '± 0.00%',
995
1027
  'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
996
- 'font_color': '#000000', 'align': 'vcenter',
1028
+ 'font_color': '#000000', 'valign': 'vcenter', 'align': 'center', 'text_wrap': True,
997
1029
  'top': 0, 'left': 0, 'bottom': 0, 'right': 0 # border width
998
1030
  })
999
- data_style.set_align('left')
1000
- data_style.set_text_wrap()
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()
1001
1043
  sht_result.set_column(0, 21, width=8.5) # column width
1002
1044
  sht_result.set_column(10, 11, width=3) # column width
1003
- sht_result.merge_range(0, 0, 1, 9, 'Sample Information', title_style)
1045
+ sht_result.merge_range(0, 0, 1, 9, 'Sample Information', title_fmt)
1004
1046
  title_list = [
1005
- [7, 0, 8, 0, 'Result'], [7, 1, 8, 1, ''], [7, 2, 8, 2, '40(r)/39(k)'], [7, 3, 8, 3, '1σ'],
1006
- [7, 4, 8, 4, 'Age'], [7, 5, 8, 5, '1σ'],
1007
- [7, 6, 8, 6, 'MSWD'], [7, 7, 8, 7, '39Ar(K)'], [7, 8, 8, 8, 'Ca/K'], [7, 9, 8, 9, '1σ'],
1008
- [7, 12, 8, 12, 'Result'], [7, 13, 8, 13, ''], [7, 14, 8, 14, '40(r)/39(k)'], [7, 15, 8, 15, '1σ'],
1009
- [7, 16, 8, 16, 'Age'], [7, 17, 8, 17, '1σ'],
1010
- [7, 18, 8, 18, 'MSWD'], [7, 19, 8, 19, '39Ar(K)'], [7, 20, 8, 20, 'Ca/K'], [7, 21, 8, 21, '1σ'],
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}σ'],
1011
1053
  ]
1012
1054
  data_list = [
1013
1055
  [3, 0, 3, 2, f"Sample = {self.sample.Info.sample.name}"],
@@ -1019,75 +1061,160 @@ class WritingWorkbook:
1019
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])))}"],
1020
1062
  ]
1021
1063
  for each in title_list:
1022
- sht_result.merge_range(*each, title_style)
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)
1023
1067
  for each in data_list:
1024
- sht_result.merge_range(*each, data_style)
1068
+ sht_result.merge_range(*each, two_decimal_fmt)
1025
1069
 
1026
1070
  def _write_results(sht: Worksheet, start_row: int, start_col: int, title: str, data: list):
1027
- if len(data) < 11:
1071
+ if len(data) < 13:
1028
1072
  return
1029
- sht.merge_range(start_row, start_col, start_row + 1, start_col + 1, title, title_style_2)
1030
- sht.merge_range(start_row, start_col + 2, start_row + 1, start_col + 2, data[0], data_style)
1031
- sht.write_column(start_row, start_col + 3, data[1:3], data_style)
1032
- sht.merge_range(start_row, start_col + 4, start_row + 1, start_col + 4, data[3], data_style)
1033
- sht.write_column(start_row, start_col + 5, data[4:6], data_style)
1034
- sht.merge_range(start_row, start_col + 6, start_row + 1, start_col + 6, data[6], data_style)
1035
- sht.write_column(start_row, start_col + 7, data[7:9], data_style)
1036
- sht.merge_range(start_row, start_col + 8, start_row + 1, start_col + 8, data[9], data_style)
1037
- sht.write_column(start_row, start_col + 9, data[9:11], data_style)
1038
-
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
1039
1090
  try:
1040
- _write_results(sht_result, 10, 0, 'Total Age', [
1041
- *self.sample.AgeSpectraPlot.info[0:2], '', self.sample.AgeSpectraPlot.info[4],
1042
- self.sample.AgeSpectraPlot.info[6], '',
1043
- '', 1, len(self.sample.SequenceName), '', '', ''])
1044
- _write_results(sht_result, 10, 12, 'Total Age', [
1045
- *self.sample.AgeSpectraPlot.info[0:2], '', self.sample.AgeSpectraPlot.info[4],
1046
- self.sample.AgeSpectraPlot.info[6], '',
1047
- '', 1, len(self.sample.SequenceName), '', '', ''])
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
+ )
1048
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())
1049
1131
  pass
1050
1132
  try:
1051
- _write_results(sht_result, 17, 0, 'Set 1 Age Plateau', [
1052
- *self.sample.AgeSpectraPlot.set1.info[0:2], '',
1053
- self.sample.AgeSpectraPlot.set1.info[4], self.sample.AgeSpectraPlot.set1.info[6], '',
1054
- self.sample.AgeSpectraPlot.set1.info[3], '', self.sample.AgeSpectraPlot.set1.info[2],
1055
- '', '', ''
1056
- ])
1057
- except (IndexError, TypeError):
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())
1058
1148
  pass
1149
+
1150
+ # age spectra, weighted mean age with inverse intercept
1059
1151
  try:
1060
- _write_results(sht_result, 17, 12, 'Set 2 Age Plateau', [
1061
- *self.sample.AgeSpectraPlot.set2.info[0:2], '',
1062
- self.sample.AgeSpectraPlot.set2.info[4], self.sample.AgeSpectraPlot.set2.info[6], '',
1063
- self.sample.AgeSpectraPlot.set2.info[2], '', self.sample.AgeSpectraPlot.set2.info[3],
1064
- '', '', ''
1065
- ])
1066
- except (IndexError, TypeError):
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())
1067
1167
  pass
1068
- for row_index, figure in enumerate(['figure_2', 'figure_3', 'figure_4', 'figure_5', 'figure_6']):
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']):
1069
1188
  for col_index, set in enumerate(['set1', 'set2']):
1070
1189
  try:
1071
- _isochron_results = getattr(basic.get_component_byid(self.sample, figure), set)
1072
- _name = \
1073
- ['Normal Ioschron', 'Inverse Isochron', 'K-Cl-Ar Plot 1', 'K-Cl-Ar Plot 2', 'K-Cl-Ar Plot 3'][
1074
- row_index]
1075
- _write_results(sht_result, 24 + row_index * 7, 0 + col_index * 12,
1076
- f'{["Set 1", "Set 2"][col_index]} {_name}', [
1077
- *_isochron_results.info[2], '',
1078
- _isochron_results.info[3][0], _isochron_results.info[3][2], '',
1079
- _isochron_results.info[0][4], '',
1080
- len([self.sample.SelectedSequence1, self.sample.SelectedSequence2][col_index]),
1081
- '', '', ''
1082
- ])
1083
- except (IndexError, TypeError):
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())
1084
1210
  continue
1085
1211
 
1212
+ # write tables and charts
1086
1213
  for sht_name, [prop_name, sht_type, row, col, _, smp_attr_name, header_name] in self.template.sheet():
1087
1214
  try:
1088
1215
  if sht_type == "table":
1089
1216
  self.write_sht_table(sht_name, prop_name, sht_type, row, col, _, smp_attr_name, header_name,
1090
- style, xls)
1217
+ style, xls, sigma)
1091
1218
  elif sht_type == "chart":
1092
1219
  self.write_sht_chart(sht_name, prop_name, sht_type, row, col, _, smp_attr_name, header_name,
1093
1220
  style, xls, start_row, total_rows)
@@ -1098,21 +1225,24 @@ class WritingWorkbook:
1098
1225
  return None
1099
1226
  xls.get_worksheet_by_name("Reference").hide()
1100
1227
  xls.get_worksheet_by_name("Isochrons").hidden = 0 # unhiden isochrons worksheet
1101
- xls.get_worksheet_by_name("Publish").activate()
1228
+ xls.get_worksheet_by_name("Results").activate()
1102
1229
  xls.close()
1103
1230
  print('导出完毕,文件路径:%s' % self.filepath)
1104
1231
  return True
1105
1232
 
1106
- def write_sht_table(self, sht_name, prop_name, sht_type, row, col, _, smp_attr_name, header_name, style, xls):
1233
+ def write_sht_table(self, sht_name, prop_name, sht_type, row, col, _, smp_attr_name, header_name, style, xls, sigma=1):
1107
1234
  sht = xls.add_worksheet(sht_name)
1108
1235
  data = arr.transpose(getattr(self.sample, smp_attr_name, None).data)
1109
1236
  sht.hide_gridlines(2) # 0 = show grids, 1 = hide print grid, else = hide print and screen grids
1110
1237
  sht.hide() # default hidden table sheet
1111
1238
  sht.set_column(0, len(data), width=12) # column width
1112
1239
  header = getattr(sample, header_name)
1240
+ header = list(map(lambda each: each if "σ" not in each else each.replace('1', str(sigma)) if str(sigma) not in each else each.replace('2', str(sigma)), header))
1113
1241
  sht.write_row(row=row - 1, col=col, data=header, cell_format=style)
1114
- for each_col in data:
1115
- res = sht.write_column(row=row, col=col, data=each_col, cell_format=style)
1242
+ for index, col_data in enumerate(data):
1243
+ if "σ" in header[col]:
1244
+ col_data = list(map(lambda each: each * sigma, col_data))
1245
+ res = sht.write_column(row=row, col=col, data=col_data, cell_format=style)
1116
1246
  if res:
1117
1247
  raise ValueError(res)
1118
1248
  col += 1
@@ -1127,20 +1257,20 @@ class WritingWorkbook:
1127
1257
  figure = self.sample.AgeSpectraPlot
1128
1258
  data_area = [
1129
1259
  # Spectra lines
1130
- f"A{start_row}:A{total_rows + start_row - 1}",
1131
- f"B{start_row}:B{total_rows + start_row - 1}",
1132
- f"C{start_row}:C{total_rows + start_row - 1}",
1260
+ f"A{start_row}:A{(total_rows + 1) * 2 + start_row - 1}",
1261
+ f"B{start_row}:B{(total_rows + 1) * 2 + start_row - 1}",
1262
+ f"C{start_row}:C{(total_rows + 1) * 2 + start_row - 1}",
1133
1263
  # set 1
1134
- f"D{start_row}:D{total_rows + start_row - 1}",
1135
- f"E{start_row}:E{total_rows + start_row - 1}",
1136
- f"F{start_row}:F{total_rows + start_row - 1}",
1264
+ f"D{start_row}:D{(total_rows + 1) * 2 + start_row - 1}",
1265
+ f"E{start_row}:E{(total_rows + 1) * 2 + start_row - 1}",
1266
+ f"F{start_row}:F{(total_rows + 1) * 2 + start_row - 1}",
1137
1267
  # set 2
1138
- f"G{start_row}:G{total_rows + start_row - 1}",
1139
- f"H{start_row}:H{total_rows + start_row - 1}",
1140
- f"I{start_row}:I{total_rows + start_row - 1}",
1268
+ f"G{start_row}:G{(total_rows + 1) * 2 + start_row - 1}",
1269
+ f"H{start_row}:H{(total_rows + 1) * 2 + start_row - 1}",
1270
+ f"I{start_row}:I{(total_rows + 1) * 2 + start_row - 1}",
1141
1271
  ]
1142
1272
  axis_range = [figure.xaxis.min, figure.xaxis.max, figure.yaxis.min, figure.yaxis.max]
1143
- self.get_chart_age_spectra(xls, sht, data_area, axis_range)
1273
+ self.get_chart_age_spectra(xls, sht, data_area, axis_range, age_unit=self.sample.Info.preference['ageUnit'])
1144
1274
  elif "normal_isochron" in prop_name.lower():
1145
1275
  data_area = [
1146
1276
  f"O{start_row}:O{num_set1 + start_row - 1}", f"P{start_row}:P{num_set1 + start_row - 1}",
@@ -1297,7 +1427,7 @@ class WritingWorkbook:
1297
1427
 
1298
1428
  return chart
1299
1429
 
1300
- def get_chart_age_spectra(self, xls: Workbook, sht: Chartsheet, data_area: list, axis_range: list):
1430
+ def get_chart_age_spectra(self, xls: Workbook, sht: Chartsheet, data_area: list, axis_range: list, age_unit = 'Ma'):
1301
1431
  # ==============SpectraDiagram===============
1302
1432
  [xMin, xMax, yMin, yMax] = axis_range
1303
1433
  # Initializing a chart
@@ -1353,7 +1483,7 @@ class WritingWorkbook:
1353
1483
  # chart.title_name = 'Age Spectra'
1354
1484
  # Axis title
1355
1485
  chart.x_axis.update({'name': f'Cumulative {consts.sup_39}Ar released (%)', 'min': xMin, 'max': xMax})
1356
- chart.y_axis.update({'name': 'Apparent age (Ma)', 'min': yMin, 'max': yMax})
1486
+ chart.y_axis.update({'name': f'Apparent age ({age_unit})', 'min': yMin, 'max': yMax})
1357
1487
  sht.set_chart(chart)
1358
1488
 
1359
1489
  def get_chart_isochron(self, xls: Workbook, sht: Chartsheet, data_areas, axis_range,
ararpy/smp/initial.py CHANGED
@@ -49,11 +49,11 @@ spectra_res_keys = [
49
49
  SPECTRA_RES = dict(zip(
50
50
  spectra_res_keys, [np.nan for i in spectra_res_keys])
51
51
  )
52
- settings_keys = [
53
- 'sigma_level'
52
+ preference_keys = [
53
+ 'decimalPlaces', 'toPrecision', 'confidenceLevel', 'ageUnit'
54
54
  ]
55
- SETTINGS_RES = dict(zip(
56
- settings_keys, [np.nan for i in settings_keys])
55
+ PREFERENCE_RES = dict(zip(
56
+ preference_keys, [6, 'fixed', 1, 'Ma'])
57
57
  )
58
58
 
59
59
 
@@ -110,9 +110,9 @@ def create_sample_from_dict(content: dict, smp_info: dict):
110
110
 
111
111
  smp.Info = basic.update_plot_from_dict(smp.Info, smp_info)
112
112
 
113
- smp.SelectedSequence1 = [index for index, item in enumerate(smp.IsochronMark) if item == 1]
114
- smp.SelectedSequence2 = [index for index, item in enumerate(smp.IsochronMark) if item == 2]
115
- smp.UnselectedSequence = [index for index, item in enumerate(smp.IsochronMark) if item not in [1, 2]]
113
+ smp.SelectedSequence1 = [index for index, item in enumerate(smp.IsochronMark) if item == 1 or item == '1']
114
+ smp.SelectedSequence2 = [index for index, item in enumerate(smp.IsochronMark) if item == 2 or item == '2']
115
+ smp.UnselectedSequence = [index for index, item in enumerate(smp.IsochronMark) if item not in [1, 2, '1', '2']]
116
116
  #
117
117
  smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
118
118
  smp.Info.results.selection[1]['data'] = smp.SelectedSequence2
@@ -182,45 +182,50 @@ def initial(smp: Sample):
182
182
  reference=ArArBasic(
183
183
  name='REFERENCE', journal='JOURNAL', doi='DOI'
184
184
  ),
185
- settings=copy.deepcopy(SETTINGS_RES)
185
+ preference=copy.deepcopy(PREFERENCE_RES)
186
186
  ))
187
187
 
188
- smp.Info.settings.update({'sigma_level': 1})
189
-
188
+ decimal_places = PREFERENCE_RES['decimalPlaces']
190
189
  # Plots and Tables
191
190
  setattr(smp, 'UnknownTable', Table(
192
- id='1', name='Unknown', header=samples.SAMPLE_INTERCEPT_HEADERS,
193
- text_indexes=[0], numeric_indexes=list(range(1, 20))
191
+ id='1', name='Unknown', header=samples.SAMPLE_INTERCEPT_HEADERS, decimal_places=decimal_places,
192
+ text_indexes=[0, 1],
193
+ # numeric_indexes=list(range(1, 20))
194
194
  ))
195
195
  setattr(smp, 'BlankTable', Table(
196
- id='2', name='Blank', header=samples.BLANK_INTERCEPT_HEADERS,
197
- text_indexes=[0], numeric_indexes=list(range(1, 20))
196
+ id='2', name='Blank', header=samples.BLANK_INTERCEPT_HEADERS, decimal_places=decimal_places,
197
+ text_indexes=[0, 1],
198
+ # numeric_indexes=list(range(1, 20))
198
199
  ))
199
200
  setattr(smp, 'CorrectedTable', Table(
200
- id='3', name='Corrected', header=samples.CORRECTED_HEADERS,
201
- text_indexes=[0], numeric_indexes=list(range(1, 35))
201
+ id='3', name='Corrected', header=samples.CORRECTED_HEADERS, decimal_places=decimal_places,
202
+ text_indexes=[0, 1],
203
+ # numeric_indexes=list(range(1, 35))
202
204
  ))
203
205
  setattr(smp, 'DegasPatternTable', Table(
204
- id='4', name='Degas Pattern', header=samples.DEGAS_HEADERS,
205
- text_indexes=[0], numeric_indexes=list(range(1, 35))
206
+ id='4', name='Degas Pattern', header=samples.DEGAS_HEADERS, decimal_places=decimal_places,
207
+ text_indexes=[0, 1],
208
+ # numeric_indexes=list(range(1, 35))
206
209
  ))
207
210
  setattr(smp, 'PublishTable', Table(
208
- id='5', name='Publish', header=samples.PUBLISH_TABLE_HEADERS,
209
- text_indexes=[0], numeric_indexes=list(range(1, 20))
211
+ id='5', name='Publish', header=samples.PUBLISH_TABLE_HEADERS, decimal_places=decimal_places,
212
+ text_indexes=[0, 1],
213
+ # numeric_indexes=list(range(1, 20))
210
214
  ))
211
215
  setattr(smp, 'AgeSpectraTable', Table(
212
- id='6', name='Age Spectra', header=samples.SPECTRUM_TABLE_HEADERS,
213
- text_indexes=[0], numeric_indexes=list(range(1, 26))
216
+ id='6', name='Age Spectra', header=samples.SPECTRUM_TABLE_HEADERS, decimal_places=decimal_places,
217
+ text_indexes=[0, 1],
218
+ # numeric_indexes=list(range(1, 26))
214
219
  ))
215
220
  setattr(smp, 'IsochronsTable', Table(
216
- id='7', name='Isochrons', header=samples.ISOCHRON_TABLE_HEADERS,
217
- text_indexes=[0], numeric_indexes=list(range(1, 42))
221
+ id='7', name='Isochrons', header=samples.ISOCHRON_TABLE_HEADERS, decimal_places=decimal_places,
222
+ text_indexes=[0, 1, 2, 8, 14, 20, 26, 32],
223
+ # numeric_indexes=[1, *list(range(3, 42))]
218
224
  ))
219
225
  setattr(smp, 'TotalParamsTable', Table(
220
- id='8', name='Total Params', header=samples.TOTAL_PARAMS_HEADERS,
221
- text_indexes=[0, 29, 30, 32, 33, 60, 99, 102, *list(range(103, 115))],
226
+ id='8', name='Total Params', header=samples.TOTAL_PARAMS_HEADERS, decimal_places=decimal_places,
227
+ text_indexes=[0, 1, 29, 30, 32, 33, 60, 99, *list(range(100, 115))],
222
228
  # numeric_indexes=list(range(1, 120)),
223
- numeric_indexes=[1],
224
229
  ))
225
230
 
226
231
  initial_plot_styles(smp)
ararpy/smp/plots.py CHANGED
@@ -61,7 +61,7 @@ def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
61
61
  try:
62
62
  initial_plot_data(sample)
63
63
  except (Exception, BaseException):
64
- # print(traceback.format_exc())
64
+ print("initial_plot_data(sample) error:\n", traceback.format_exc())
65
65
  pass
66
66
 
67
67
  # Recalculate isochron lines
@@ -69,12 +69,12 @@ def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
69
69
  try:
70
70
  recalc_isochrons(sample, **kwargs)
71
71
  except (Exception, BaseException):
72
- # print(traceback.format_exc())
72
+ print("recalc_isochrons(sample, **kwargs) error:\n", traceback.format_exc())
73
73
  pass
74
74
  try:
75
75
  reset_isochron_line_data(sample)
76
76
  except (Exception, BaseException):
77
- # print(traceback.format_exc())
77
+ print("reset_isochron_line_data(sample):\n", traceback.format_exc())
78
78
  pass
79
79
 
80
80
  # Recalculate plateaus
@@ -82,7 +82,7 @@ def set_plot_data(sample: Sample, isInit: bool = True, isIsochron: bool = True,
82
82
  try:
83
83
  recalc_plateaus(sample)
84
84
  except (Exception, BaseException):
85
- # print(traceback.format_exc())
85
+ print("recalc_plateaus(sample) error:\n", traceback.format_exc())
86
86
  pass
87
87
 
88
88
 
@@ -226,6 +226,7 @@ def get_isochron_results(data: list, smp: Sample, sequence, figure_type: int = 0
226
226
  'k', 'sk', 'm1', 'sm1',
227
227
  'MSWD', 'abs_conv', 'iter', 'mag', 'R2', 'Chisq', 'Pvalue',
228
228
  'rs', # 'rs' means relative error of the total sum
229
+ 'cov_b_m'
229
230
  ]
230
231
  age_res_index = ['age', 's1', 's2', 's3', ]
231
232
  iso_res = dict(zip(
@@ -360,7 +361,7 @@ def set_selection(smp: Sample, index: int, mark: int):
360
361
  -------
361
362
 
362
363
  """
363
- if mark not in [1, 2]:
364
+ if mark not in [1, 2, '1', '2']:
364
365
  raise ValueError(f"{mark = }, mark must be 1 or 2.")
365
366
 
366
367
  def seq(_i): return [smp.UnselectedSequence, smp.SelectedSequence1, smp.SelectedSequence2][_i]
@@ -374,7 +375,7 @@ def set_selection(smp: Sample, index: int, mark: int):
374
375
  seq(i).remove(index)
375
376
  seq(mark).append(index)
376
377
  smp.IsochronMark = [
377
- 1 if i in smp.SelectedSequence1 else 2 if i in smp.SelectedSequence2 else '' for i in
378
+ '1' if i in smp.SelectedSequence1 else '2' if i in smp.SelectedSequence2 else '' for i in
378
379
  range(len(smp.IsochronValues[2]))]
379
380
  #
380
381
  smp.Info.results.selection[0]['data'] = smp.SelectedSequence1
ararpy/smp/sample.py CHANGED
@@ -951,7 +951,7 @@ class Table:
951
951
  rowcount = len(data[0])
952
952
  if coltypes is None:
953
953
  # Note the difference between [xx] * 10 and [xx for i in range(10)]
954
- coltypes = [{'type': 'numeric'} for i in range(colcount)]
954
+ coltypes = [{'type': 'text'} for i in range(colcount)]
955
955
  self.id = id
956
956
  self.name = name
957
957
  self.colcount = colcount
@@ -959,12 +959,13 @@ class Table:
959
959
  self.header = header
960
960
  self.data = data
961
961
  self.coltypes = coltypes
962
- self.numeric_indexes = numeric_indexes
963
- self.text_indexes = text_indexes
964
- if text_indexes is not None and numeric_indexes is not None:
965
- self.set_coltypes()
962
+ self.text_indexes = text_indexes if text_indexes is not None else []
963
+ self.numeric_indexes = numeric_indexes if numeric_indexes is not None else list(set(range(0, colcount)) - set(self.text_indexes))
964
+ self.decimal_places = 6
965
+
966
966
  for k, v in kwargs.items():
967
967
  setattr(self, k, v)
968
+ self.set_coltypes()
968
969
 
969
970
  def set_coltypes(self):
970
971
  for i in self.text_indexes:
@@ -972,7 +973,10 @@ class Table:
972
973
  self.coltypes[i].update({'type': 'text'})
973
974
  for i in self.numeric_indexes:
974
975
  if i < self.colcount:
975
- self.coltypes[i].update({'type': 'numeric'})
976
+ self.coltypes[i].update({
977
+ 'type': 'numeric',
978
+ 'numericFormat': {'pattern': {'mantissa': self.decimal_places}},
979
+ })
976
980
 
977
981
 
978
982
  class Plot: