ararpy 0.1.198__py3-none-any.whl → 0.2.1__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.
Files changed (41) hide show
  1. ararpy/Example - Check arr.py +52 -0
  2. ararpy/Example - Granite Cooling History.py +411 -0
  3. ararpy/Example - Plot temperature calibration.py +291 -0
  4. ararpy/Example - Show MDD results.py +561 -0
  5. ararpy/Example - Show all Kfs age spectra.py +344 -0
  6. ararpy/Example - Show random walk results.py +363 -0
  7. ararpy/Example - Tc calculation.py +437 -0
  8. ararpy/__init__.py +3 -4
  9. ararpy/calc/age.py +34 -36
  10. ararpy/calc/arr.py +5 -24
  11. ararpy/calc/basic.py +26 -3
  12. ararpy/calc/corr.py +135 -89
  13. ararpy/calc/jvalue.py +1 -1
  14. ararpy/calc/plot.py +6 -4
  15. ararpy/calc/raw_funcs.py +41 -2
  16. ararpy/calc/regression.py +224 -132
  17. ararpy/files/arr_file.py +2 -1
  18. ararpy/files/basic.py +0 -22
  19. ararpy/files/calc_file.py +107 -84
  20. ararpy/files/raw_file.py +242 -229
  21. ararpy/smp/basic.py +202 -46
  22. ararpy/smp/calculation.py +6 -6
  23. ararpy/smp/corr.py +339 -154
  24. ararpy/smp/diffusion_funcs.py +345 -36
  25. ararpy/smp/export.py +247 -129
  26. ararpy/smp/info.py +2 -2
  27. ararpy/smp/initial.py +105 -48
  28. ararpy/smp/json.py +2 -2
  29. ararpy/smp/plots.py +225 -218
  30. ararpy/smp/raw.py +11 -15
  31. ararpy/smp/sample.py +257 -183
  32. ararpy/smp/style.py +48 -22
  33. ararpy/smp/table.py +42 -33
  34. ararpy/thermo/atomic_level_random_walk.py +56 -48
  35. ararpy/thermo/basic.py +2 -2
  36. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/METADATA +1 -1
  37. ararpy-0.2.1.dist-info/RECORD +73 -0
  38. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/WHEEL +1 -1
  39. ararpy-0.1.198.dist-info/RECORD +0 -66
  40. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/licenses/LICENSE +0 -0
  41. {ararpy-0.1.198.dist-info → ararpy-0.2.1.dist-info}/top_level.txt +0 -0
ararpy/smp/info.py CHANGED
@@ -15,9 +15,9 @@
15
15
 
16
16
  def name(smp, n: str = None):
17
17
  if n is None:
18
- return smp.Info.sample.name
18
+ return smp.Info.experiment.name
19
19
  elif isinstance(n, str):
20
- smp.Info.sample.name = n
20
+ smp.Info.experiment.name = n
21
21
  return n
22
22
  else:
23
23
  raise ValueError(f"{n} is not a string")
ararpy/smp/initial.py CHANGED
@@ -10,13 +10,14 @@
10
10
  #
11
11
  """
12
12
  import os
13
+ import re
13
14
  import pickle
14
15
  import uuid
15
16
  import pandas as pd
16
17
  import numpy as np
17
18
  import copy
18
19
  from typing import List, Union, Optional
19
- from ..calc import arr, err
20
+ from ..calc import arr, err, basic as calc_basic
20
21
  from ..files import calc_file
21
22
  from . import (sample as samples, basic, table, raw as smp_raw)
22
23
 
@@ -50,7 +51,7 @@ SPECTRA_RES = dict(zip(
50
51
  spectra_res_keys, [np.nan for i in spectra_res_keys])
51
52
  )
52
53
  preference_keys = [
53
- 'decimalPlaces', 'toPrecision', 'confidenceLevel', 'ageUnit'
54
+ 'decimal_places', 'to_precision', 'confidence_level', 'age_unit'
54
55
  ]
55
56
  PREFERENCE_RES = dict(zip(
56
57
  preference_keys, [6, 'fixed', 1, 'Ma'])
@@ -123,14 +124,14 @@ def create_sample_from_dict(content: dict, smp_info: dict):
123
124
 
124
125
  def initial(smp: Sample):
125
126
  # 已更新 2023/7/4
126
- smp.TotalParam = arr.create_arr((len(samples.TOTAL_PARAMS_HEADERS) - 2, 0))
127
- smp.BlankIntercept = arr.create_arr((len(samples.BLANK_INTERCEPT_HEADERS) - 2, 0))
128
- smp.SampleIntercept = arr.create_arr((len(samples.SAMPLE_INTERCEPT_HEADERS) - 2, 0))
129
- smp.PublishValues = arr.create_arr((len(samples.PUBLISH_TABLE_HEADERS) - 2, 0))
127
+ smp.TotalParam = arr.create_arr((len(samples.TOTAL_PARAMS_HEADERS) - 3, 0))
128
+ smp.BlankIntercept = arr.create_arr((len(samples.BLANK_INTERCEPT_HEADERS) - 3, 0))
129
+ smp.SampleIntercept = arr.create_arr((len(samples.SAMPLE_INTERCEPT_HEADERS) - 3, 0))
130
+ smp.PublishValues = arr.create_arr((len(samples.PUBLISH_TABLE_HEADERS) - 3, 0))
130
131
  smp.DecayCorrected = arr.create_arr((10, 0))
131
- smp.CorrectedValues = arr.create_arr((len(samples.CORRECTED_HEADERS) - 2, 0))
132
- smp.DegasValues = arr.create_arr((len(samples.DEGAS_HEADERS) - 2, 0))
133
- smp.ApparentAgeValues = arr.create_arr((len(samples.SPECTRUM_TABLE_HEADERS) - 2, 0))
132
+ smp.CorrectedValues = arr.create_arr((len(samples.CORRECTED_HEADERS) - 3, 0))
133
+ smp.DegasValues = arr.create_arr((len(samples.DEGAS_HEADERS) - 3, 0))
134
+ smp.ApparentAgeValues = arr.create_arr((len(samples.SPECTRUM_TABLE_HEADERS) - 3, 0))
134
135
  smp.IsochronValues = arr.create_arr((len(samples.ISOCHRON_TABLE_HEADERS) - 3, 0))
135
136
 
136
137
  # Doi
@@ -140,15 +141,18 @@ def initial(smp: Sample):
140
141
  # Info
141
142
  setattr(smp, 'Info', ArArBasic(
142
143
  id='0', name='info', attr_name='Info', arr_version=samples.VERSION,
144
+ experiment=ArArBasic(
145
+ name='', type='', instrument='', mass_spec='', collectors='', step_num=0,
146
+ ),
143
147
  sample=ArArBasic(
144
148
  name='SAMPLE NAME', material='MATERIAL', location='LOCATION', type='Unknown', method='',
145
- sequence_unit='', weight=''
149
+ sequence_unit='', weight='',
146
150
  ),
147
151
  researcher=ArArBasic(
148
- name='RESEARCHER', addr='ADDRESS', email='EMAIL'
152
+ name='RESEARCHER', addr='ADDRESS', email='EMAIL',
149
153
  ),
150
154
  laboratory=ArArBasic(
151
- name='LABORATORY', addr='ADDRESS', email='EMAIL', info='INFORMATION', analyst='ANALYST'
155
+ name='LABORATORY', addr='ADDRESS', email='EMAIL', info='INFORMATION', analyst='ANALYST',
152
156
  ),
153
157
  results=ArArBasic(
154
158
  name='RESULTS', plateau_F=[], plateau_age=[], total_F=[], total_age=[],
@@ -183,42 +187,42 @@ def initial(smp: Sample):
183
187
  reference=ArArBasic(
184
188
  name='REFERENCE', journal='JOURNAL', doi='DOI'
185
189
  ),
186
- preference=copy.deepcopy(PREFERENCE_RES),
187
- experiment=ArArBasic(
188
- name='', mass_spec='', collectors='', step_num=0
189
- ),
190
+ preference=ArArBasic(**PREFERENCE_RES),
191
+ irradiation= ArArBasic(
192
+ label='', pos_h='', pos_x='', pos_y='',
193
+ )
190
194
  ))
191
195
 
192
- decimal_places = PREFERENCE_RES['decimalPlaces']
196
+ decimal_places = smp.Info.preference.decimal_places
193
197
  # Plots and Tables
194
198
  setattr(smp, 'UnknownTable', Table(
195
199
  id='1', name='Unknown', header=samples.SAMPLE_INTERCEPT_HEADERS, decimal_places=decimal_places,
196
- text_indexes=[0, 1],
200
+ text_indexes=[0, 1, 2],
197
201
  # numeric_indexes=list(range(1, 20))
198
202
  ))
199
203
  setattr(smp, 'BlankTable', Table(
200
204
  id='2', name='Blank', header=samples.BLANK_INTERCEPT_HEADERS, decimal_places=decimal_places,
201
- text_indexes=[0, 1],
205
+ text_indexes=[0, 1, 2],
202
206
  # numeric_indexes=list(range(1, 20))
203
207
  ))
204
208
  setattr(smp, 'CorrectedTable', Table(
205
209
  id='3', name='Corrected', header=samples.CORRECTED_HEADERS, decimal_places=decimal_places,
206
- text_indexes=[0, 1],
210
+ text_indexes=[0, 1, 2],
207
211
  # numeric_indexes=list(range(1, 35))
208
212
  ))
209
213
  setattr(smp, 'DegasPatternTable', Table(
210
214
  id='4', name='Degas Pattern', header=samples.DEGAS_HEADERS, decimal_places=decimal_places,
211
- text_indexes=[0, 1],
215
+ text_indexes=[0, 1, 2],
212
216
  # numeric_indexes=list(range(1, 35))
213
217
  ))
214
218
  setattr(smp, 'PublishTable', Table(
215
219
  id='5', name='Publish', header=samples.PUBLISH_TABLE_HEADERS, decimal_places=decimal_places,
216
- text_indexes=[0, 1],
220
+ text_indexes=[0, 1, 2],
217
221
  # numeric_indexes=list(range(1, 20))
218
222
  ))
219
223
  setattr(smp, 'AgeSpectraTable', Table(
220
224
  id='6', name='Age Spectra', header=samples.SPECTRUM_TABLE_HEADERS, decimal_places=decimal_places,
221
- text_indexes=[0, 1],
225
+ text_indexes=[0, 1, 2],
222
226
  # numeric_indexes=list(range(1, 26))
223
227
  ))
224
228
  setattr(smp, 'IsochronsTable', Table(
@@ -228,7 +232,7 @@ def initial(smp: Sample):
228
232
  ))
229
233
  setattr(smp, 'TotalParamsTable', Table(
230
234
  id='8', name='Total Params', header=samples.TOTAL_PARAMS_HEADERS, decimal_places=decimal_places,
231
- text_indexes=[0, 1, 29, 30, 32, 33, 60, 99, *list(range(100, 115))],
235
+ text_indexes=[0, 1, 2, 30, 31, 33, 34, 61, 100, 103, *list(range(104, 118))],
232
236
  # numeric_indexes=list(range(1, 120)),
233
237
  ))
234
238
 
@@ -237,7 +241,7 @@ def initial(smp: Sample):
237
241
  return smp
238
242
 
239
243
 
240
- def initial_plot_styles(sample: Sample, except_attrs=None):
244
+ def initial_plot_styles(smp: Sample, except_attrs=None):
241
245
  """
242
246
  Initialize plot components styles based on Default Styles. Except attrs is a list containing attrs
243
247
  that are not expected to be initialized.
@@ -261,13 +265,22 @@ def initial_plot_styles(sample: Sample, except_attrs=None):
261
265
  for k, v in value.items():
262
266
  set_attr(getattr(obj, name), k, v)
263
267
 
264
- default_styles = copy.deepcopy(samples.DEFAULT_PLOT_STYLES)
268
+ default_styles = get_default_plot_style(smp)
265
269
  for figure_index, figure_attr in default_styles.items():
266
- plot = getattr(sample, figure_attr['attr_name'], Plot())
270
+ plot = getattr(smp, figure_attr['attr_name'], Plot())
267
271
  for key, attr in figure_attr.items():
268
272
  set_attr(plot, key, attr)
269
273
 
270
274
 
275
+ def get_default_plot_style(smp: Sample):
276
+ sample_type = smp.Info.sample.type
277
+ try:
278
+ age_unit = str(smp.Info.preference['ageUnit']).capitalize()
279
+ except:
280
+ age_unit = "Undefined"
281
+ return copy.deepcopy(samples.DEFAULT_PLOT_STYLES(sample_type, age_unit))
282
+
283
+
271
284
  def re_set_smp(smp: Sample):
272
285
  std = initial(Sample())
273
286
  basic.get_merged_smp(smp, std)
@@ -289,25 +302,65 @@ def check_version(smp: Sample):
289
302
  std = initial(Sample())
290
303
  basic.get_merged_smp(smp, std)
291
304
 
305
+ try:
306
+ version = int(smp.version)
307
+ except ValueError:
308
+ return smp
309
+
292
310
  # 20250328: # Experiment info
293
311
  smp.Info.experiment.name = smp.name()
294
312
  smp.Info.experiment.step_num = smp.sequence().size
295
313
 
296
- # 20250404
297
- doNormalize = True
298
- v, sv = [], []
299
- if smp.Info.sample.type.lower() == "unknown":
300
- v, sv = smp.TotalParam[67:69]
301
- sv = np.multiply(v, sv) / 100
302
- elif smp.Info.sample.type.lower() == "air":
303
- v, sv = smp.TotalParam[93:95]
304
- sv = np.multiply(v, sv) / 100
305
- elif smp.Info.sample.type.lower() == "standard":
306
- v, sv = smp.TotalParam[59:61]
307
- smp.NormalizeFactor = [
308
- [1 if v[0] == each or not doNormalize else v[0] / each for each in v],
309
- [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))]
310
- ]
314
+ # old version: add masses and gain factors
315
+ if version < 20240730:
316
+ gains = np.ones([10, smp.Info.experiment.step_num])
317
+ gains[[1, 3, 5, 7, 9], :] = 0
318
+ smp.TotalParam[126:136] = gains.tolist()
319
+ gains[0] = 35.96754628
320
+ gains[2] = 36.9667759
321
+ gains[4] = 37.9627322
322
+ gains[6] = 38.964313
323
+ gains[8] = 39.962383123
324
+ smp.TotalParam[71:81] = gains.tolist()
325
+ smp.version = "20240730"
326
+
327
+ # 20250404: # Normalization for steps with different J values
328
+ # always check
329
+ if version < 1120250405:
330
+ doNormalize = True
331
+ v, sv = [], []
332
+ try:
333
+ if smp.Info.sample.type.lower() == "unknown":
334
+ v, sv = smp.TotalParam[67:69]
335
+ sv = np.multiply(v, sv) / 100
336
+ elif smp.Info.sample.type.lower() == "air":
337
+ v, sv = smp.TotalParam[93:95]
338
+ sv = np.multiply(v, sv) / 100
339
+ elif smp.Info.sample.type.lower() == "standard":
340
+ v, sv = smp.TotalParam[59:61]
341
+ except:
342
+ doNormalize = False
343
+ smp.TotalParam[136:138] = [
344
+ [1 if v[0] == each or not doNormalize else v[0] / each for each in v],
345
+ [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))]
346
+ ]
347
+ # smp.version = "20250405"
348
+
349
+ # 20251001: # add marks for every table
350
+ if version < 20251002:
351
+ try:
352
+ stand_time_second = [
353
+ calc_basic.get_datetime(*re.findall(r"\d+", smp.TotalParam[31][i])) - calc_basic.get_datetime(
354
+ *re.findall(r"\d+", smp.TotalParam[30][i])) for i in range(smp.Info.experiment.step_num)]
355
+ except (BaseException, Exception) as e:
356
+ print(f"{type(e).__name__}: {str(e)}")
357
+ smp.TotalParam[32] = [np.nan for index in range(smp.Info.experiment.step_num)]
358
+ else:
359
+ smp.TotalParam[32] = [item / (3600 * 24 * 365.242) for item in stand_time_second] # stand year
360
+ smp = smp.recalculate(re_table_style=True)
361
+ smp = smp.recalculate(re_set_table=True)
362
+ smp.version = "20251001"
363
+
311
364
  return smp
312
365
 
313
366
 
@@ -439,14 +492,14 @@ def from_raw_data(raw: RawData, mapping: Optional[List[dict]] = None) -> Sample:
439
492
  for row in mapping:
440
493
  row_unknown_intercept = []
441
494
  row_blank_intercept = []
442
-
443
495
  unknown: Sequence = raw.get_sequence(row['unknown'], flag='name')
444
- if row['blank'].lower() == "Interpolated Blank".lower():
496
+ try:
497
+ blank: Sequence = raw.get_sequence(row['blank'], flag='name')
498
+ if blank is None or blank == []: raise KeyError
499
+ except KeyError:
445
500
  blank: Sequence = arr.filter(
446
- raw.interpolated_blank, func=lambda seq: seq.datetime == unknown.datetime,
501
+ raw.interpolated_blank, func=lambda seq: seq.datetime == unknown.datetime and seq.name == row['blank'],
447
502
  get=None, unique=True)
448
- else:
449
- blank: Sequence = raw.get_sequence(row['blank'], flag='name')
450
503
  for i in range(5):
451
504
  row_unknown_intercept = arr.multi_append(row_unknown_intercept, *unknown.results[i][int(unknown.fitting_method[i])][:2])
452
505
  row_blank_intercept = arr.multi_append(row_blank_intercept, *blank.results[i][int(blank.fitting_method[i])][:2])
@@ -462,12 +515,16 @@ def from_raw_data(raw: RawData, mapping: Optional[List[dict]] = None) -> Sample:
462
515
  sample.UnselectedSequence = list(range(len(sample.SequenceName)))
463
516
  sample.SelectedSequence1 = []
464
517
  sample.SelectedSequence2 = []
518
+ sample.IsochronMark = ['' for i in range(len(sample.SequenceName))]
465
519
  #
466
520
  sample.Info.results.selection[0]['data'] = sample.SelectedSequence1
467
521
  sample.Info.results.selection[1]['data'] = sample.SelectedSequence2
468
522
  sample.Info.results.selection[2]['data'] = sample.UnselectedSequence
523
+ sample.Info.experiment.step_num = len(sample.SequenceName)
524
+
525
+ sample.recalculate(re_initial=True)
469
526
 
470
- table.update_table_data(sample) # Update table after submission row data and calculation
527
+ # table.update_table_data(sample) # Update table after submission row data and calculation
471
528
 
472
529
  # sample.TotalParam[31] = [raw.get_sequence(row['unknown'], flag='name').datetime for row in mapping]
473
530
 
ararpy/smp/json.py CHANGED
@@ -50,8 +50,8 @@ class MyEncoder(json.JSONEncoder):
50
50
  Plot.Set, Plot.BasicAttr, RawData, Sequence, ArArBasic)):
51
51
  if isinstance(obj, Sequence):
52
52
  return dict(obj.__dict__, **{
53
- 'is_blank': obj.is_blank(), 'is_unknown': obj.is_unknown(),
54
- 'is_air': obj.is_air()})
53
+ 'is_blank': obj.is_blank(), 'is_unknown': obj.is_unknown()
54
+ })
55
55
  return obj.__dict__
56
56
  # Error
57
57
  if isinstance(obj, BaseException):