ararpy 0.1.191__tar.gz → 0.1.195__tar.gz
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-0.1.191 → ararpy-0.1.195}/PKG-INFO +1 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/__init__.py +4 -2
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/arr.py +10 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/calc_file.py +2 -5
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/raw_file.py +1 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/xls.py +1 -2
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/basic.py +35 -44
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/corr.py +1 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/export.py +82 -49
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/initial.py +17 -13
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/sample.py +6 -3
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy.egg-info/PKG-INFO +1 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/setup.py +1 -1
- {ararpy-0.1.191 → ararpy-0.1.195}/LICENSE +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/README.md +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/__init__.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/age.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/basic.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/corr.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/err.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/histogram.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/isochron.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/jvalue.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/plot.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/raw_funcs.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/regression.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/calc/spectra.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/022_VU124-M11a.ahd +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/20WHA0103.age +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/22WHA0078.xls +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/22WHA0433.age +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/22WHA0433.arr +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/22WHA0433.full.xls +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/24WHN0001-51-592.XLS +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/AHD.input-filter +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/ArAr.calc +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/ArArCALC.age +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/NGX-600 - Copy.TXT +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/NGX-600.TXT +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/NGX-XLS.input-filter +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/Qtegra-exported-xls.input-filter +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/S01-239.csv +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/WH01.irra +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/WHA.pdf +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/raw_example.xls +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/examples/sample-default.smp +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/__init__.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/arr_file.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/basic.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/files/new_file.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/__init__.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/calculation.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/consts.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/diffusion_funcs.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/info.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/json.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/plots.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/raw.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/style.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/smp/table.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/test.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/thermo/__init__.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/thermo/arrhenius.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/thermo/atomic_level_random_walk.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy/thermo/basic.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy.egg-info/SOURCES.txt +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy.egg-info/dependency_links.txt +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/ararpy.egg-info/top_level.txt +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/setup.cfg +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/tests/test.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/tests/test2.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/tests/test_error_correlation.py +0 -0
- {ararpy-0.1.191 → ararpy-0.1.195}/tests/test_regression_methods.py +0 -0
|
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
|
|
|
16
16
|
""" Information """
|
|
17
17
|
|
|
18
18
|
name = 'ararpy'
|
|
19
|
-
version = '0.
|
|
19
|
+
version = '0.1.195'
|
|
20
20
|
__version__ = version
|
|
21
21
|
full_version = version
|
|
22
|
-
last_update = '2024-
|
|
22
|
+
last_update = '2024-03-28'
|
|
23
23
|
|
|
24
24
|
""" ArArPy Functions """
|
|
25
25
|
|
|
@@ -116,6 +116,8 @@ Sample.plot_cl_3 = lambda _smp: smp.calculation.recalculate(
|
|
|
116
116
|
Sample.plot_3D = lambda _smp: smp.calculation.recalculate(
|
|
117
117
|
_smp, re_plot=True, isIsochron=True, isInit=False, isPlateau=False, figures=['figure_7'])
|
|
118
118
|
|
|
119
|
+
Sample.to_excel = lambda _smp, file_path, *args, **kwargs: smp.export.to_excel(_smp, file_path=file_path, *args, **kwargs)
|
|
120
|
+
|
|
119
121
|
Sample.show_data = lambda _smp: \
|
|
120
122
|
f"Sample Name: \n\t{_smp.name()}\n" \
|
|
121
123
|
f"Doi: \n\t{_smp.doi()}\n" \
|
|
@@ -514,6 +514,15 @@ def transpose(obj, ignore: bool = True):
|
|
|
514
514
|
raise ValueError
|
|
515
515
|
|
|
516
516
|
|
|
517
|
+
def remove_empty(a: list):
|
|
518
|
+
index = 0
|
|
519
|
+
for i in range(len(a)):
|
|
520
|
+
if not is_empty(a[-(i + 1)]):
|
|
521
|
+
index = len(a) - i
|
|
522
|
+
break
|
|
523
|
+
return transpose(a[:index])
|
|
524
|
+
|
|
525
|
+
|
|
517
526
|
def get_item(obj: list, loc: (list, tuple, int), default: Union[str, int, float, bool] = None,
|
|
518
527
|
base: Union[int, tuple, list] = 0) -> Union[str, int, float, bool]:
|
|
519
528
|
""" Get item from a n-dimension list
|
|
@@ -566,7 +575,7 @@ def wtd_mean(a: list, e: list, sf: int = 1, adjust_error: bool = True):
|
|
|
566
575
|
k0 = sum(a * wt) / sum(wt) # error weighting
|
|
567
576
|
k4 = sum((a - k0) ** 2 * wt) # Chi square
|
|
568
577
|
k3 = k4 / df # MSWD mentioned in Min et al., 2000
|
|
569
|
-
if adjust_error:
|
|
578
|
+
if adjust_error and k3 > 1:
|
|
570
579
|
k1 = (k3 / sum(wt)) ** .5
|
|
571
580
|
else:
|
|
572
581
|
k1 = (1 / sum(wt)) ** .5
|
|
@@ -49,8 +49,7 @@ def read_calc_file(file_path: str):
|
|
|
49
49
|
book_contents[each_sheet] = sheet_contents
|
|
50
50
|
os.remove(decrypt_file_path)
|
|
51
51
|
except Exception as e:
|
|
52
|
-
|
|
53
|
-
return False
|
|
52
|
+
raise
|
|
54
53
|
else:
|
|
55
54
|
return book_contents
|
|
56
55
|
|
|
@@ -420,7 +419,7 @@ def open_full_xls(file_path: str, sample_name: str = ''):
|
|
|
420
419
|
try:
|
|
421
420
|
res = xls.open_xls(file_path)
|
|
422
421
|
except (Exception, BaseException) as e:
|
|
423
|
-
|
|
422
|
+
raise
|
|
424
423
|
start_row = 5
|
|
425
424
|
rows_num = len(res['Sample Parameters']) - 5
|
|
426
425
|
|
|
@@ -583,8 +582,6 @@ class ArArCalcFile:
|
|
|
583
582
|
|
|
584
583
|
def open(self):
|
|
585
584
|
book_contents = read_calc_file(self.file_path)
|
|
586
|
-
if not book_contents:
|
|
587
|
-
raise ValueError('Fail to open the file')
|
|
588
585
|
# create data frames for book values
|
|
589
586
|
content = pd.DataFrame(book_contents['Data Tables'])
|
|
590
587
|
logs01 = pd.DataFrame(book_contents['Logs01'])
|
|
@@ -274,7 +274,7 @@ def get_raw_data(file_contents: List[List[Union[int, float, str, bool, list]]],
|
|
|
274
274
|
raise ValueError(f"Step name not found")
|
|
275
275
|
except (TypeError, ValueError, IndexError):
|
|
276
276
|
# When parsing the step name fails, the end of the file has been reached
|
|
277
|
-
|
|
277
|
+
raise
|
|
278
278
|
|
|
279
279
|
# other information
|
|
280
280
|
options = get_sample_info(file_contents, optional_info_index, default="", base=[1, 1 - idx, 1])
|
|
@@ -20,8 +20,7 @@ def open_xls(filepath: str):
|
|
|
20
20
|
sheet = wb.sheet_by_name(sheet_name)
|
|
21
21
|
res[sheet_name] = [[sheet.cell(row, col).value for col in range(sheet.ncols)] for row in range(sheet.nrows)]
|
|
22
22
|
except biffh.XLRDError as e:
|
|
23
|
-
|
|
24
|
-
return e
|
|
23
|
+
raise
|
|
25
24
|
else:
|
|
26
25
|
return res
|
|
27
26
|
|
|
@@ -477,7 +477,7 @@ def get_diff_smp(backup: (dict, Sample), smp: (dict, Sample)):
|
|
|
477
477
|
# =======================
|
|
478
478
|
# Set parameters
|
|
479
479
|
# =======================
|
|
480
|
-
def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None):
|
|
480
|
+
def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None, rows: Optional[List] =None):
|
|
481
481
|
"""
|
|
482
482
|
Parameters
|
|
483
483
|
----------
|
|
@@ -485,84 +485,76 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
485
485
|
params
|
|
486
486
|
flag : optional, should be one of 'calc', 'irra', and 'smp'. If it is not given,
|
|
487
487
|
the text of the extension without a dot will be used
|
|
488
|
+
rows
|
|
488
489
|
|
|
489
490
|
Returns
|
|
490
491
|
-------
|
|
491
492
|
|
|
492
493
|
"""
|
|
494
|
+
if rows is None:
|
|
495
|
+
rows = []
|
|
496
|
+
rows = list(set(rows))
|
|
497
|
+
|
|
493
498
|
if isinstance(params, str) and os.path.isfile(params):
|
|
494
499
|
if flag is None:
|
|
495
500
|
flag = params.split(".")[-1]
|
|
496
501
|
return set_params(smp, read_params(params), flag=flag)
|
|
497
502
|
|
|
498
|
-
def
|
|
499
|
-
|
|
503
|
+
def isValid(item):
|
|
504
|
+
valid = True
|
|
505
|
+
if isinstance(item, (float, int)):
|
|
506
|
+
valid = not np.isnan(item)
|
|
507
|
+
return valid and item is not None and item != ""
|
|
508
|
+
|
|
509
|
+
def remove_none(old_params, new_params, row_list, length):
|
|
510
|
+
res = [[old_params[i][j] if j < len(old_params[i]) else None for j in range(max(len(old_params[i]), length))] for i in range(len(old_params))]
|
|
500
511
|
for index, item in enumerate(new_params):
|
|
501
|
-
if item
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
res[index] = [item] * rows
|
|
512
|
+
if isValid(item):
|
|
513
|
+
for row in row_list:
|
|
514
|
+
res[index][row] = item
|
|
505
515
|
return res
|
|
506
516
|
|
|
507
517
|
n = len(smp.SequenceName)
|
|
508
|
-
|
|
509
518
|
if n == 0:
|
|
510
|
-
raise ValueError(f"The number of sample sequences is
|
|
519
|
+
raise ValueError(f"The number of sample sequences is zero")
|
|
511
520
|
|
|
512
521
|
if flag == 'calc':
|
|
513
|
-
smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22],
|
|
514
|
-
smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48],
|
|
522
|
+
smp.TotalParam[34:56] = remove_none(smp.TotalParam[34:56], params[0:22], rows, n)
|
|
523
|
+
smp.TotalParam[71:97] = remove_none(smp.TotalParam[71:97], params[22:48], rows, n)
|
|
515
524
|
elif flag == 'irra':
|
|
516
|
-
smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20],
|
|
517
|
-
smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22],
|
|
518
|
-
smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29],
|
|
519
|
-
# smp.TotalParam[26] = [params[26]] * n
|
|
525
|
+
smp.TotalParam[0:20] = remove_none(smp.TotalParam[0:20], params[0:20], rows, n)
|
|
526
|
+
smp.TotalParam[56:58] = remove_none(smp.TotalParam[56:58], params[20:22], rows, n) # Cl36/38 productivity
|
|
527
|
+
smp.TotalParam[20:27] = remove_none(smp.TotalParam[20:27], params[22:29], rows, n)
|
|
520
528
|
irradiation_time = []
|
|
521
529
|
duration = []
|
|
522
530
|
if None not in params[29:-3] and '' not in params[29:-3]:
|
|
523
531
|
for i in range(len(params[29:-3])):
|
|
524
532
|
if i % 2 == 0:
|
|
525
|
-
# [d, t] = params[29:-3][i].split('T')
|
|
526
|
-
# [t1, t2] = t.split(':')
|
|
527
|
-
# irradiation_time.append(d + '-' + t1 + '-' + t2 + 'D' + str(params[29:-3][i + 1]))
|
|
528
|
-
text = params[29:-3][i]
|
|
529
|
-
for char in ['T', ':']:
|
|
530
|
-
text = text.replace(char, '-')
|
|
531
533
|
irradiation_time.append(params[29:-3][i] + 'D' + str(params[29:-3][i + 1]))
|
|
532
534
|
duration.append(float(params[29:-3][i + 1]))
|
|
533
|
-
smp.TotalParam[27] = ['S'.join(irradiation_time)]
|
|
534
|
-
smp.TotalParam[28] = [params[-3]] * n
|
|
535
|
-
smp.TotalParam[29] = [sum(duration)] * n
|
|
535
|
+
smp.TotalParam[27:30] = remove_none(smp.TotalParam[27:30], ['S'.join(irradiation_time), params[-3], sum(duration)], rows, n)
|
|
536
536
|
if params[-5] != '':
|
|
537
|
-
|
|
538
|
-
# [b, c] = b.split(':')
|
|
539
|
-
# smp.TotalParam[30] = [a + '-' + b + '-' + c] * n
|
|
540
|
-
text = params[-5]
|
|
541
|
-
for char in ['T', ':']:
|
|
542
|
-
text = text.replace(char, '-')
|
|
543
|
-
# smp.TotalParam[30] = [text] * n
|
|
544
|
-
smp.TotalParam[30] = [params[-5]] * n
|
|
537
|
+
smp.TotalParam[30:32] = remove_none(smp.TotalParam[30:32], [params[-5], None], rows, n)
|
|
545
538
|
try:
|
|
546
539
|
stand_time_second = [
|
|
547
540
|
calc.basic.get_datetime(*re.findall(r"\d+", smp.TotalParam[31][i])) - calc.basic.get_datetime(
|
|
548
|
-
*re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(
|
|
541
|
+
*re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(len(smp.TotalParam[30]))]
|
|
549
542
|
except (BaseException, Exception):
|
|
550
543
|
print(f'Error in calculate standing duration: {traceback.format_exc()}')
|
|
551
|
-
|
|
544
|
+
smp.TotalParam[32] = [None for index in range(n)]
|
|
552
545
|
else:
|
|
553
|
-
smp.TotalParam[32] = [
|
|
546
|
+
smp.TotalParam[32] = [item / (3600 * 24 * 365.242) if index in rows else smp.TotalParam[32][index] for index, item in enumerate(stand_time_second)] # stand year
|
|
554
547
|
|
|
555
548
|
elif flag == 'smp':
|
|
556
|
-
|
|
557
|
-
smp.TotalParam[67
|
|
558
|
-
smp.TotalParam[
|
|
559
|
-
smp.TotalParam[
|
|
560
|
-
smp.TotalParam[
|
|
561
|
-
smp.TotalParam[
|
|
562
|
-
# smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], n, 123 - 120)
|
|
549
|
+
smp.TotalParam[67:71] = remove_none(smp.TotalParam[67:71], params[0:4], rows, n)
|
|
550
|
+
smp.TotalParam[58:67] = remove_none(smp.TotalParam[58:67], params[4:13], rows, n)
|
|
551
|
+
smp.TotalParam[97:100] = remove_none(smp.TotalParam[97:100], params[13:16], rows, n)
|
|
552
|
+
smp.TotalParam[115:120] = remove_none(smp.TotalParam[115:120], params[16:21], rows, n)
|
|
553
|
+
smp.TotalParam[126:136] = remove_none(smp.TotalParam[126:136], params[21:31], rows, n)
|
|
554
|
+
# smp.TotalParam[120:123] = remove_none(smp.TotalParam[120:123], params[31:34], rows, n)
|
|
563
555
|
smp.TotalParam[100:114] = remove_none(
|
|
564
556
|
smp.TotalParam[100:114],
|
|
565
|
-
[['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]],
|
|
557
|
+
[['Linear', 'Exponential', 'Power'][params[35:38].index(True)] if True in params[35:38] else '', *params[38:]], rows, n)
|
|
566
558
|
pref = dict(zip(preference_keys, params[31:35]))
|
|
567
559
|
smp.Info.preference.update(pref)
|
|
568
560
|
for key, comp in get_components(smp).items():
|
|
@@ -570,7 +562,6 @@ def set_params(smp: Sample, params: Union[List, str], flag: Optional[str] = None
|
|
|
570
562
|
comp.decimal_places = pref['decimalPlaces']
|
|
571
563
|
comp.set_coltypes()
|
|
572
564
|
smp.AgeSpectraPlot.yaxis.title.text = f"Apparent Age ({str(pref['ageUnit']).capitalize()})"
|
|
573
|
-
print(smp.Info.preference)
|
|
574
565
|
|
|
575
566
|
else:
|
|
576
567
|
raise KeyError(f"{flag = } is not supported. It must be 'calc' for Calc Params, "
|
|
@@ -349,7 +349,7 @@ def calc_degas_r(sample: Sample):
|
|
|
349
349
|
"""
|
|
350
350
|
ar40ar = calc.arr.sub(sample.CorrectedValues[8:10], sample.DegasValues[30:32])
|
|
351
351
|
ar40r = calc.arr.sub(ar40ar, sample.DegasValues[26:28])
|
|
352
|
-
ar40r[0] = [
|
|
352
|
+
ar40r[0] = [0 if item < 0 and sample.TotalParam[101][index] else item for index, item in enumerate(ar40r[0])]
|
|
353
353
|
sample.DegasValues[24:26] = copy.deepcopy(ar40r)
|
|
354
354
|
sample.PublishValues[4] = copy.deepcopy(ar40r[0])
|
|
355
355
|
|
|
@@ -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}],
|
|
@@ -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']
|
|
@@ -265,10 +268,10 @@ def initial_plot_styles(sample: Sample, except_attrs=None):
|
|
|
265
268
|
set_attr(plot, key, attr)
|
|
266
269
|
|
|
267
270
|
|
|
268
|
-
def re_set_smp(
|
|
271
|
+
def re_set_smp(smp: Sample):
|
|
269
272
|
std = initial(Sample())
|
|
270
|
-
basic.get_merged_smp(
|
|
271
|
-
return
|
|
273
|
+
basic.get_merged_smp(smp, std)
|
|
274
|
+
return check_version(smp)
|
|
272
275
|
|
|
273
276
|
|
|
274
277
|
def check_version(smp: Sample):
|
|
@@ -283,7 +286,11 @@ def check_version(smp: Sample):
|
|
|
283
286
|
|
|
284
287
|
"""
|
|
285
288
|
if smp.version != samples.VERSION:
|
|
286
|
-
|
|
289
|
+
std = initial(Sample())
|
|
290
|
+
basic.get_merged_smp(smp, std)
|
|
291
|
+
# if int(smp.version) <= 20250328: # Experiment info
|
|
292
|
+
smp.Info.experiment.name = smp.name()
|
|
293
|
+
smp.Info.experiment.step_num = smp.sequence().size
|
|
287
294
|
return smp
|
|
288
295
|
|
|
289
296
|
|
|
@@ -329,11 +336,8 @@ def from_arr_files(file_path, sample_name: str = ""):
|
|
|
329
336
|
def renamed_load(file_obj):
|
|
330
337
|
return RenameUnpickler(file_obj).load()
|
|
331
338
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
sample = renamed_load(f)
|
|
335
|
-
except (Exception, BaseException):
|
|
336
|
-
raise ValueError(f"Fail to open arr file: {file_path}")
|
|
339
|
+
with open(file_path, 'rb') as f:
|
|
340
|
+
sample = renamed_load(f)
|
|
337
341
|
# Check arr version
|
|
338
342
|
# recalculation will not be applied automatically
|
|
339
343
|
return check_version(sample)
|
|
@@ -353,7 +357,7 @@ def from_calc_files(file_path: str, **kwargs):
|
|
|
353
357
|
"""
|
|
354
358
|
file = calc_file.ArArCalcFile(file_path=file_path, **kwargs).open()
|
|
355
359
|
sample = create_sample_from_df(file.get_content(), file.get_smp_info())
|
|
356
|
-
return sample
|
|
360
|
+
return check_version(sample)
|
|
357
361
|
|
|
358
362
|
|
|
359
363
|
# create
|
|
@@ -372,7 +376,7 @@ def from_full_files(file_path: str, sample_name: str = None):
|
|
|
372
376
|
sample_name = str(os.path.split(file_path)[-1]).split('.')[0]
|
|
373
377
|
content, sample_info = calc_file.open_full_xls(file_path, sample_name)
|
|
374
378
|
sample = create_sample_from_dict(content=content, smp_info=sample_info)
|
|
375
|
-
return sample
|
|
379
|
+
return check_version(sample)
|
|
376
380
|
|
|
377
381
|
|
|
378
382
|
# create
|
|
@@ -450,4 +454,4 @@ def from_raw_data(raw: RawData, mapping: Optional[List[dict]] = None) -> Sample:
|
|
|
450
454
|
|
|
451
455
|
# sample.TotalParam[31] = [raw.get_sequence(row['unknown'], flag='name').datetime for row in mapping]
|
|
452
456
|
|
|
453
|
-
return sample
|
|
457
|
+
return check_version(sample)
|
|
@@ -743,7 +743,7 @@ DEFAULT_PLOT_STYLES = {
|
|
|
743
743
|
},
|
|
744
744
|
}
|
|
745
745
|
|
|
746
|
-
VERSION = '
|
|
746
|
+
VERSION = '20250328'
|
|
747
747
|
|
|
748
748
|
NAMED_DICT = {
|
|
749
749
|
"unknown": {"header": SAMPLE_INTERCEPT_HEADERS.copy()},
|
|
@@ -847,8 +847,9 @@ class Sample:
|
|
|
847
847
|
# self.__version = '20240730' # change parameter table for thermo calculation
|
|
848
848
|
# self.__version = '20241028' # gain correction
|
|
849
849
|
# self.__version = '20250102' # gain correction to blanks
|
|
850
|
+
# self.__version = '20250301' # update sample info
|
|
850
851
|
# self.__version = '20250321' # error sigma adjustment
|
|
851
|
-
self.__version = '
|
|
852
|
+
self.__version = '20250328' # Experiment info
|
|
852
853
|
|
|
853
854
|
@property
|
|
854
855
|
def version(self):
|
|
@@ -930,7 +931,7 @@ class Sample:
|
|
|
930
931
|
|
|
931
932
|
def show_data(self): ...
|
|
932
933
|
|
|
933
|
-
def set_params(self, params: Union[List, str], flag: Optional[str] = None): ...
|
|
934
|
+
def set_params(self, params: Union[List, str], flag: Optional[str] = None, rows: Optional[List] = None): ...
|
|
934
935
|
|
|
935
936
|
def set_info(self, info: dict): ...
|
|
936
937
|
|
|
@@ -938,6 +939,8 @@ class Sample:
|
|
|
938
939
|
|
|
939
940
|
def to_pdf(self, file_path: str, figure: str = "figure_3"): ...
|
|
940
941
|
|
|
942
|
+
def to_excel(self, file_path: str, *args, **kwargs): ...
|
|
943
|
+
|
|
941
944
|
|
|
942
945
|
class Table:
|
|
943
946
|
def __init__(self, id='', name='Table', colcount=None, rowcount=None, header=None,
|
|
@@ -16,7 +16,7 @@ long_description = (here / 'README.md').read_text(encoding='utf-8')
|
|
|
16
16
|
|
|
17
17
|
setuptools.setup(
|
|
18
18
|
name='ararpy', #
|
|
19
|
-
version='0.1.
|
|
19
|
+
version='0.1.195', # version
|
|
20
20
|
author='Yang Wu',
|
|
21
21
|
author_email='wuycug@hotmail.com',
|
|
22
22
|
description='A project for Ar-Ar geochronology', # short description
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|