ararpy 0.1.19__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/__init__.py +4 -2
- ararpy/calc/age.py +2 -1
- ararpy/calc/arr.py +16 -6
- ararpy/calc/corr.py +9 -7
- ararpy/calc/jvalue.py +1 -1
- ararpy/calc/plot.py +5 -2
- ararpy/files/calc_file.py +2 -5
- ararpy/files/raw_file.py +3 -4
- ararpy/files/xls.py +1 -2
- ararpy/smp/basic.py +119 -70
- ararpy/smp/corr.py +69 -51
- ararpy/smp/export.py +82 -49
- ararpy/smp/initial.py +47 -17
- ararpy/smp/plots.py +126 -87
- ararpy/smp/sample.py +55 -17
- ararpy/smp/style.py +23 -16
- {ararpy-0.1.19.dist-info → ararpy-0.1.20.dist-info}/METADATA +1 -1
- {ararpy-0.1.19.dist-info → ararpy-0.1.20.dist-info}/RECORD +21 -21
- {ararpy-0.1.19.dist-info → ararpy-0.1.20.dist-info}/WHEEL +1 -1
- {ararpy-0.1.19.dist-info → ararpy-0.1.20.dist-info}/licenses/LICENSE +0 -0
- {ararpy-0.1.19.dist-info → ararpy-0.1.20.dist-info}/top_level.txt +0 -0
ararpy/smp/corr.py
CHANGED
|
@@ -25,16 +25,15 @@ from .sample import Sample
|
|
|
25
25
|
def corr_gain(sample: Sample):
|
|
26
26
|
"""Blank Correction"""
|
|
27
27
|
corrGain = True
|
|
28
|
-
gain_corrected = np.zeros([10,
|
|
28
|
+
gain_corrected = np.zeros([10, sample.Info.experiment.step_num])
|
|
29
29
|
try:
|
|
30
30
|
for i in range(5):
|
|
31
31
|
f, sf = np.array(sample.TotalParam[126 + i * 2:128 + i * 2])
|
|
32
32
|
sf = f * sf / 100
|
|
33
33
|
gain_corrected[i * 2:2 + i * 2] = calc.corr.gain(*sample.SampleIntercept[i * 2:2 + i * 2], f, sf)
|
|
34
|
-
except Exception as e:
|
|
35
|
-
print(f"Gain correction failed")
|
|
36
|
-
|
|
37
|
-
return
|
|
34
|
+
except (Exception, BaseException) as e:
|
|
35
|
+
print(f"Gain correction failed: \n{traceback.format_exc()}")
|
|
36
|
+
raise
|
|
38
37
|
for i in range(0, 10, 2):
|
|
39
38
|
gain_corrected[i] = [gain_corrected[i][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i])]
|
|
40
39
|
gain_corrected[i + 1] = [gain_corrected[i + 1][index] if corrGain else j for index, j in enumerate(sample.SampleIntercept[i + 1])]
|
|
@@ -156,15 +155,12 @@ def calc_degas_ca(sample: Sample):
|
|
|
156
155
|
ar39ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[8:10], isRelative=True)
|
|
157
156
|
ar38ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[10:12], isRelative=True)
|
|
158
157
|
ar36ca = calc.arr.mul_factor(ar37ca, sample.TotalParam[12:14], isRelative=True)
|
|
159
|
-
sample.DegasValues[8:10] = copy.deepcopy(ar37ca)
|
|
160
|
-
|
|
161
|
-
# sample.DegasValues[18:20] = ar38ca if corrDecasCa else [[0] * n, [0] * n]
|
|
162
|
-
# sample.DegasValues[4:6] = ar36ca if corrDecasCa else [[0] * n, [0] * n]
|
|
163
|
-
sample.DegasValues[ 4] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[0])]
|
|
158
|
+
sample.DegasValues[8:10] = copy.deepcopy(ar37ca) # 37Ca
|
|
159
|
+
sample.DegasValues[ 4] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[0])] # 36Ca
|
|
164
160
|
sample.DegasValues[ 5] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar36ca[1])]
|
|
165
|
-
sample.DegasValues[18] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[0])]
|
|
161
|
+
sample.DegasValues[18] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[0])] # 38Ca
|
|
166
162
|
sample.DegasValues[19] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar38ca[1])]
|
|
167
|
-
sample.DegasValues[22] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[0])]
|
|
163
|
+
sample.DegasValues[22] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[0])] # 39Ca
|
|
168
164
|
sample.DegasValues[23] = [val if corrDecasCa[idx] else 0 for idx, val in enumerate(ar39ca[1])]
|
|
169
165
|
sample.PublishValues[1] = copy.deepcopy(ar37ca[0])
|
|
170
166
|
|
|
@@ -241,43 +237,51 @@ def calc_degas_cl(sample: Sample):
|
|
|
241
237
|
try:
|
|
242
238
|
if not corrDecasCl:
|
|
243
239
|
raise ValueError("Do not apply degas chlorine")
|
|
244
|
-
|
|
240
|
+
vDecay = [cl36_cl38_p[0][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i])) for i in
|
|
245
241
|
range(len(stand_time_year))]
|
|
246
|
-
|
|
242
|
+
sDecay = [pow((cl36_cl38_p[1][i] * (1 - np.exp(-1 * decay_const[0][i] * stand_time_year[i]))) ** 2 +
|
|
247
243
|
(cl36_cl38_p[0][i] * stand_time_year[i] * (np.exp(-1 * decay_const[0][i] * stand_time_year[i])) *
|
|
248
244
|
decay_const[1][i]) ** 2, 0.5) for i in range(len(stand_time_year))]
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
sDecay = [calc.err.div((1, 0), (vDecay[i], sDecay[i])) for i in range(len(sDecay))]
|
|
246
|
+
vDecay = [1 / vDecay[i] for i in range(len(vDecay))]
|
|
247
|
+
|
|
251
248
|
# 36ArCl
|
|
252
249
|
ar36cl = [[], []]
|
|
253
|
-
ar36cl[0] = [(ar36acl[0][i] * ar38ar36[0][i] - ar38acl[0][i]) / (ar38ar36[0][i] - v3[i])
|
|
254
|
-
for i in range(len(ar36acl[0]))]
|
|
255
|
-
s1 = [(ar36acl[1][i] * ar38ar36[0][i] / (ar38ar36[0][i] - v3[i])) ** 2 for i in range(len(ar36cl[0]))]
|
|
256
|
-
s2 = [(ar38acl[1][i] / (ar38ar36[0][i] - v3[i])) ** 2 for i in range(len(ar36cl[0]))]
|
|
257
|
-
s3 = [(s3[i] * (ar36acl[0][i] * ar38ar36[0][i] - ar38acl[0][i]) / (ar38ar36[0][i] - v3[i]) ** 2) ** 2
|
|
258
|
-
for i in range(len(ar36cl[0]))]
|
|
259
|
-
s4 = [(ar36acl[0][i] / (ar38ar36[0][i] - v3[i]) -
|
|
260
|
-
(ar36acl[0][i] * ar38ar36[0][i] - ar38acl[0][i]) / (ar38ar36[0][i] - v3[i]) ** 2) ** 2 *
|
|
261
|
-
(ar38ar36[1][i]) ** 2 for i in range(len(ar36cl[0]))]
|
|
262
|
-
ar36cl[1] = [pow(s1[i] + s2[i] + s3[i] + s4[i], 0.5) for i in range(len(ar36cl[0]))]
|
|
263
|
-
|
|
264
250
|
# 38ArCl
|
|
265
251
|
ar38cl = [[], []]
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
252
|
+
for i in range(len(vDecay)):
|
|
253
|
+
a1 = sample.CorrectedValues[0][i]; s1 = sample.CorrectedValues[1][i]
|
|
254
|
+
a2 = sample.DegasValues[4][i]; s2 = sample.DegasValues[5][i];
|
|
255
|
+
a3 = sample.DegasValues[16][i]; s3 = sample.DegasValues[17][i]
|
|
256
|
+
a4 = sample.DegasValues[18][i]; s4 = sample.DegasValues[19][i]
|
|
257
|
+
a5 = sample.CorrectedValues[4][i]; s5 = sample.CorrectedValues[5][i]
|
|
258
|
+
a6 = vDecay[i]; s6 = sDecay[i]
|
|
259
|
+
a7 = ar38ar36[0][i]; s7 = ar38ar36[1][i]
|
|
260
|
+
|
|
261
|
+
d1 = 1 / (1 - a6 / a7)
|
|
262
|
+
d2 = - 1 / (1 - a6 / a7)
|
|
263
|
+
d3 = 1 / (a7 - a6)
|
|
264
|
+
d4 = 1 / (a7 - a6)
|
|
265
|
+
d5 = - 1 / (a7 - a6)
|
|
266
|
+
d6 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / a7 / (1 - a6 / a7) ** 2
|
|
267
|
+
d7 = -(a1 - a2) * (a6) / (a7 - a6) ** 2 - (a3 + a4 - a5) / (a7 - a6) ** 2
|
|
268
|
+
|
|
269
|
+
v1 = (a1 - a2 + (a3 + a4) / a7 - a5 / a7) / (1 - a6 / a7)
|
|
270
|
+
s1 = (d1**2*s1**2 + d2**2*s2**2 + d3**2*s3**2 + d4**2*s4**2+ d5**2*s5**2 + d6**2*s6**2 + d7**2*s7**2) ** .5
|
|
271
|
+
s2 = calc.err.mul((v1, s1), (vDecay[i], sDecay[i]))
|
|
272
|
+
v1 = 0 if (ar36acl[0][i] - v1 < 0 or v1 < 0) and set_negative_zero[i] else v1
|
|
273
|
+
v2 = v1 * vDecay[i]
|
|
274
|
+
|
|
275
|
+
# Note: Ar36Cl uncertainty is differen with ArArCALC. All calculation was conducted separately considering they are independent
|
|
276
|
+
# s1 = calc.err.div((a1 - a2 + (a3 + a4) / a7 - a5 / a7, calc.err.add(s1, s2, calc.err.div((a3 + a4, calc.err.add(s3, s4)), (a7, s7)), calc.err.div((a5, s5), (a7, s7)))), (1 - a6 / a7, calc.err.div((a6, s6), (a7, s7))))
|
|
277
|
+
|
|
278
|
+
ar36cl[0].append(v1); ar36cl[1].append(s1)
|
|
279
|
+
ar38cl[0].append(v2); ar38cl[1].append(s2)
|
|
275
280
|
|
|
276
281
|
except Exception as e:
|
|
277
282
|
print('Error in corr Cl: {}, lines: {}'.format(e, e.__traceback__.tb_lineno))
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
ar38cl = np.zeros([2, n])
|
|
283
|
+
ar36cl = np.zeros([2, len(ar36acl[0])])
|
|
284
|
+
ar38cl = np.zeros([2, len(ar36acl[0])])
|
|
281
285
|
|
|
282
286
|
# sample.DegasValues[6:8] = ar36cl
|
|
283
287
|
# sample.DegasValues[10:12] = ar38cl
|
|
@@ -349,7 +353,7 @@ def calc_degas_r(sample: Sample):
|
|
|
349
353
|
"""
|
|
350
354
|
ar40ar = calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32])
|
|
351
355
|
ar40r = calc.arr.sub(ar40ar, sample.DegasValues[26:28])
|
|
352
|
-
ar40r[0] = [
|
|
356
|
+
ar40r[0] = [0 if item < 0 and sample.TotalParam[101][index] else item for index, item in enumerate(ar40r[0])]
|
|
353
357
|
sample.DegasValues[24:26] = copy.deepcopy(ar40r)
|
|
354
358
|
sample.PublishValues[4] = copy.deepcopy(ar40r[0])
|
|
355
359
|
|
|
@@ -360,11 +364,16 @@ def calc_degas_r(sample: Sample):
|
|
|
360
364
|
def calc_nor_inv_isochrons(sample: Sample):
|
|
361
365
|
n = len(sample.SequenceName)
|
|
362
366
|
try:
|
|
363
|
-
isochron_1 = calc.isochron.get_data(
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
sample.
|
|
367
|
-
|
|
367
|
+
isochron_1 = calc.isochron.get_data(
|
|
368
|
+
*calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
|
|
369
|
+
*calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]),
|
|
370
|
+
*sample.DegasValues[0:2]
|
|
371
|
+
)
|
|
372
|
+
isochron_2 = calc.isochron.get_data(
|
|
373
|
+
*calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
|
|
374
|
+
*sample.DegasValues[0:2],
|
|
375
|
+
*calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32]))
|
|
376
|
+
except (BaseException, Exception):
|
|
368
377
|
return np.zeros([5, n]), np.zeros([5, n])
|
|
369
378
|
else:
|
|
370
379
|
return isochron_1, isochron_2
|
|
@@ -374,12 +383,18 @@ def calc_cl_isochrons(sample: Sample):
|
|
|
374
383
|
n = len(sample.SequenceName)
|
|
375
384
|
try:
|
|
376
385
|
isochron_3 = calc.isochron.get_data(
|
|
377
|
-
*sample.DegasValues[20:22],
|
|
386
|
+
*calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
|
|
387
|
+
*sample.DegasValues[24:26],
|
|
388
|
+
*calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor))
|
|
378
389
|
isochron_4 = calc.isochron.get_data(
|
|
379
|
-
*sample.DegasValues[20:22],
|
|
390
|
+
*calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor),
|
|
391
|
+
*calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor),
|
|
392
|
+
*sample.DegasValues[24:26])
|
|
380
393
|
isochron_5 = calc.isochron.get_data(
|
|
381
|
-
*sample.DegasValues[10:12],
|
|
382
|
-
|
|
394
|
+
*calc.arr.mul(sample.DegasValues[10:12], sample.NormalizeFactor),
|
|
395
|
+
*sample.DegasValues[24:26],
|
|
396
|
+
*calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor))
|
|
397
|
+
except (BaseException, Exception):
|
|
383
398
|
return np.zeros([5, n]), np.zeros([5, n]), np.zeros([5, n])
|
|
384
399
|
else:
|
|
385
400
|
return isochron_3, isochron_4, isochron_5
|
|
@@ -422,7 +437,6 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
|
|
|
422
437
|
"""
|
|
423
438
|
ar40r_percent = [item / sample.CorrectedValues[8][index] * 100 if sample.CorrectedValues[8][index] != 0 else 0
|
|
424
439
|
for index, item in enumerate(sample.DegasValues[24])]
|
|
425
|
-
sum_ar39k = sum(sample.DegasValues[20])
|
|
426
440
|
sum_ar36a = sum(sample.DegasValues[ 0])
|
|
427
441
|
CaK = calc.arr.mul_factor(calc.arr.mul_factor(
|
|
428
442
|
sample.DegasValues[8:10], calc.arr.rec_factor(sample.DegasValues[20:22], isRelative=False)),
|
|
@@ -437,10 +451,12 @@ def calc_ratio(sample: Sample, monte_carlo: bool = False):
|
|
|
437
451
|
sample.ApparentAgeValues[0:2] = ar40aar36a
|
|
438
452
|
sample.ApparentAgeValues[7] = ar36a_percent
|
|
439
453
|
else:
|
|
454
|
+
ar39k, sar39k = calc.arr.mul(sample.DegasValues[20:22], sample.NormalizeFactor)
|
|
455
|
+
sum_ar39k = sum(ar39k)
|
|
456
|
+
ar39k_percent = [item / sum_ar39k * 100 if sum_ar39k != 0 else 0 for item in ar39k]
|
|
440
457
|
ar40rar39k = calc.arr.mul_factor(
|
|
441
458
|
sample.DegasValues[24:26], calc.arr.rec_factor(sample.DegasValues[20:22], isRelative=False),
|
|
442
459
|
isRelative=False)
|
|
443
|
-
ar39k_percent = [item / sum_ar39k * 100 if sum_ar39k != 0 else 0 for item in sample.DegasValues[20]]
|
|
444
460
|
sample.ApparentAgeValues[0:2] = ar40rar39k
|
|
445
461
|
sample.ApparentAgeValues[7] = ar39k_percent
|
|
446
462
|
|
|
@@ -529,6 +545,7 @@ def monte_carlo_f(sample: Sample):
|
|
|
529
545
|
R36v38clp = np.transpose(sample.TotalParam[56:58])
|
|
530
546
|
|
|
531
547
|
stand_time_year = np.transpose(sample.TotalParam[32])
|
|
548
|
+
JNFactor = sample.NormalizeFactor
|
|
532
549
|
|
|
533
550
|
irradiation_cycles = [list(filter(None, re.split(r'[DS]', each_step))) for each_step in sample.TotalParam[27]]
|
|
534
551
|
t1 = [re.findall(r"\d+", i) for i in sample.TotalParam[31]] # t1: experimental times
|
|
@@ -562,6 +579,7 @@ def monte_carlo_f(sample: Sample):
|
|
|
562
579
|
L37ar=L37ar[i], L39ar=L39ar[i], L36cl=L36cl[i],
|
|
563
580
|
MDFunc=None,
|
|
564
581
|
MDF=MDF[i], stand_time_year=stand_time_year[i],
|
|
582
|
+
JNFactor=JNFactor,
|
|
565
583
|
blank_gain_corr=sample.TotalParam[111][i]
|
|
566
584
|
)
|
|
567
585
|
|
ararpy/smp/export.py
CHANGED
|
@@ -38,8 +38,8 @@ except ModuleNotFoundError:
|
|
|
38
38
|
SETTINGS_ROOT = ""
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def to_excel(file_path: str):
|
|
42
|
-
excel = WritingWorkbook(filepath=file_path)
|
|
41
|
+
def to_excel(smp: Sample, file_path: str, *args, **kwargs):
|
|
42
|
+
excel = WritingWorkbook(sample=smp, filepath=file_path, *args, **kwargs)
|
|
43
43
|
excel.get_xls()
|
|
44
44
|
|
|
45
45
|
|
|
@@ -297,6 +297,24 @@ def get_plot_series_data(smp: Sample, diagram: str = 'age spectra', **options):
|
|
|
297
297
|
return series
|
|
298
298
|
|
|
299
299
|
|
|
300
|
+
def spectraData2Sgima(data, sigma=2):
|
|
301
|
+
return list(map(lambda row: [row[0], (row[1] - row[2]) / 2 * (sigma - 1) + row[1], (row[2] - row[1]) / 2 * (sigma - 1) + row[2]], data))
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def getRectFromSpectra(data):
|
|
305
|
+
"""
|
|
306
|
+
Parameters
|
|
307
|
+
----------
|
|
308
|
+
data: [x, y1, y2]
|
|
309
|
+
|
|
310
|
+
Returns
|
|
311
|
+
-------
|
|
312
|
+
|
|
313
|
+
"""
|
|
314
|
+
data = np.array(data)
|
|
315
|
+
return list(map(lambda index: [data[index,0], min(data[index,[1,2]]), np.diff(data[[index,index+1],0])[0], np.diff(data[index,[1,2]])[0]], list(range(len(data) - 1))))
|
|
316
|
+
|
|
317
|
+
|
|
300
318
|
def _get_additional_text_series(name):
|
|
301
319
|
return {
|
|
302
320
|
'type': 'text', 'id': f'text-{name}-{get_random_digits()}',
|
|
@@ -330,22 +348,42 @@ def _get_plot_data_age_spectra_series(smp: sample, **options):
|
|
|
330
348
|
})
|
|
331
349
|
text1 = smp.AgeSpectraPlot.text1
|
|
332
350
|
text2 = smp.AgeSpectraPlot.text2
|
|
351
|
+
sigma = 1
|
|
352
|
+
set_data = [spectraData2Sgima(smp.AgeSpectraPlot.set1.data, sigma),
|
|
353
|
+
spectraData2Sgima(smp.AgeSpectraPlot.set2.data, sigma)]
|
|
333
354
|
for index, text in enumerate([text1, text2]):
|
|
334
|
-
|
|
355
|
+
res = smp.Info.results.age_plateau[index]
|
|
356
|
+
if not np.isnan(res['age']):
|
|
335
357
|
selection = np.array(smp.Info.results.selection[index]['data']) * 2 + 1
|
|
336
|
-
|
|
358
|
+
plateau_data = np.array(set_data[index])
|
|
359
|
+
# spectra_fill_data = list(map(lambda each: [data[0][each - 1], min(data[1][each], data[2][each]), data[0][each + 1] - data[0][each], sigma * abs(data[1][each] - data[2][each])], selection))
|
|
360
|
+
spectra_fill_data = getRectFromSpectra(plateau_data)
|
|
337
361
|
series.append({
|
|
338
362
|
'type': 'series.rect', 'id': f'rect-{smp.name()}-{get_random_digits()}', 'name': f'rect-{smp.name()}-{get_random_digits()}',
|
|
339
|
-
'color': '
|
|
340
|
-
'data':
|
|
363
|
+
'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index], 'line_width': 0, 'line_style': 'solid', 'z_index': 9,
|
|
364
|
+
'data': spectra_fill_data, 'line_caps': 'square', 'fill': True,
|
|
365
|
+
'axis_index': 0,
|
|
366
|
+
})
|
|
367
|
+
series.append({
|
|
368
|
+
'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
|
|
369
|
+
'name': f'line-{smp.name()}-{get_random_digits()}',
|
|
370
|
+
'color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
|
|
371
|
+
'data': plateau_data[:,[0,1]].tolist(), 'line_caps': 'square',
|
|
372
|
+
'axis_index': 0,
|
|
373
|
+
})
|
|
374
|
+
series.append({
|
|
375
|
+
'type': 'series.line', 'id': f'line-{smp.name()}-{get_random_digits()}',
|
|
376
|
+
'name': f'line-{smp.name()}-{get_random_digits()}',
|
|
377
|
+
'color': ['red', 'blue'][index], 'line_width': 1, 'line_style': 'solid', 'z_index': 9,
|
|
378
|
+
'data': plateau_data[:,[0,2]].tolist(), 'line_caps': 'square',
|
|
341
379
|
'axis_index': 0,
|
|
342
380
|
})
|
|
343
381
|
series.append({
|
|
344
382
|
'type': 'text', 'id': f'text-{smp.name()}-{get_random_digits()}', 'name': f'text-{smp.name()}-{get_random_digits()}',
|
|
345
383
|
'color': ['red', 'blue'][index], 'fill_color': ['red', 'blue'][index],
|
|
346
|
-
'text': f"WMPA = {
|
|
347
|
-
f"MSWD = {
|
|
348
|
-
f"<sup>39</sup>Ar = {
|
|
384
|
+
'text': f"WMPA = {res['age']:.2f} ± {(sigma * res['s3']):.2f} Ma<r>"
|
|
385
|
+
f"MSWD = {res['MSWD']:.2f}, n = {res['Num']:.0f}<r>"
|
|
386
|
+
f"<sup>39</sup>Ar = {res['Ar39']:.2f}%",
|
|
349
387
|
'size': title_size,
|
|
350
388
|
'data': [text.pos],
|
|
351
389
|
'axis_index': 1,
|
|
@@ -386,10 +424,15 @@ def _get_plot_data_age_spectra_axis(smp: sample, **options):
|
|
|
386
424
|
y_low_limit, y_up_limit, stick_num, inc = get_axis_scale(np.array(data[1:3]).flatten())
|
|
387
425
|
y_extent = [y_low_limit, y_up_limit]
|
|
388
426
|
y_interval = [y_low_limit + i * inc for i in range(stick_num + 1)]
|
|
427
|
+
y_interval.extend([y_up_limit * 10] * 3)
|
|
428
|
+
dp = int(np.log10(abs(y_up_limit - y_low_limit)) - 1)
|
|
429
|
+
dp = 0 if dp >= 0 else abs(dp)
|
|
430
|
+
print(f"{dp = }")
|
|
431
|
+
y_interval = [f"{i:.{dp}f}" for i in y_interval]
|
|
389
432
|
|
|
390
|
-
y_extent = [4, 12]
|
|
391
|
-
y_interval = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']
|
|
392
|
-
y_interval = ['0', '4', '6', '8', '10', '12', '60', '70', '80', '90', '100']
|
|
433
|
+
# y_extent = [4, 12]
|
|
434
|
+
# y_interval = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100']
|
|
435
|
+
# y_interval = ['0', '4', '6', '8', '10', '12', '60', '70', '80', '90', '100']
|
|
393
436
|
|
|
394
437
|
xAxis.append({
|
|
395
438
|
'extent': [0, 100], 'interval': [0, 20, 40, 60, 80, 100], 'id': 0, 'show_frame': True,
|
|
@@ -762,16 +805,6 @@ class WritingWorkbook:
|
|
|
762
805
|
|
|
763
806
|
if self.template_filepath is not None:
|
|
764
807
|
self.read_template()
|
|
765
|
-
if self.style is None:
|
|
766
|
-
self.style = {
|
|
767
|
-
'font_size': 10, 'font_name': 'Microsoft Sans Serif', 'bold': False,
|
|
768
|
-
'bg_color': '#FFFFFF', # back ground
|
|
769
|
-
'font_color': '#000000', 'align': 'left',
|
|
770
|
-
'top': 1, 'left': 1, 'right': 1, 'bottom': 1 # border width
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
def spectraData2Sgima(self, data, sigma=2):
|
|
774
|
-
return list(map(lambda row: [row[0], (row[1] - row[2]) / 2 * (sigma - 1) + row[1], (row[2] - row[1]) / 2 * (sigma - 1) + row[2]], data))
|
|
775
808
|
|
|
776
809
|
def read_template(self):
|
|
777
810
|
# print(self.template_filepath)
|
|
@@ -781,7 +814,7 @@ class WritingWorkbook:
|
|
|
781
814
|
# TypeError: NAN/INF not supported in write_number() without 'nan_inf_to_errors' Workbook() option
|
|
782
815
|
xls = Workbook(self.filepath, {"nan_inf_to_errors": True})
|
|
783
816
|
|
|
784
|
-
style = xls.add_format(self.
|
|
817
|
+
style = xls.add_format(self.default_fmt_prop)
|
|
785
818
|
|
|
786
819
|
sigma = int(self.sample.Info.preference['confidenceLevel'])
|
|
787
820
|
|
|
@@ -809,9 +842,9 @@ class WritingWorkbook:
|
|
|
809
842
|
|
|
810
843
|
# Data for age spectra
|
|
811
844
|
try:
|
|
812
|
-
spectra_data = arr.transpose(
|
|
813
|
-
spectra_set1_data = arr.transpose(
|
|
814
|
-
spectra_set2_data = arr.transpose(
|
|
845
|
+
spectra_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.data, sigma))
|
|
846
|
+
spectra_set1_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.set1.data, sigma)) or [[]] * 3
|
|
847
|
+
spectra_set2_data = arr.transpose(spectraData2Sgima(self.sample.AgeSpectraPlot.set2.data, sigma)) or [[]] * 3
|
|
815
848
|
sht_reference.write_column(f"A{start_row}", spectra_data[0], style)
|
|
816
849
|
sht_reference.write_column(f"B{start_row}", spectra_data[1], style)
|
|
817
850
|
sht_reference.write_column(f"C{start_row}", spectra_data[2], style)
|
|
@@ -1036,7 +1069,7 @@ class WritingWorkbook:
|
|
|
1036
1069
|
material = self.sample.Info.sample.material
|
|
1037
1070
|
weight = self.sample.Info.sample.weight
|
|
1038
1071
|
J_value = self.sample.TotalParam[67][0]
|
|
1039
|
-
J_error = self.sample.TotalParam[68][0]
|
|
1072
|
+
J_error = self.sample.TotalParam[68][0] * self.sample.TotalParam[67][0] / 100
|
|
1040
1073
|
sigma = self.sample.Info.preference['confidenceLevel']
|
|
1041
1074
|
sequence_type = {"StepLaser": "Laser", "StepFurnace": "Temperature", "StepCrusher": "Drop", }.get(method, "Step Value")
|
|
1042
1075
|
sequence_unit = self.sample.Info.sample.sequence_unit if self.sample.Info.sample.sequence_unit != "" else "Unit"
|
|
@@ -1046,27 +1079,27 @@ class WritingWorkbook:
|
|
|
1046
1079
|
set2_ratio = [self.sample.Info.results.isochron['figure_3'][1]['initial'], self.sample.Info.results.isochron['figure_2'][1]['initial'], self.sample.TotalParam[118][0]][int(self.sample.TotalParam[115][0])]
|
|
1047
1080
|
|
|
1048
1081
|
content = [
|
|
1049
|
-
[(0, 0
|
|
1050
|
-
[(1, 0, 2, 0), f"Step", {'bold': 1}],
|
|
1051
|
-
[(1, 1), f"{sequence_type}", {'bold': 1}],
|
|
1052
|
-
[(2, 1), f"({sequence_unit})", {'bold': 1}],
|
|
1053
|
-
[(1, 2, 2, 2), f"Set", {'bold': 1}],
|
|
1054
|
-
[(1, 3, 2, 3), f"36Arair", {'bold': 1}],
|
|
1055
|
-
[(1, 4, 2, 4), f"
|
|
1056
|
-
[(1, 5, 2, 5), f"
|
|
1057
|
-
[(1, 6, 2, 6), f"
|
|
1058
|
-
[(1, 7, 2, 7), f"
|
|
1059
|
-
[(1, 8, 2, 8), f"39Ar/40Ar", {'bold': 1}],
|
|
1060
|
-
[(1, 9, 2, 9), f"36Ar/40Ar", {'bold': 1}],
|
|
1061
|
-
[(1, 10), f"Apparent Age", {'bold': 1}],
|
|
1062
|
-
[(1, 11), f"± {sigma} σ", {'bold': 1}],
|
|
1063
|
-
[(2, 10, 2, 11), f"({age_unit})", {'bold': 1}],
|
|
1064
|
-
[(1, 12), f"40Ar*", {'bold': 1}],
|
|
1065
|
-
[(2, 12), f"(%)", {'bold': 1}],
|
|
1066
|
-
[(1, 13), f"39ArK", {'bold': 1}],
|
|
1067
|
-
[(2, 13), f"(%)", {'bold': 1}],
|
|
1068
|
-
[(1, 14, 2, 14), f"Ca/K", {'bold': 1}],
|
|
1069
|
-
[(3, 0
|
|
1082
|
+
[(0, 0), f"Table 1. 40Ar/39Ar dating results", {'bold': 1, 'top': 1, 'align': 'left'}],
|
|
1083
|
+
[(1, 0, 2, 0), f"Step", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1084
|
+
[(1, 1), f"{sequence_type}", {'bold': 1, 'top': 1}],
|
|
1085
|
+
[(2, 1), f"({sequence_unit})", {'bold': 1, 'bottom': 6}],
|
|
1086
|
+
[(1, 2, 2, 2), f"Set", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1087
|
+
[(1, 3, 2, 3), f"36Arair", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1088
|
+
[(1, 4, 2, 4), f"37ArCa", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1089
|
+
[(1, 5, 2, 5), f"38ArCl", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1090
|
+
[(1, 6, 2, 6), f"39ArK", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1091
|
+
[(1, 7, 2, 7), f"40Ar*", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1092
|
+
[(1, 8, 2, 8), f"39Ar/40Ar", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1093
|
+
[(1, 9, 2, 9), f"36Ar/40Ar", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1094
|
+
[(1, 10), f"Apparent Age", {'bold': 1, 'top': 1}],
|
|
1095
|
+
[(1, 11), f"± {sigma} σ", {'bold': 1, 'top': 1}],
|
|
1096
|
+
[(2, 10, 2, 11), f"({age_unit})", {'bold': 1, 'bottom': 6}],
|
|
1097
|
+
[(1, 12), f"40Ar*", {'bold': 1, 'top': 1}],
|
|
1098
|
+
[(2, 12), f"(%)", {'bold': 1, 'bottom': 6}],
|
|
1099
|
+
[(1, 13), f"39ArK", {'bold': 1, 'top': 1}],
|
|
1100
|
+
[(2, 13), f"(%)", {'bold': 1, 'bottom': 6}],
|
|
1101
|
+
[(1, 14, 2, 14), f"Ca/K", {'bold': 1, 'top': 1, 'bottom': 6}],
|
|
1102
|
+
[(3, 0), f"Sample {name} ({material}){' by ' if method != '' else ''}{method}, weight = {weight} mg, J = {J_value} ± {J_error}", {'bold': 1, 'italic': 1, 'align': 'left'}],
|
|
1070
1103
|
[(4, 0, 1), self.sample.SequenceName, {'align': 'left'}],
|
|
1071
1104
|
[(4, 1, 1), self.sample.SequenceValue, {'num_format': 'General'}],
|
|
1072
1105
|
[(4, 2, 1), list(map(lambda x: int(x) if str(x).isnumeric() else "", self.sample.IsochronMark)), {'num_format': 'General'}],
|
|
@@ -1084,7 +1117,7 @@ class WritingWorkbook:
|
|
|
1084
1117
|
[(4, 14, 1), self.sample.PublishValues[9], {}],
|
|
1085
1118
|
[(4 + num_step, 0, 0), [''] * 15, {'bold': 1, 'top': 1}],
|
|
1086
1119
|
|
|
1087
|
-
[(5 + num_step, 0
|
|
1120
|
+
[(5 + num_step, 0), "Table 2. 40Ar/39Ar age summary", {'bold': 1, 'align': 'left'}],
|
|
1088
1121
|
[(6 + num_step, 0, 7 + num_step, 0), "Group", {'bold': 1, 'top': 1}],
|
|
1089
1122
|
[(6 + num_step, 1, 7 + num_step, 1), "40Arr/39K", {'bold': 1, 'top': 1}],
|
|
1090
1123
|
[(6 + num_step, 2, 7 + num_step, 2), f"± {sigma} σ", {'bold': 1, 'top': 1}],
|
ararpy/smp/initial.py
CHANGED
|
@@ -16,7 +16,7 @@ import pandas as pd
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
import copy
|
|
18
18
|
from typing import List, Union, Optional
|
|
19
|
-
from ..calc import arr
|
|
19
|
+
from ..calc import arr, err
|
|
20
20
|
from ..files import calc_file
|
|
21
21
|
from . import (sample as samples, basic, table, raw as smp_raw)
|
|
22
22
|
|
|
@@ -183,7 +183,10 @@ def initial(smp: Sample):
|
|
|
183
183
|
reference=ArArBasic(
|
|
184
184
|
name='REFERENCE', journal='JOURNAL', doi='DOI'
|
|
185
185
|
),
|
|
186
|
-
preference=copy.deepcopy(PREFERENCE_RES)
|
|
186
|
+
preference=copy.deepcopy(PREFERENCE_RES),
|
|
187
|
+
experiment=ArArBasic(
|
|
188
|
+
name='', mass_spec='', collectors='', step_num=0
|
|
189
|
+
),
|
|
187
190
|
))
|
|
188
191
|
|
|
189
192
|
decimal_places = PREFERENCE_RES['decimalPlaces']
|
|
@@ -234,7 +237,7 @@ def initial(smp: Sample):
|
|
|
234
237
|
return smp
|
|
235
238
|
|
|
236
239
|
|
|
237
|
-
def initial_plot_styles(
|
|
240
|
+
def initial_plot_styles(smp: Sample, except_attrs=None):
|
|
238
241
|
"""
|
|
239
242
|
Initialize plot components styles based on Default Styles. Except attrs is a list containing attrs
|
|
240
243
|
that are not expected to be initialized.
|
|
@@ -258,17 +261,26 @@ def initial_plot_styles(sample: Sample, except_attrs=None):
|
|
|
258
261
|
for k, v in value.items():
|
|
259
262
|
set_attr(getattr(obj, name), k, v)
|
|
260
263
|
|
|
261
|
-
default_styles =
|
|
264
|
+
default_styles = get_default_plot_style(smp)
|
|
262
265
|
for figure_index, figure_attr in default_styles.items():
|
|
263
|
-
plot = getattr(
|
|
266
|
+
plot = getattr(smp, figure_attr['attr_name'], Plot())
|
|
264
267
|
for key, attr in figure_attr.items():
|
|
265
268
|
set_attr(plot, key, attr)
|
|
266
269
|
|
|
267
270
|
|
|
268
|
-
def
|
|
271
|
+
def get_default_plot_style(smp: Sample):
|
|
272
|
+
sample_type = smp.Info.sample.type
|
|
273
|
+
try:
|
|
274
|
+
age_unit = str(smp.Info.preference['ageUnit']).capitalize()
|
|
275
|
+
except:
|
|
276
|
+
age_unit = "Undefined"
|
|
277
|
+
return copy.deepcopy(samples.DEFAULT_PLOT_STYLES(sample_type, age_unit))
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def re_set_smp(smp: Sample):
|
|
269
281
|
std = initial(Sample())
|
|
270
|
-
basic.get_merged_smp(
|
|
271
|
-
return
|
|
282
|
+
basic.get_merged_smp(smp, std)
|
|
283
|
+
return check_version(smp)
|
|
272
284
|
|
|
273
285
|
|
|
274
286
|
def check_version(smp: Sample):
|
|
@@ -283,7 +295,28 @@ def check_version(smp: Sample):
|
|
|
283
295
|
|
|
284
296
|
"""
|
|
285
297
|
if smp.version != samples.VERSION:
|
|
286
|
-
|
|
298
|
+
std = initial(Sample())
|
|
299
|
+
basic.get_merged_smp(smp, std)
|
|
300
|
+
|
|
301
|
+
# 20250328: # Experiment info
|
|
302
|
+
smp.Info.experiment.name = smp.name()
|
|
303
|
+
smp.Info.experiment.step_num = smp.sequence().size
|
|
304
|
+
|
|
305
|
+
# 20250404
|
|
306
|
+
doNormalize = True
|
|
307
|
+
v, sv = [], []
|
|
308
|
+
if smp.Info.sample.type.lower() == "unknown":
|
|
309
|
+
v, sv = smp.TotalParam[67:69]
|
|
310
|
+
sv = np.multiply(v, sv) / 100
|
|
311
|
+
elif smp.Info.sample.type.lower() == "air":
|
|
312
|
+
v, sv = smp.TotalParam[93:95]
|
|
313
|
+
sv = np.multiply(v, sv) / 100
|
|
314
|
+
elif smp.Info.sample.type.lower() == "standard":
|
|
315
|
+
v, sv = smp.TotalParam[59:61]
|
|
316
|
+
smp.NormalizeFactor = [
|
|
317
|
+
[1 if v[0] == each or not doNormalize else v[0] / each for each in v],
|
|
318
|
+
[0 if v[0] == v[i] or not doNormalize else err.div((v[0], sv[0]), (v[i], sv[i])) for i in range(len(v))]
|
|
319
|
+
]
|
|
287
320
|
return smp
|
|
288
321
|
|
|
289
322
|
|
|
@@ -329,11 +362,8 @@ def from_arr_files(file_path, sample_name: str = ""):
|
|
|
329
362
|
def renamed_load(file_obj):
|
|
330
363
|
return RenameUnpickler(file_obj).load()
|
|
331
364
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
sample = renamed_load(f)
|
|
335
|
-
except (Exception, BaseException):
|
|
336
|
-
raise ValueError(f"Fail to open arr file: {file_path}")
|
|
365
|
+
with open(file_path, 'rb') as f:
|
|
366
|
+
sample = renamed_load(f)
|
|
337
367
|
# Check arr version
|
|
338
368
|
# recalculation will not be applied automatically
|
|
339
369
|
return check_version(sample)
|
|
@@ -353,7 +383,7 @@ def from_calc_files(file_path: str, **kwargs):
|
|
|
353
383
|
"""
|
|
354
384
|
file = calc_file.ArArCalcFile(file_path=file_path, **kwargs).open()
|
|
355
385
|
sample = create_sample_from_df(file.get_content(), file.get_smp_info())
|
|
356
|
-
return sample
|
|
386
|
+
return check_version(sample)
|
|
357
387
|
|
|
358
388
|
|
|
359
389
|
# create
|
|
@@ -372,7 +402,7 @@ def from_full_files(file_path: str, sample_name: str = None):
|
|
|
372
402
|
sample_name = str(os.path.split(file_path)[-1]).split('.')[0]
|
|
373
403
|
content, sample_info = calc_file.open_full_xls(file_path, sample_name)
|
|
374
404
|
sample = create_sample_from_dict(content=content, smp_info=sample_info)
|
|
375
|
-
return sample
|
|
405
|
+
return check_version(sample)
|
|
376
406
|
|
|
377
407
|
|
|
378
408
|
# create
|
|
@@ -450,4 +480,4 @@ def from_raw_data(raw: RawData, mapping: Optional[List[dict]] = None) -> Sample:
|
|
|
450
480
|
|
|
451
481
|
# sample.TotalParam[31] = [raw.get_sequence(row['unknown'], flag='name').datetime for row in mapping]
|
|
452
482
|
|
|
453
|
-
return sample
|
|
483
|
+
return check_version(sample)
|