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/calc/arr.py +2 -1
- ararpy/calc/basic.py +36 -14
- ararpy/calc/corr.py +3 -30
- ararpy/calc/raw_funcs.py +2 -2
- ararpy/calc/regression.py +3 -1
- ararpy/files/calc_file.py +1 -1
- ararpy/files/raw_file.py +84 -82
- ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +95 -0
- ararpy/smp/basic.py +6 -5
- ararpy/smp/calculation.py +2 -2
- ararpy/smp/corr.py +99 -77
- ararpy/smp/diffusion_funcs.py +248 -111
- ararpy/smp/export.py +445 -28
- ararpy/smp/raw.py +9 -2
- ararpy/smp/sample.py +25 -19
- {ararpy-0.1.12.dist-info → ararpy-0.1.13.dist-info}/METADATA +1 -1
- {ararpy-0.1.12.dist-info → ararpy-0.1.13.dist-info}/RECORD +20 -19
- {ararpy-0.1.12.dist-info → ararpy-0.1.13.dist-info}/WHEEL +1 -1
- {ararpy-0.1.12.dist-info → ararpy-0.1.13.dist-info}/LICENSE +0 -0
- {ararpy-0.1.12.dist-info → ararpy-0.1.13.dist-info}/top_level.txt +0 -0
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
|
|
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
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
pt.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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(
|
|
79
|
-
|
|
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(
|
|
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
|
-
|
|
54
|
-
|
|
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 = '
|
|
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
|
|
1158
|
+
if sequence is not None:
|
|
1159
|
+
self.sequence = sequence
|
|
1160
|
+
elif data is not None:
|
|
1158
1161
|
self.sequence: List[Sequence] = [
|
|
1159
|
-
Sequence(
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
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
|