ararpy 0.1.12__py3-none-any.whl → 0.1.13__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
@@ -17,9 +17,11 @@ import sys
17
17
  import pickle
18
18
  import traceback
19
19
  import pdf_maker as pm
20
+ import numpy as np
20
21
  from decimal import Decimal
21
22
 
22
- from ..calc import arr, isochron
23
+ from ..calc import arr, isochron, spectra
24
+ from ..calc.basic import get_random_digits
23
25
  from . import basic, sample, consts
24
26
 
25
27
  Sample = sample.Sample
@@ -41,52 +43,467 @@ def to_pdf(file_path: str, figure: str, smp: Sample):
41
43
  pdf.save(figure=figure)
42
44
 
43
45
 
44
- def export_chart_to_pdf(data: dict):
46
+ def get_cv_from_dict(data: dict):
45
47
  # create a canvas
46
48
  cv = pm.Canvas(width=17, height=12, unit="cm", show_frame=True, clip_outside_plot_areas=False)
47
49
  # change frame outline style
48
50
  cv.show_frame(color="grey", line_width=0.5)
49
- sc = (*data['xAxis'][0]['extent'], *data['yAxis'][0]['extent'])
50
- pt = cv.add_plot_area(name="Plot1", plot_area=(0.15, 0.15, 0.8, 0.8), plot_scale=sc, show_frame=True)
51
+ axis_num = min([len(data['xAxis']), len(data['yAxis'])])
51
52
  # draw axis
52
- for stick in data['xAxis'][0]['interval']:
53
- start = pt.scale_to_points(stick, sc[2])
54
- end = pt.scale_to_points(stick, sc[2])
55
- end = (end[0], end[1] - 5)
56
- pt.line(start=start, end=end, width=1, line_style="solid", y_clip=False, coordinate="pt", z_index=100)
57
- pt.text(x=start[0], y=end[1] - 15, text=f"{stick}", clip=False,
58
- coordinate="pt", h_align="middle", z_index=150)
59
- for stick in data['yAxis'][0]['interval']:
60
- start = pt.scale_to_points(sc[0], stick)
61
- end = pt.scale_to_points(sc[0], stick)
62
- end = (end[0] - 5, end[1])
63
- pt.line(start=start, end=end, width=1, line_style="solid", x_clip=False, coordinate="pt", z_index=100)
64
- pt.text(x=end[0] - 5, y=end[1], text=f"{stick}", clip=False,
65
- coordinate="pt", h_align="right", v_align="center", z_index=150)
66
- # axis titles
67
- nameLocation = pt.scale_to_points(sum(sc[:2]) / 2, sc[2])
68
- pt.text(x=nameLocation[0], y=nameLocation[1] - 30, text=data['xAxis'][0]['title'], clip=False, coordinate="pt",
69
- h_align="middle", v_align="top", z_index=150)
70
- nameLocation = pt.scale_to_points(sc[0], sum(sc[2:4]) / 2)
71
- pt.text(x=nameLocation[0] - 50, y=nameLocation[1], text=data['yAxis'][0]['title'], clip=False, coordinate="pt",
72
- h_align="middle", v_align="bottom", rotate=90, z_index=150)
53
+ plots = []
54
+ for i in range(axis_num):
55
+ scale = [*data['xAxis'][i]['extent'], *data['yAxis'][i]['extent']]
56
+ scale = (*scale,)
57
+ # create plot area based on axis scale
58
+ pt = cv.add_plot_area(name=f"PlotArea{i}", plot_area=(0.15, 0.15, 0.8, 0.8), plot_scale=scale, show_frame=True)
59
+ for stick in data['xAxis'][i]['interval']:
60
+ start = pt.scale_to_points(stick, scale[2])
61
+ end = pt.scale_to_points(stick, scale[2])
62
+ end = (end[0], end[1] - 5)
63
+ if pt.line(start=start, end=end, width=1, line_style="solid", y_clip=False, coordinate="pt", z_index=100):
64
+ pt.text(x=start[0], y=end[1] - 15, text=f"{stick}", clip=False,
65
+ coordinate="pt", h_align="middle", z_index=150)
66
+ for stick in data['yAxis'][i]['interval']:
67
+ start = pt.scale_to_points(scale[0], stick)
68
+ end = pt.scale_to_points(scale[0], stick)
69
+ end = (end[0] - 5, end[1])
70
+ if pt.line(start=start, end=end, width=1, line_style="solid", x_clip=False, coordinate="pt", z_index=100):
71
+ pt.text(x=end[0] - 5, y=end[1], text=f"{stick}", clip=False,
72
+ coordinate="pt", h_align="right", v_align="center", z_index=150)
73
+ # axis titles
74
+ nloc = pt.scale_to_points(sum(scale[:2]) / 2, scale[2])
75
+ pt.text(x=nloc[0], y=nloc[1] - 30, text=data['xAxis'][i]['title'], clip=False, coordinate="pt",
76
+ h_align="middle", v_align="top", z_index=150)
77
+ nloc = pt.scale_to_points(scale[0], sum(scale[2:4]) / 2)
78
+ pt.text(x=nloc[0] - 50, y=nloc[1], text=data['yAxis'][i]['title'], clip=False, coordinate="pt",
79
+ h_align="middle", v_align="bottom", rotate=90, z_index=150)
80
+ plots.append(pt)
73
81
  # draw series
74
82
  for se in data['series']:
75
83
  data = se.get('data', [])
84
+ try:
85
+ pt = plots[se.get('axis_index', 0)]
86
+ except IndexError:
87
+ continue
76
88
  if 'line' in se['type']:
77
89
  for index in range(1, len(data)):
78
- pt.line(start=data[index - 1], end=data[index], width=1, line_style='solid', name=se['name'],
79
- color=se.get('color', 'black'), clip=True, line_caps=se.get('line_caps', 'none'), z_index=9)
90
+ pt.line(
91
+ start=data[index - 1], end=data[index], width=se.get('line_width', 1),
92
+ line_style=se.get('line_style', 'solid'), name=se['name'],
93
+ color=se.get('color', 'black'), clip=True, line_caps=se.get('line_caps', 'none'),
94
+ z_index=se.get('z_index', 9))
80
95
  if 'scatter' in se['type'] and se['name'] != 'Text':
81
96
  for each in data:
82
- pt.scatter(each[0], each[1], fill_color=se.get('color', 'black'), size=2)
97
+ pt.scatter(
98
+ each[0], each[1], fill_color=se.get('fill_color', 'black'), size=se.get('size', 5),
99
+ stroke_color=se.get('stroke_color', se.get('color', 'black')),
100
+ z_index=se.get('z_index', 9)
101
+ )
83
102
  if 'scatter' in se['type'] and se['name'] == 'Text' or 'text' in se['type']:
84
103
  for each in data:
85
104
  pt.text(*each[:2], **se)
105
+ if 'rect' in se['type']:
106
+ for each in data:
107
+ lb = each[:2]; width, height = each[2:4]
108
+ pt.rect(lb, width, height, **se)
86
109
 
87
110
  return cv
88
111
 
89
112
 
113
+ def export_chart_to_pdf(data: dict, filepath: str = "", **kwargs):
114
+ """
115
+
116
+ Parameters
117
+ ----------
118
+ filepath: str
119
+ data: dict
120
+ - file_name: string
121
+ file name, like "24WHA0001"
122
+ - data: list of dicts
123
+ properties:
124
+ - name: string
125
+ diagram name, like "Age spectra"
126
+
127
+ - xAxis: list
128
+ properties:
129
+ - extend: list
130
+ limits of values of axis, like [0, 100]
131
+ - interval: list
132
+ sticks location, like [0, 20, 40, 60, 80, 100]
133
+ - title: string
134
+ - name_location: string
135
+ axis title location, 'middle'
136
+
137
+ - yAxis: same as xAxis
138
+
139
+ - series: list
140
+ properties:
141
+ - type: string
142
+ series type, 'line', 'scatter', 'text', and any string contains these characters
143
+ - id: string
144
+ - name: string
145
+ - color: string or list
146
+ color for outlines, color name | RGB triplet | Hex color code
147
+ - fill_color: string or list
148
+ color for filling markers, format is similar to that of color
149
+ - data: 2-dimensional array
150
+ [[x1, y1], [x2, y2], ...]
151
+ - axis_index: int
152
+ index of axis to combine with, which is useful for plotting on different scales.
153
+
154
+ optional:
155
+ - line_caps: string
156
+ for lines only, 'square', 'none', 'butt'
157
+ - text: string
158
+ for texts only
159
+ - size: int
160
+ for scatters only
161
+ **kwargs:
162
+ author, producer, creator, page_size, ppi, ...
163
+
164
+ Returns
165
+ -------
166
+
167
+ """
168
+ title = data.get('file_name', '')
169
+ # write pdf
170
+ file = pm.NewPDF(filepath=filepath, title=f"{title}", **kwargs)
171
+ plot_data = data.get('data', [])
172
+ for index, each in enumerate(plot_data):
173
+ # rich text tags should follow this priority: color > script > break
174
+ file.text(
175
+ page=index, x=50, y=780, line_space=1.2, size=12, base=0, h_align="left",
176
+ text=f"{each.get('name', '')}"
177
+ )
178
+ cv = get_cv_from_dict(each)
179
+ file.canvas(page=index, base=0, margin_top=5, canvas=cv, unit="cm", h_align="middle")
180
+ if index + 1 < len(plot_data):
181
+ file.add_page()
182
+
183
+ # save pdf
184
+ file.save()
185
+
186
+ return filepath
187
+
188
+
189
+ def get_plot_data(smp: Sample, diagram: str = 'age spectra', **options):
190
+ """
191
+
192
+ Parameters
193
+ ----------
194
+ smp
195
+ diagram
196
+ color
197
+ options
198
+
199
+ Returns
200
+ -------
201
+
202
+ """
203
+ if diagram.lower() == "age spectra":
204
+ xAxis, yAxis, series = _get_plot_data_age_spectra(smp, **options)
205
+ elif diagram.lower() == "inverse isochron":
206
+ xAxis, yAxis, series = _get_plot_data_inv_isochron(smp, **options)
207
+ elif "degas spectra" in diagram.lower():
208
+ xAxis, yAxis, series = _get_plot_data_degas_spectra(smp, diagram_name = diagram.lower(), **options)
209
+ elif "degas curve" in diagram.lower():
210
+ xAxis, yAxis, series = _get_plot_data_degas_curve(smp, diagram_name = diagram.lower(), **options)
211
+ else:
212
+ raise KeyError
213
+
214
+ data = {
215
+ 'name': smp.name(), 'xAxis': xAxis, 'yAxis': yAxis, 'series': series
216
+ }
217
+
218
+ print(data)
219
+
220
+ return data
221
+
222
+
223
+ def _get_plot_data_age_spectra(smp: sample, **options):
224
+ color = options.get('color', 'black')
225
+ xAxis, yAxis, series = [], [], []
226
+ age = smp.ApparentAgeValues[2:4]
227
+ ar = smp.DegasValues[20]
228
+ data = spectra.get_data(*age, ar, cumulative=False)
229
+ series.append({
230
+ 'type': 'series.line', 'id': f'line-{get_random_digits()}', 'name': f'line-{get_random_digits()}',
231
+ 'color': color, 'fill_color': color, 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
232
+ 'data': np.transpose([data[0], data[1]]).tolist(), 'line_caps': 'square',
233
+ 'axis_index': 0,
234
+ })
235
+ series.append({
236
+ 'type': 'series.line', 'id': f'line-{get_random_digits()}', 'name': f'line-{get_random_digits()}',
237
+ 'color': color, 'fill_color': color, 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
238
+ 'data': np.transpose([data[0], data[2]]).tolist(), 'line_caps': 'square',
239
+ 'axis_index': 0,
240
+ })
241
+ text1 = smp.AgeSpectraPlot.text1
242
+ text2 = smp.AgeSpectraPlot.text2
243
+ for text in [text1, text2]:
244
+ series.append({
245
+ 'type': 'text', 'id': f'text-{get_random_digits()}', 'name': f'text-{get_random_digits()}',
246
+ 'color': color, 'fill_color': color,
247
+ 'text': smp.name() + '<r>' + text.text.replace("\n", "<r>"), 'size': int(text.font_size / 1.5),
248
+ 'data': [text.pos],
249
+ 'axis_index': 1,
250
+ })
251
+
252
+ xAxis.append({
253
+ 'extent': [0, 100], 'interval': [0, 20, 40, 60, 80, 100], 'id': 0, 'show_frame': True,
254
+ 'title': 'Cumulative <sup>39</sup>Ar Released (%)', 'name_location': 'middle',
255
+ 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
256
+ })
257
+ xAxis.append({
258
+ 'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
259
+ 'title': '', 'name_location': 'middle',
260
+ 'line_width': 1, 'line_style': 'solid', 'z_index': 0,
261
+ })
262
+ yAxis.append({
263
+ 'extent': [0, 25], 'interval': [0, 5, 10, 15, 20, 25], 'id': 0, 'show_frame': True,
264
+ 'title': 'Apparent Age (Ma)', 'name_location': 'middle',
265
+ 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
266
+ })
267
+ yAxis.append({
268
+ 'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
269
+ 'title': '', 'name_location': 'middle',
270
+ 'line_width': 1, 'line_style': 'solid', 'z_index': 0,
271
+ })
272
+ return xAxis, yAxis, series
273
+
274
+
275
+ def _get_plot_data_inv_isochron(smp: sample, **options):
276
+ color = options.get('color', 'black')
277
+ xAxis, yAxis, series = [], [], []
278
+ age = smp.ApparentAgeValues[2:4]
279
+ ar = smp.DegasValues[20]
280
+ data = np.array(smp.InvIsochronPlot.data)
281
+ set1 = smp.InvIsochronPlot.set1.data
282
+ set2 = smp.InvIsochronPlot.set2.data
283
+ set3 = smp.InvIsochronPlot.set3.data
284
+ # set 1
285
+ series.append({
286
+ 'type': 'series.scatter', 'id': f'scatter-{get_random_digits()}', 'name': f'scattter-{get_random_digits()}',
287
+ 'stroke_color': 'red', 'fill_color': 'red', 'myType': 'scatter', 'size': 4, 'line_width': 1,
288
+ 'data': (data[[0, 2], :][:, set1]).transpose().tolist(),
289
+ 'axis_index': 0, 'z_index': 99
290
+ })
291
+ # set 2
292
+ series.append({
293
+ 'type': 'series.scatter', 'id': f'scatter-{get_random_digits()}', 'name': f'scattter-{get_random_digits()}',
294
+ 'stroke_color': 'blue', 'fill_color': 'blue', 'myType': 'scatter', 'size': 4, 'line_width': 1,
295
+ 'data': (data[[0, 2], :][:, set2]).transpose().tolist(),
296
+ 'axis_index': 0, 'z_index': 99
297
+ })
298
+ # set 3
299
+ series.append({
300
+ 'type': 'series.scatter', 'id': f'scatter-{get_random_digits()}', 'name': f'scattter-{get_random_digits()}',
301
+ 'stroke_color': 'black', 'fill_color': 'none', 'myType': 'scatter', 'size': 4, 'line_width': 1,
302
+ 'data': (data[[0, 2], :][:, set3]).transpose().tolist(),
303
+ 'axis_index': 0, 'z_index': 0
304
+ })
305
+
306
+ text1 = smp.InvIsochronPlot.text1
307
+ text2 = smp.InvIsochronPlot.text2
308
+
309
+ series.append({
310
+ 'type': 'text', 'id': f'text-{get_random_digits()}', 'name': f'text-{get_random_digits()}',
311
+ 'color': 'red', 'fill_color': 'red',
312
+ 'text': smp.name() + '<r>' + text1.text.replace("\n", "<r>"), 'size': int(text1.font_size / 1.5),
313
+ 'data': [text1.pos],
314
+ 'axis_index': 1,
315
+ })
316
+ series.append({
317
+ 'type': 'text', 'id': f'text-{get_random_digits()}', 'name': f'text-{get_random_digits()}',
318
+ 'color': 'blue', 'fill_color': 'blue',
319
+ 'text': smp.name() + '<r>' + text2.text.replace("\n", "<r>"), 'size': int(text2.font_size / 1.5),
320
+ 'data': [text2.pos],
321
+ 'axis_index': 1,
322
+ })
323
+
324
+ xaxis = smp.InvIsochronPlot.xaxis
325
+ yaxis = smp.InvIsochronPlot.yaxis
326
+
327
+ xAxis.append({
328
+ 'extent': [float(xaxis.min), float(xaxis.max)],
329
+ 'interval': [float("{:g}".format(float(xaxis.min) + i * float(xaxis.interval))) for i in range(int(xaxis.split_number) + 1)],
330
+ 'id': 0, 'show_frame': True, 'z_index': 9,
331
+ 'title': 'XXXX', 'name_location': 'middle',
332
+ })
333
+ xAxis.append({
334
+ 'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
335
+ 'title': '', 'name_location': 'middle', 'z_index': 0,
336
+ })
337
+ yAxis.append({
338
+ 'extent': [float(yaxis.min), float(yaxis.max)],
339
+ 'interval': [float("{:g}".format(float(yaxis.min) + i * float(yaxis.interval))) for i in range(int(yaxis.split_number) + 1)],
340
+ 'id': 0, 'show_frame': True, 'z_index': 9,
341
+ 'title': 'YYYY', 'name_location': 'middle',
342
+ })
343
+ yAxis.append({
344
+ 'extent': [0, 100], 'interval': [], 'id': 1, 'show_frame': False,
345
+ 'title': '', 'name_location': 'middle', 'z_index': 0,
346
+ })
347
+ return xAxis, yAxis, series
348
+
349
+
350
+ def _get_plot_data_degas_pattern(smp: sample, **options):
351
+ color = options.get('color', 'black')
352
+ plot = smp.DegasPatternPlot
353
+ xAxis, yAxis, series = [], [], []
354
+ argon = smp.DegasValues[20] # Ar39K as default
355
+ while argon[-1] == 0:
356
+ argon = argon[:-1]
357
+ y = [argon[i] / sum(argon[i:]) * 100 for i in range(len(argon))]
358
+ x = list(range(1, len(argon) + 1))
359
+ data = np.array([x, y])
360
+ # set 1
361
+ series.append({
362
+ 'type': 'series.scatter', 'id': f'scatter-{get_random_digits()}', 'name': f'scattter-{get_random_digits()}',
363
+ 'stroke_color': color, 'fill_color': 'white', 'myType': 'scatter', 'size': 4, 'line_width': 1,
364
+ 'data': data.transpose().tolist(), 'axis_index': 0, 'z_index': 99
365
+ })
366
+
367
+ xaxis = plot.xaxis
368
+ yaxis = plot.yaxis
369
+
370
+ xaxis.min = 0
371
+ xaxis.max = 100
372
+ xaxis.interval = 20
373
+ xaxis.split_number = 5
374
+ yaxis.min = 0
375
+ yaxis.max = 20
376
+ yaxis.interval = 5
377
+ yaxis.split_number = 4
378
+
379
+ xAxis.append({
380
+ 'extent': [float(xaxis.min), float(xaxis.max)],
381
+ 'interval': [float("{:g}".format(float(xaxis.min) + i * float(xaxis.interval))) for i in range(int(xaxis.split_number) + 1)],
382
+ 'id': 0, 'show_frame': True, 'z_index': 9,
383
+ 'title': 'XXXX', 'name_location': 'middle',
384
+ })
385
+ yAxis.append({
386
+ 'extent': [float(yaxis.min), float(yaxis.max)],
387
+ 'interval': [float("{:g}".format(float(yaxis.min) + i * float(yaxis.interval))) for i in range(int(yaxis.split_number) + 1)],
388
+ 'id': 0, 'show_frame': True, 'z_index': 9,
389
+ 'title': 'YYYY', 'name_location': 'middle',
390
+ })
391
+ return xAxis, yAxis, series
392
+
393
+
394
+ def _get_plot_data_degas_spectra(smp: sample, **options):
395
+ name = options.get('diagram_name', '39Ar')
396
+ color = options.get('color', 'black')
397
+ plot = smp.DegasPatternPlot
398
+ xAxis, yAxis, series = [], [], []
399
+ nindex = {"40": 24, "39": 20, "38": 10, "37": 8, "36": 0}
400
+ if name[:2] in list(nindex.keys()):
401
+ ar = np.array(smp.DegasValues[nindex[name[:2]]], dtype=np.float64) # 20-21 Ar39
402
+ sar = np.array(smp.DegasValues[nindex[name[:2]] + 1], dtype=np.float64)
403
+ elif 'total' in name:
404
+ all_ar = np.array(smp.CorrectedValues, dtype=np.float64) # 20-21 Ar39
405
+ ar, sar = arr.add(*all_ar.reshape(5, 2, len(all_ar[0])))
406
+ ar = np.array(ar); sar = np.array(sar)
407
+ else:
408
+ raise KeyError
409
+
410
+ while ar[-1] == 0:
411
+ ar = ar[:-1]
412
+ x = list(range(0, len(ar)))
413
+ y = [0 for i in range(len(ar))]
414
+ width = [1 for i in range(len(ar))]
415
+ height = [ar[i] / sum(ar) * 100 for i in range(len(ar))]
416
+ data = np.array([x, y, width, height])
417
+
418
+ xaxis = plot.xaxis
419
+ yaxis = plot.yaxis
420
+
421
+ xaxis.min = 0
422
+ xaxis.max = 100
423
+ xaxis.interval = 20
424
+ xaxis.split_number = 5
425
+ yaxis.min = 0
426
+ yaxis.max = 20
427
+ yaxis.interval = 5
428
+ yaxis.split_number = 4
429
+
430
+ # set 1
431
+ series.append({
432
+ 'type': 'rect', 'id': f'rect-{get_random_digits()}', 'name': f'rect-{get_random_digits()}',
433
+ 'color': color, 'myType': 'rect', 'line_width': 1,
434
+ 'data': data.transpose().tolist(),
435
+ 'axis_index': 0, 'z_index': 99
436
+ })
437
+
438
+ xAxis.append({
439
+ 'extent': [float(xaxis.min), float(xaxis.max)],
440
+ 'interval': [float("{:g}".format(float(xaxis.min) + i * float(xaxis.interval))) for i in range(int(xaxis.split_number) + 1)],
441
+ 'id': 0, 'show_frame': True, 'z_index': 9,
442
+ 'title': 'Steps [n]', 'name_location': 'middle',
443
+ })
444
+ yAxis.append({
445
+ 'extent': [float(yaxis.min), float(yaxis.max)],
446
+ 'interval': [float("{:g}".format(float(yaxis.min) + i * float(yaxis.interval))) for i in range(int(yaxis.split_number) + 1)],
447
+ 'id': 0, 'show_frame': True, 'z_index': 9,
448
+ 'title': 'Argon Released [%]', 'name_location': 'middle',
449
+ })
450
+ return xAxis, yAxis, series
451
+
452
+
453
+ def _get_plot_data_degas_curve(smp: sample, **options):
454
+ name = options.get('diagram_name', '39Ar')
455
+ color = options.get('color', 'black')
456
+ xAxis, yAxis, series = [], [], []
457
+ nindex = {"40": 24, "39": 20, "38": 10, "37": 8, "36": 0}
458
+ if name[:2] in list(nindex.keys()):
459
+ ar = np.array(smp.DegasValues[nindex[name[:2]]], dtype=np.float64) # 20-21 Ar39
460
+ sar = np.array(smp.DegasValues[nindex[name[:2]] + 1], dtype=np.float64)
461
+ elif 'total' in name:
462
+ all_ar = np.array(smp.CorrectedValues, dtype=np.float64) # 20-21 Ar39
463
+ ar, sar = arr.add(*all_ar.reshape(5, 2, len(all_ar[0])))
464
+ ar = np.array(ar); sar = np.array(sar)
465
+ else:
466
+ raise KeyError
467
+
468
+ while ar[-1] == 0:
469
+ ar = ar[:-1]
470
+ x = list(range(0, len(ar) + 1))
471
+ f = ar / sum(ar) * 100
472
+ released = np.zeros(len(ar) + 1)
473
+ remained = np.zeros(len(ar) + 1) + 100
474
+ for i in range(1, len(ar) + 1):
475
+ released[i] = sum(f[:i])
476
+ remained[i] = 100 - released[i]
477
+
478
+ # line
479
+ series.append({
480
+ 'type': 'line', 'id': f'line-{get_random_digits()}', 'name': f'line-{get_random_digits()}',
481
+ 'color': color, 'myType': 'line', 'line_width': 1, 'line_style': 'solid',
482
+ 'data': np.array([x, released]).transpose().tolist(),
483
+ 'axis_index': 0, 'z_index': 99
484
+ })
485
+ series.append({
486
+ 'type': 'line', 'id': f'line-{get_random_digits()}', 'name': f'line-{get_random_digits()}',
487
+ 'color': color, 'myType': 'line', 'line_width': 1, 'line_style': 'solid',
488
+ 'data': np.array([x, remained]).transpose().tolist(),
489
+ 'axis_index': 0, 'z_index': 99
490
+ })
491
+
492
+ xAxis.append({
493
+ 'extent': [0, 100],
494
+ 'interval': [0, 20, 40, 60, 80, 100],
495
+ 'id': 0, 'show_frame': True, 'z_index': 9,
496
+ 'title': 'Steps [n]', 'name_location': 'middle',
497
+ })
498
+ yAxis.append({
499
+ 'extent': [0, 100],
500
+ 'interval': [0, 20, 40, 60, 80, 100],
501
+ 'id': 0, 'show_frame': True, 'z_index': 9,
502
+ 'title': 'Argon [%]', 'name_location': 'middle',
503
+ })
504
+ return xAxis, yAxis, series
505
+
506
+
90
507
  class ExcelTemplate:
91
508
  def __init__(self, **kwargs):
92
509
  self.name = ""
ararpy/smp/raw.py CHANGED
@@ -50,8 +50,15 @@ def to_raw(file_path: Union[str, List[str]], input_filter_path: Union[str, List[
50
50
  data = res.get('data', None)
51
51
  sequences = res.get('sequences', None)
52
52
  sequence_num = len(data) if data is not None else len(sequences)
53
- raw = RawData(name=file_name, data=data, isotopic_num=10, sequence_num=sequence_num,
54
- source=[file_path], sequence=sequences, unit=str(input_filter[30]))
53
+ # default fitting method, all exponential
54
+ # <option value=0>Linear</option>
55
+ # <option value=1>Quadratic</option>
56
+ # <option value=2>Exponential</option>
57
+ # <option value=3>Power</option>
58
+ # <option value=4>Average</option>
59
+ fitting_method = [2, 0, 2, 2, 2]
60
+ raw = RawData(name=file_name, data=data, isotopic_num=10, sequence_num=sequence_num, source=[file_path],
61
+ sequence=sequences, unit=str(input_filter[30]), fitting_method=[*fitting_method])
55
62
  else:
56
63
  raise ValueError("File path and input filter should be both string or list with a same length.")
57
64
  return raw
ararpy/smp/sample.py CHANGED
@@ -137,11 +137,11 @@ TOTAL_PARAMS_HEADERS = [
137
137
  'Heating Time (s)', # 125
138
138
  'Heating Actual Temp (C)', # 126
139
139
  'Heating AT 1\u03C3', # 127
140
- '36Ar Gain', '1\u03C3', # 128-129
141
- '37Ar Gain', '1\u03C3', # 130-131
142
- '38Ar Gain', '1\u03C3', # 132-133
143
- '39Ar Gain', '1\u03C3', # 134-135
144
- '40Ar Gain', '1\u03C3', # 136-137
140
+ '36Ar Gain', '%1\u03C3', # 128-129
141
+ '37Ar Gain', '%1\u03C3', # 130-131
142
+ '38Ar Gain', '%1\u03C3', # 132-133
143
+ '39Ar Gain', '%1\u03C3', # 134-135
144
+ '40Ar Gain', '%1\u03C3', # 136-137
145
145
  ]
146
146
 
147
147
  SAMPLE_INTERCEPT_SHORT_HEADERS = [
@@ -250,11 +250,11 @@ TOTAL_PARAMS_SHORT_HEADERS = [
250
250
  'HeatingTime', # 125
251
251
  'HeatingActualTemp', # 126
252
252
  'HeatingActualTempError', # 127
253
- '36Gain', '1s', # 128-129
254
- '37Gain', '1s', # 130-131
255
- '38Gain', '1s', # 132-133
256
- '39Gain', '1s', # 134-135
257
- '40Gain', '1s', # 136-137
253
+ '36Gain', '%1s', # 128-129
254
+ '37Gain', '%1s', # 130-131
255
+ '38Gain', '%1s', # 132-133
256
+ '39Gain', '%1s', # 134-135
257
+ '40Gain', '%1s', # 136-137
258
258
  ]
259
259
 
260
260
  DEFAULT_PLOT_STYLES = {
@@ -741,7 +741,7 @@ DEFAULT_PLOT_STYLES = {
741
741
  },
742
742
  }
743
743
 
744
- VERSION = '20240930'
744
+ VERSION = '20241028'
745
745
 
746
746
  NAMED_DICT = {
747
747
  "unknown": {"header": SAMPLE_INTERCEPT_HEADERS.copy()},
@@ -842,7 +842,8 @@ class Sample:
842
842
  # self.__version = '20230730' # delete calcparams attribute
843
843
  # self.__version = '20230827' # using merge smp to update arr version
844
844
  # self.__version = '20231116' # change smp parameters
845
- self.__version = '20240730' # change parameter table for thermo calculation
845
+ # self.__version = '20240730' # change parameter table for thermo calculation
846
+ self.__version = '20241028' # gain correction
846
847
 
847
848
  @property
848
849
  def version(self):
@@ -1154,16 +1155,21 @@ class RawData:
1154
1155
  self.isotopic_num = isotopic_num
1155
1156
  self.sequence_num = sequence_num
1156
1157
  self.interpolated_blank = None
1157
- if data is not None:
1158
+ if sequence is not None:
1159
+ self.sequence = sequence
1160
+ elif data is not None:
1158
1161
  self.sequence: List[Sequence] = [
1159
- Sequence(index=index, name=item[0][0] if isinstance(item[0][0], str) and item[0][
1160
- 0] != '' else f"{self.name}-{index + 1:02d}", data=item[1:], datetime=item[0][1], type_str=item[0][2],
1161
- fitting_method=[0] * 5, options=item[0][3])
1162
- for index, item in enumerate(data)]
1162
+ Sequence(
1163
+ index=index,
1164
+ name=item[0][0] if isinstance(item[0][0], str) and item[0][0] != '' else f"{self.name}-{index + 1:02d}",
1165
+ data=item[1:],
1166
+ datetime=item[0][1],
1167
+ type_str=item[0][2],
1168
+ fitting_method=[*kwargs.get("fitting_method", [0] * 5)],
1169
+ options=item[0][3]
1170
+ ) for index, item in enumerate(data)]
1163
1171
  else:
1164
1172
  self.sequence: List[Sequence] = []
1165
- if sequence is not None:
1166
- self.sequence = sequence
1167
1173
  for k, v in kwargs.items():
1168
1174
  if hasattr(self, k) and type(getattr(self, k)) is MethodType:
1169
1175
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ararpy
3
- Version: 0.1.12
3
+ Version: 0.1.13
4
4
  Summary: A project for Ar-Ar geochronology
5
5
  Home-page: https://github.com/wuyangchn/ararpy.git
6
6
  Author: Yang Wu