ararpy 0.0.24__py3-none-any.whl → 0.1.11__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.
@@ -0,0 +1,4745 @@
1
+ # Copyright (C) 2024 Yang. - All Rights Reserved
2
+
3
+ # !/usr/bin/env python
4
+ # -*- coding: UTF-8 -*-
5
+ """
6
+ # ==========================================
7
+ # Copyright 2024 Yang
8
+ # ararpy - diffusion_funcs
9
+ # ==========================================
10
+ #
11
+ #
12
+ #
13
+ """
14
+
15
+ import os
16
+ import shutil
17
+ import string
18
+
19
+ import numpy as np
20
+ from .sample import Sample
21
+ import ararpy as ap
22
+ import matplotlib as mpl
23
+ import scipy.stats as stats
24
+ import math
25
+ from scipy.special import comb
26
+ from datetime import datetime as dt
27
+ import re
28
+ import time
29
+ import ctypes
30
+ import gc
31
+ import random
32
+
33
+ mpl.use('TkAgg')
34
+ import matplotlib.pyplot as plt
35
+
36
+ np.set_printoptions(precision=18, threshold=10000, linewidth=np.inf)
37
+
38
+
39
+ def is_number(s):
40
+ try:
41
+ float(s)
42
+ return True
43
+ except ValueError:
44
+ return False
45
+
46
+
47
+ class DiffSample:
48
+ def __init__(self, smp: Sample = None, name: str = None, **kwargs):
49
+
50
+ self.loc = "D:\\PythonProjects\\ararpy_package\\ararpy\\examples"
51
+
52
+ for key, val in kwargs.items():
53
+ setattr(self, key, val)
54
+
55
+ os.makedirs(self.loc, exist_ok=True)
56
+
57
+ if smp is not None:
58
+ self.smp = smp
59
+ self.sname = self.smp.name()
60
+
61
+ self.sequence = self.smp.sequence()
62
+ self.ni = self.sequence.size # sequence number
63
+
64
+ # self.telab = np.linspace(600, 1500, self.ni, dtype=np.float64)
65
+ self.telab = np.array(self.smp.TotalParam[124], dtype=np.float64)
66
+
67
+ self.telab = self.telab + 273.15
68
+ # self.tilab = np.array([15*60 for i in range(self.ni)], dtype=np.float64)
69
+ self.tilab = np.array(self.smp.TotalParam[123], dtype=np.float64) # in minute
70
+ self.a39 = np.array(self.smp.DegasValues[20], dtype=np.float64)
71
+ self.sig39 = np.array(self.smp.DegasValues[21], dtype=np.float64)
72
+ self.f = np.cumsum(self.a39) / self.a39.sum()
73
+ self.f = np.where(self.f >= 1, 0.9999999999999999, self.f)
74
+ # self.f[-1] = 0.999999999
75
+ # self.f = np.insert(self.f, 0, 0)
76
+ self.ya = np.array(self.smp.ApparentAgeValues[2], dtype=np.float64)
77
+ self.sig = np.array(self.smp.ApparentAgeValues[3], dtype=np.float64)
78
+
79
+ read_from_file = kwargs.get('read_from_file', False)
80
+ if read_from_file:
81
+ self.file_age_in = open(os.path.join(self.loc, f"{self.sname}_age.in"), "w")
82
+ self.file_sig_in = open(os.path.join(self.loc, f"{self.sname}_sig.in"), "w")
83
+ self.file_tmp_in = open(os.path.join(self.loc, f"{self.sname}_tmp.in"), "w")
84
+ self.file_fj_in = open(os.path.join(self.loc, f"{self.sname}_fj.in"), "w")
85
+ self.file_a39_in = open(os.path.join(self.loc, f"{self.sname}_a39.in"), "w")
86
+
87
+ self.file_age_in.writelines("\n".join([f" {self.f[i] * 100} {self.ya[i]}" for i in range(self.ni)]))
88
+ self.file_sig_in.writelines("\n".join([f"{self.sig[i]}" for i in range(self.ni)]))
89
+ self.file_tmp_in.writelines(f"{str(self.ni)}\n")
90
+ self.file_tmp_in.writelines("\n".join([f"{self.telab[i]}\n{self.tilab[i]}" for i in range(self.ni)]))
91
+ self.file_fj_in.writelines("\n".join([f"{self.f[i]}" for i in range(self.ni)]))
92
+ self.file_a39_in.writelines("\n".join([f" {self.a39[i]} {self.sig39[i]}" for i in range(self.ni)]))
93
+
94
+ self.file_age_in.close()
95
+ self.file_sig_in.close()
96
+ self.file_tmp_in.close()
97
+ self.file_fj_in.close()
98
+ self.file_a39_in.close()
99
+
100
+
101
+ elif name is not None:
102
+ self.sname = name
103
+ else:
104
+ raise ValueError("Sample not found")
105
+
106
+ self.pi = 3.141592654
107
+ self.nloop = 1
108
+ self.ngauss = 10
109
+ self.zi = [0.]
110
+ self.b = 8
111
+ self.imp = 2
112
+ self.acut = 0.5
113
+ self.dchmin = 0.01
114
+ self.ncons = 0
115
+ self.ndom = 8
116
+ self.mdom = 8
117
+ self.iset = 0
118
+ self.gset = 0
119
+ self.wt = []
120
+
121
+
122
+ class DiffArrmultiFunc(DiffSample):
123
+ def __init__(self, **kwargs):
124
+ super().__init__(**kwargs)
125
+
126
+ self.file_output_par = open(os.path.join(self.loc, f"{self.sname}.par"), "w")
127
+ self.file_output_ame = open(os.path.join(self.loc, f"{self.sname}.ame"), "w")
128
+ # self.file_output_mch = open(os.path.join(self.loc, f"{self.sname}_mch-out.dat"), "w")
129
+ # self.file_output_mages = open(os.path.join(self.loc, f"{self.sname}_mages-out.dat"), "w")
130
+ # self.file_output_agesd = open(os.path.join(self.loc, f"{self.sname}_ages-sd.samp"), "w")
131
+ # self.file_output_mchisq = open(os.path.join(self.loc, f"{self.sname}_mchisq.dat"), "w")
132
+ # self.file_output_mpar = open(os.path.join(self.loc, f"{self.sname}_mpar.out"), "w")
133
+
134
+ # self.file_tmp_in = open(os.path.join(self.loc, f"{self.sname}_tmp.in"), "r")
135
+ # self.file_fj_in = open(os.path.join(self.loc, f"{self.sname}_fj.in"), "r")
136
+ # self.file_a39_in = open(os.path.join(self.loc, f"{self.sname}_a39.in"), "r")
137
+
138
+ # self.ni = int(self.file_tmp_in.readline()) # sequence number
139
+ self.ni = 100
140
+ self.nimax = self.ni
141
+ self.telab = []
142
+ self.tilab = []
143
+ self.f = [0] # ar39%, array(ni)
144
+ self.a39 = [] # ar39, array(ni - 1)
145
+ self.sig39 = [] # sigma of ar39, array(ni - 1)
146
+
147
+ # for i in range(self.ni):
148
+ # self.telab.append(float(self.file_tmp_in.readline())) # heating temperature in Kelvin
149
+ # self.tilab.append(float(self.file_tmp_in.readline()) * 60) # heating time in second.
150
+ # self.f.append(float(self.file_fj_in.readline()))
151
+ # try:
152
+ # [_, v, sv] = self.file_a39_in.readline().split(' ')
153
+ # except ValueError:
154
+ # continue
155
+ # else:
156
+ # self.a39.append(float(v))
157
+ # self.sig39.append(float(sv))
158
+ #
159
+ # self.file_fj_in.close()
160
+ # self.file_tmp_in.close()
161
+ # self.file_a39_in.close()
162
+
163
+ print(f"{self.sname = }")
164
+ print(f"{self.a39 = }")
165
+ print(f"{self.sig39 = }")
166
+ print(f"{self.f = }")
167
+ print(f"{self.telab = }")
168
+ print(f"{self.tilab = }")
169
+
170
+ def main(self):
171
+
172
+ print(f"\n======================================")
173
+ print(f"Run Arrmulti Main | ")
174
+ print(f"======================================")
175
+
176
+ print(f"{self.sname = }")
177
+ print(f"{self.a39 = }")
178
+ print(f"{self.sig39 = }")
179
+ print(f"{self.f = }")
180
+ print(f"{self.telab = }")
181
+ print(f"{self.tilab = }")
182
+
183
+ output_lines = ""
184
+
185
+ self.ochisq = 0
186
+ mmax = 20
187
+ self.da = np.zeros(mmax, dtype=np.float64)
188
+ da = np.zeros(mmax, dtype=np.float64)
189
+ self.atry = np.zeros(mmax, dtype=np.float64)
190
+ self.beta = np.zeros(mmax, dtype=np.float64)
191
+
192
+ ns = 200
193
+ r = 1.987E-3
194
+ pi = 3.141592654
195
+ ee = 0.4342944879
196
+ amax = 0
197
+
198
+ xlogr = [0]
199
+ # dtr2 = [math.pi * (fi / 4) ** 2 if fi <= 0.5 else math.log((1 - fi) * math.pi ** 2 / 8) / (- math.pi ** 2) for
200
+ # fi in self.f[1:]]
201
+ # dtr2.insert(0, 0)
202
+ # xlogd = [np.log10((dtr2[i + 1] - dtr2[i]) / self.tilab[i] * self.imp ** 2) for i in range(0, len(dtr2) - 1)]
203
+ xlogd = self.xlogd
204
+ tinv = [1 / i * 10000 for i in self.telab]
205
+ self.nimax = self.ni # the first sequence index great than 1100 celsius degree
206
+ for i in range(self.ni):
207
+ if self.nimax == self.ni and self.telab[i] > 1373:
208
+ self.nimax = i
209
+
210
+ # wt = self.errcal()
211
+ wt = self.wt
212
+
213
+ wf = []
214
+ sumwf = 0
215
+ for i in range(self.ni):
216
+ wf.append(1 / np.sqrt(self.f[i + 1] - self.f[i]))
217
+ sumwf += wf[i]
218
+
219
+
220
+
221
+ for i in range(self.ni):
222
+ # print(f"{wf[i] = }")
223
+ wf[i] = wf[i] / sumwf
224
+
225
+ e, sige, ordi, sigo = self.param(tinv=tinv, wt=wt, xlogd=xlogd)
226
+
227
+ print(self.sname)
228
+ print(f'E={e} +- {sige} Ordinate={ordi} +- {sigo}')
229
+
230
+ self.file_output_par.writelines(f'{self.sname}\nE={e} +- {sige} Ordinate={ordi} +- {sigo}\n')
231
+
232
+ slop = e * ee / (r * 10000)
233
+ xro = (ordi - slop * tinv[self.nimax - 1] - xlogd[self.nimax - 1]) / 2 * (1 + (1 - self.f[self.nimax]) / 2)
234
+
235
+ e0 = e
236
+ ord0 = ordi
237
+ self.ni = self.nimax
238
+
239
+ ### here starts loop for gaussian E,
240
+
241
+ nca = 20
242
+ zi = [0]
243
+ ndom = 8
244
+ na = 2 * ndom - 1
245
+ a1 = np.zeros(na + 1, dtype=np.float64)
246
+ a2 = np.zeros(na + 1, dtype=np.float64)
247
+ auxal = np.zeros([na + 1, na + 1], dtype=np.float64)
248
+ auxa1 = np.zeros(na + 1, dtype=np.float64)
249
+ auxa2 = np.zeros(na + 1, dtype=np.float64)
250
+ iseed = -3
251
+ ckchisq = 1.0e30
252
+ ckchin = 1.0e30
253
+ dchmin = 0.01
254
+ mct = 0
255
+ ncicle = 0
256
+ chisq = 100000
257
+ kctotal = 0
258
+ alpha = np.zeros([nca, nca], dtype=np.float64)
259
+ alpha[:nca, :nca] = 0.0
260
+ covar = np.zeros([na, na], dtype=np.float64)
261
+ covar[:na, :na] = 0.0
262
+
263
+ zi = self.zita(e, ordi)
264
+
265
+ print(f"{zi = }")
266
+
267
+ self.generator = Ran1Generator(idum=iseed)
268
+
269
+ nnnnnn = 0
270
+
271
+ count = 0
272
+ count2 = 0
273
+ to_break = False
274
+
275
+ while True:
276
+
277
+ nnnnnn += 1
278
+
279
+ a1, a2 = self.guess(ndom, a1, a2, xro, self.generator.idum)
280
+
281
+ continue_mark = 0
282
+
283
+ if mct > 30:
284
+ if ncicle > 0:
285
+ ncicle = 4
286
+ amax = 0.
287
+ mct = 0
288
+ chisq = 1.0e30
289
+
290
+ continue
291
+
292
+ nc = 0
293
+ lista = np.zeros(na, dtype=np.float64)
294
+ for j in range(na):
295
+ lista[j] = j
296
+ mfit = na
297
+ if self.ncons == 1:
298
+ mfit = na - 1
299
+ alamda = -1
300
+ kc = 0.
301
+ ch = -1.
302
+ alam = 0.001
303
+
304
+ while True:
305
+
306
+ # print(f"\n======================================")
307
+ # print(f"Before run mrqmin | inputs: ")
308
+ # print(f"======================================")
309
+ #
310
+ # print(f"{zi = }")
311
+ # print(f"{self.f = }")
312
+ # print(f"{wf = }")
313
+ # print(f"{self.ni = }")
314
+ # print(f"{a2 = }")
315
+ # print(f"{na = }")
316
+ # print(f"{lista = }")
317
+ # print(f"{mfit = }")
318
+ # print(f"{covar = }")
319
+ # print(f"{alpha = }")
320
+ # print(f"{chisq = }")
321
+ # print(f"{alamda = }")
322
+
323
+ amax, chisq, alamda, covar, alpha, a2, y = self.mrqmin(
324
+ x=zi, y=self.f, sig=wf, ndata=self.ni, a=a2, ma=na, lista=lista, mfit=mfit, covar=covar,
325
+ alpha=alpha, chisq=chisq, alamda=alamda
326
+ )
327
+
328
+ kctotal = kctotal + 1
329
+
330
+ for j in range(0, na, 2):
331
+ if a2[j + 1] < -14:
332
+ amax = -1
333
+
334
+ for j in range(0, na, 2):
335
+ for k in range(0, na, 2):
336
+ if j == k:
337
+ continue
338
+ if a2[j] == a2[k]:
339
+ amax = -1
340
+
341
+ if amax == -1:
342
+ mct += 1
343
+ continue_mark = 1
344
+ break
345
+
346
+ if alam > alamda:
347
+ nc = 0
348
+ else:
349
+ nc += 1
350
+ if nc <= 50:
351
+ ch = chisq
352
+ alam = alamda
353
+ continue
354
+ mct += 1
355
+ continue_mark = 1
356
+ break
357
+
358
+ chisqn = chisq
359
+ if chisq > 1.:
360
+ chisqn = 1.
361
+
362
+ dchisq = abs((chisq - ch) / chisqn)
363
+ kc += 1
364
+
365
+ # print(f"{kc = }, {dchisq = }, {dchmin = }, {amax = }")
366
+ print(f'# dom = {ndom}, Isteps = {kc}, mct = {mct}, nc = {nc}, chisq = {chisq}')
367
+
368
+ # if count == 1 and count2 == 7:
369
+ # wuyang = input("continue")
370
+ # wuyang = input("continue")
371
+
372
+ if (dchisq >= dchmin and kc <= 100) or kc < 5:
373
+ ch = chisq
374
+ alam = alamda
375
+ continue
376
+ else:
377
+ break
378
+
379
+ if continue_mark == 1:
380
+ continue
381
+ count2 += 1
382
+ output_lines += f'\n{nnnnnn}# dom = {ndom}, Isteps = {kc}, mct = {mct}, nc = {nc}, chisq = {chisq}'
383
+ print(output_lines)
384
+ self.file_output_par.writelines(f"dom = {ndom}, Isteps = {kc}, mct = {mct}, nc = {nc}, chisq = {chisq}\n")
385
+ # wuyang = input("continue")
386
+
387
+ if ckchisq > chisq:
388
+ for j in range(na + 1):
389
+ auxa2[j] = a2[j]
390
+ for k in range(na + 1):
391
+ auxal[j, k] = alpha[j, k] # 注意二维数组的索引, alpha是一个对称矩阵
392
+ auxna = na
393
+ ckchisq = chisq
394
+
395
+ if ckchin > chisq:
396
+
397
+ y, dyda = self.funcs(zi[1], a2, na, auxa1)
398
+ if amax == -1:
399
+ break
400
+ ckchin = chisq
401
+
402
+ if ncicle < 4:
403
+ ncicle = ncicle + 1
404
+ else:
405
+ auxa1, a2, da = self.sort3(auxa1[:na + 1], a2[:na + 1], da[:na + 1])
406
+ ndom -= 1
407
+ mct = 0
408
+ ncicle = 0
409
+ ckchin = 1e30
410
+ sumc = 0
411
+ for j in range(0, na, 2):
412
+ sumc += auxa1[j + 1]
413
+
414
+ if ndom == self.mdom - 1:
415
+ for j in range(0, int(auxna + 1)):
416
+ a2[j] = auxa2[j]
417
+ for k in range(0, int(auxna + 1)):
418
+ alpha[j, k] = auxal[j, k] # 注意二维数组的索引
419
+ na = auxna
420
+ mfit = na
421
+ if self.ncons == 1:
422
+ mfit = na - 1
423
+ amax = 0
424
+
425
+ # go to 72
426
+
427
+ alamda = 0
428
+ ndom = int((na + 1) / 2)
429
+
430
+ amax, chisq, alamda, covar, alpha, a2, y = \
431
+ self.mrqmin(x=zi, y=self.f, sig=wf, ndata=self.ni, a=a2, ma=na,
432
+ lista=lista, mfit=mfit, covar=covar, alpha=alpha,
433
+ chisq=chisq, alamda=alamda, amax=amax)
434
+
435
+ if amax == -1:
436
+ mct += 1
437
+ continue
438
+
439
+ fmod = np.zeros(ns, dtype=np.float64)
440
+ for nt in range(self.ni):
441
+ y, dyda = self.funcs(zi[nt], a2, na, a1)
442
+ fmod[nt] = y
443
+ if amax == -1:
444
+ continue
445
+
446
+ a1, a2, da = self.sort3(a1[:na + 1], a2[:na + 1], da[:na + 1])
447
+
448
+ rpmax = a1[na - 1]
449
+ xlog = ordi - 2 * np.log10(rpmax)
450
+
451
+ self.file_output_ame.writelines(f"{ndom}\n")
452
+
453
+ sc = 0
454
+ kd = 8
455
+
456
+ orde = np.zeros(20, dtype=np.float64)
457
+ for j in range(0, na + 1, 2):
458
+
459
+ self.file_output_ame.writelines(f"{e}\n")
460
+
461
+ orde[j] = xlog - 2 * np.log10(a1[j] / rpmax)
462
+
463
+ self.file_output_ame.writelines(f"{orde[j]}\n")
464
+ self.file_output_ame.writelines(f"{a1[j + 1]}\n")
465
+
466
+ output_lines += f'\n{int((j + 1 + 1) / 2)}, {a1[j + 1]}, {a1[j] / rpmax}'
467
+ self.file_output_par.writelines(f"{int((j + 1 + 1) / 2)}, {a1[j + 1]}, {a1[j] / rpmax}\n")
468
+
469
+ if sc + a1[j + 1] > self.f[self.nimax] > sc:
470
+ kd = int((j + 1 + 1) / 2)
471
+
472
+ sc += a1[j + 1]
473
+
474
+ output_lines += f'\n{ckchisq}'
475
+ print(output_lines)
476
+ self.file_output_par.writelines(f"{ckchisq}\n")
477
+
478
+ slop = e * ee / 10000. / r
479
+
480
+ self.file_output_ame.writelines(f"{slop}\n")
481
+ self.file_output_ame.writelines(f"{ordi}\n")
482
+
483
+ dzx = np.zeros(ns, dtype=np.float64)
484
+ dzx, _ = self.arr(e, ordi, dzx, fmod, self.f, self.telab, self.tilab, xlogd)
485
+
486
+ chisq2 = 0.
487
+ noutlier = 0
488
+
489
+ for i in range(self.nimax):
490
+ dy1 = abs((xlogd[i] - dzx[i]) / wt[i])
491
+ if dy1 < 4:
492
+ chisq2 = chisq2 + dy1 ** 2
493
+ else:
494
+ noutlier += 1
495
+
496
+ q = gammq(0.5 * (self.nimax - 2), 0.5 * chisq2)
497
+
498
+ ke = 0
499
+ # print(f"{self.sname = }, {e = }, {sige = }, {ordi = }, {sigo = }, {ke = }, {chisq2 = }, {q = }, {self.nimax}, {noutlier = }")
500
+
501
+ self.file_output_ame.writelines(f"&\n")
502
+
503
+ if self.nloop <= self.ngauss:
504
+
505
+ output_lines += f'\n{kctotal = }'
506
+ self.file_output_par.writelines(f"{kctotal = }\n\n")
507
+
508
+ kctotal = 0
509
+ e, ordi = self.stats(e0, sige, ord0, sigo, self.generator.idum)
510
+
511
+ output_lines += f'\n{e = }, {ordi = }'
512
+
513
+ print(output_lines)
514
+ self.file_output_par.writelines(f"{e = }, {ordi = }\n")
515
+
516
+ # go to self.zita()
517
+
518
+ zi = self.zita(e, ordi)
519
+ ckchisq = 1.0e30
520
+ ckchin = 1.0e30
521
+ mct = 0
522
+ nnnnnn = 0
523
+
524
+ count += 1
525
+
526
+ if self.nloop == self.ngauss:
527
+ break
528
+ self.nloop += 1
529
+
530
+ continue
531
+ break
532
+ break
533
+
534
+ self.file_output_par.close()
535
+ self.file_output_ame.close()
536
+
537
+ return e, sige, ordi, sigo
538
+
539
+ def errcal(self):
540
+
541
+ ns = 200
542
+ r = 1.987E-3
543
+ ee = 0.4342944819
544
+ sigt0 = 90.
545
+ a0 = -0.19354
546
+ a1 = -0.62946
547
+ a2 = 0.13505
548
+ a3 = -0.01528
549
+
550
+ f1 = [0]
551
+
552
+ sumat = sum(self.a39)
553
+ sigsm = [i / sumat for i in self.sig39]
554
+ siga = [self.sig39[i] / self.a39[i] for i in range(self.ni)]
555
+
556
+ an1 = self.pi ** 2
557
+ sigat = 0.
558
+ swt = 0.
559
+ sigzit = [0.]
560
+ sigf = [0]
561
+
562
+ for i in range(self.ni):
563
+ sigat += sigsm[i] ** 2
564
+ sigf.append(sigat)
565
+
566
+ for i in range(1, self.ni + 1):
567
+ sigzit.append(0)
568
+ if self.f[i] <= 0.5:
569
+ fp = self.f[i] + self.f[i - 1]
570
+ as1 = 1. / fp ** 2 - 2. / fp
571
+ as2 = (self.f[i] ** 2 - 2 * self.f[i] * (self.f[i] ** 2 - self.f[i - 1] ** 2)) / fp ** 2
572
+ sigzit[i] = 4. * (sigat + sigf[i - 1] * as1 + siga[i - 1] ** 2 * as2)
573
+ else:
574
+ dzit2 = (np.log((1 - self.f[i]) / (1 - self.f[i - 1])) / an1) ** 2
575
+ as1 = ((self.f[i] - self.f[i - 1]) / an1) ** 2 / (1 - self.f[i - 1]) ** 2
576
+ sigzit[i] = ((sigat - sigf[i]) / (1 - self.f[i]) ** 2 + siga[i - 1] ** 2) * as1
577
+ sigzit[i] = sigzit[i] / dzit2
578
+
579
+ for i in range(self.ni):
580
+ sigt = (sigt0 / self.tilab[i]) ** 2
581
+ self.wt.append(ee * (sigt + sigzit[i + 1]) ** 0.5)
582
+ swt = swt + self.wt[i]
583
+ rate = (sigzit[i + 1] / sigt) ** 0.5
584
+
585
+ return self.wt
586
+
587
+ def param(self, tinv, wt, xlogd, nstop=20, r=1.987E-3, pi=3.141592654, ee=0.4342944879, dtp=5.0):
588
+
589
+ # print(f"\n======================================")
590
+ # print(f"Run param")
591
+ # print(f"======================================\n")
592
+ # print(f"{tinv = }")
593
+ # print(f"{wt = }")
594
+ # print(f"{xlogd = }")
595
+
596
+ telab = self.telab
597
+ ni = self.ni
598
+ ns = 200
599
+ f = np.zeros(ns + 1, dtype=np.float64)
600
+ telab = np.array(telab)
601
+ tilab = np.zeros(ns, dtype=np.float64)
602
+ xlogd = np.array(xlogd, dtype=np.float64)
603
+ sig39 = np.zeros(ns, dtype=np.float64)
604
+ xlogr = np.zeros(ns + 1, dtype=np.float64)
605
+ a39 = np.zeros(ns, dtype=np.float64)
606
+ acut = 0.0
607
+ b = 0.0
608
+ sige = 0.0
609
+ sigo = 0.0
610
+ qmax = 0.0
611
+ chisqe = 0.0
612
+ ni = int(ni)
613
+ imp = 0
614
+ nimax = 0
615
+ ke = 0
616
+
617
+ iflag2 = 0
618
+ nst = nstop # nstop = 20
619
+ y = np.zeros(ns, dtype=np.float64)
620
+ alog = np.zeros(ns, dtype=np.float64)
621
+ x1 = np.zeros(ns, dtype=np.float64)
622
+ y1 = np.zeros(ns + 1, dtype=np.float64)
623
+ wty = np.zeros(ns, dtype=np.float64)
624
+ wtx = np.zeros(ns, dtype=np.float64)
625
+
626
+ if ni < nstop:
627
+ nst = ni
628
+
629
+ ki = 0
630
+
631
+ while True:
632
+ print(f"{nst = }")
633
+ qmaxk = 0.0
634
+ qmax = 1.0
635
+ sx1 = 0.0
636
+
637
+ for j in range(1, 4):
638
+ x1[j - 1] = tinv[ki + j - 1]
639
+ sx1 += x1[j - 1]
640
+ y1[j - 1] = xlogd[ki + j - 1]
641
+ wty[j - 1] = wt[ki + j - 1]
642
+ wtx[j - 1] = 10000.0 * dtp / telab[ki + j - 1] ** 2
643
+
644
+ for k in range(4, nst + 1):
645
+ x1[k - 1] = tinv[ki + k - 1]
646
+ sx1 += x1[k - 1]
647
+ y1[k - 1] = xlogd[ki + k - 1]
648
+ wty[k - 1] = wt[ki + k - 1]
649
+ wtx[k - 1] = 10000.0 * dtp / telab[ki + k - 1] ** 2
650
+
651
+ if x1[k - 1] == sx1 / k:
652
+ continue
653
+
654
+ ncont = 1
655
+ for j in range(2, k + 1):
656
+ ks = 0
657
+ for j1 in range(1, j):
658
+ if x1[j - 1] == x1[j1 - 1]:
659
+ ks = 1
660
+ if ks == 0:
661
+ ncont += 1
662
+ # print(f"{ks = }, {ncont = }, {x1[j - 1] = }")
663
+
664
+ # print(x1[:k])
665
+ # print(y1[:k])
666
+ # print(x1)
667
+ # print(y1)
668
+
669
+ # a, siga, bf, sigb, mswd, conv, Di, _, r2, chi2, p_value, s = ap.calc.regression.york2(x1[:k], wtx[:k], y1[:k], wty[:k], [0 for i in x1[:k]])
670
+
671
+ # print("==== fit over =====")
672
+ # print(f"{a = }, {siga = }, {bf = }, {sigb = }, {chi2 = }, {p_value = }")
673
+
674
+ a, bf, siga, sigb, chi2, q = fit(x1[:k], y1[:k], wtx[:k], wty[:k])
675
+ # a: intercept, bf : slope
676
+
677
+ print("==== fit over =====")
678
+ line = f"{k = }, {a = }, {siga = }, {bf = }, {sigb = }, {chi2 = }, {q = }, {ncont = }"
679
+ print(line)
680
+ # with open(r"C:\Users\Young\Desktop\fit_results.txt", 'a+') as f:
681
+ # f.writelines(line + '\n')
682
+
683
+ if q / qmax < 1.e-10 and k > 8 and iflag2 == -1:
684
+ break
685
+
686
+ y[k - 1] = -r * bf * 10000.0 / ee
687
+ alog[k - 1] = a
688
+ sige1 = r * sigb * 10000.0 / ee
689
+ qs = k * q
690
+
691
+ if qs > qmaxk and ncont >= 3:
692
+ iflag2 = -1
693
+ ke = k
694
+ if qs > qmaxk:
695
+ qmaxk = qs
696
+ qmax = q
697
+ chisqe = chi2
698
+ sige = sigb * r * 10000.0 / ee
699
+ sigo = siga
700
+
701
+ e = y[k - 1]
702
+ ordi = alog[k - 1]
703
+
704
+ print(f"{ki = }, {qs = }, {qmaxk = }, {ncont = }")
705
+
706
+ if ki == 0 and qmax < 0.05:
707
+ ki = 1
708
+ else:
709
+ break
710
+
711
+ return e, sige, ordi, sigo
712
+
713
+ def zita(self, e, ordi, nca=20, ns=200, r=1.987E-3, pi=3.141592654, ee=0.4342944879):
714
+ zi = np.zeros(ns, dtype=np.float64)
715
+ imp = 2
716
+ d0 = 10 ** ordi / (imp ** 2)
717
+ for i in range(1, self.ni + 1):
718
+ zi[i] = d0 * self.tilab[i - 1] * np.exp(-1 * e / r / self.telab[i - 1]) + zi[i - 1]
719
+ return zi
720
+
721
+ def guess(self, ndom, a1, a2, xro, iseed):
722
+
723
+ # a1 = np.zeros(2 * ndom, dtype=np.float64)
724
+ # a2 = np.zeros(2 * ndom, dtype=np.float64)
725
+
726
+ na = 2 * ndom
727
+ sum = 0.0
728
+
729
+ # print(f"\n======================================")
730
+ # print(f"Run guess")
731
+ # print(f"======================================")
732
+ # print(f"{ndom = }, {xro = }, {iseed = }, {na = }")
733
+ # print(f"{a1 = }")
734
+ # print(f"{a2 = }")
735
+
736
+ # Definition of volume concentration
737
+ for j in range(0, na, 2):
738
+ a1[j + 1] = 1.0 + 10.0 * self.generator.ran1()
739
+ sum += a1[j + 1]
740
+
741
+ # Normalization of volume concentration
742
+ for j in range(0, na, 2):
743
+ a1[j + 1] = a1[j + 1] / sum
744
+
745
+ # Definition of sizes (start with random order numbers greater to smaller)
746
+ sum = 0.0
747
+ for j in range(0, na - 2, 2):
748
+ sum = 1.0 + 10.0 * self.generator.ran1() + sum
749
+ a1[na - 2 - j - 2] = sum
750
+
751
+ # Normalized to max log(r/ro) value xro, a1(1)=xro
752
+ for j in range(0, na - 2, 2):
753
+ a1[j] = a1[j] / sum * xro
754
+
755
+ sum = a1[na - 1] + a1[na - 3]
756
+ for j in range(2, na - 3, 2):
757
+ a1[j] = a1[j] - np.log10(sum)
758
+ sum = sum + a1[na - (j + 1) - 2]
759
+
760
+ ro = 10.0 ** a1[0]
761
+
762
+ for j in range(2, na - 3, 2):
763
+ a2[j] = a1[0] - a1[na - j - 2]
764
+
765
+ for j in range(2, na - 3, 2):
766
+ a1[j] = a2[j]
767
+
768
+ a1[na - 2] = np.log10(a1[na - 1])
769
+
770
+ for j in range(0, na - 3, 2):
771
+ a1[j] = a1[j + 1] / (10.0 ** a1[j] - 10.0 ** a1[j + 2])
772
+
773
+ a1[na - 2] = 1.0
774
+
775
+ # print(f"{a1}")
776
+
777
+ nloop = 0
778
+ while True:
779
+ ncont = 0
780
+ nloop += 1
781
+ for j in range(0, na - 3, 2):
782
+ rom = 0.0
783
+ if a1[j] > 1.0:
784
+ raise ValueError("a1(j) > 1.")
785
+ if a1[j + 2] < a1[j]:
786
+ ncont = 0
787
+ for k in range(j, j + 3, 2):
788
+ rom += a1[k + 1] / a1[k]
789
+ a1[j + 2] = a1[j]
790
+ a1[j] = a1[j + 1] / (rom - a1[j + 3] / a1[j + 2])
791
+ else:
792
+ ncont += 1
793
+
794
+ if nloop > 30:
795
+ raise ValueError("nloop greater than 30 on guess")
796
+ if ncont >= (ndom - 1):
797
+ break
798
+
799
+ sumro = 0.0
800
+ for j in range(0, na - 1, 2):
801
+ sumro += a1[j + 1] / a1[j]
802
+
803
+ # Calculation of A2
804
+ for j in range(0, na - 1, 2):
805
+ a2[j] = 2.0 * np.log(a1[j] * ro)
806
+ z = 2.0 * a1[j + 1] - 1.0
807
+ a2[j + 1] = 0.5 * np.log((z + 1.0) / abs(z - 1.0))
808
+
809
+
810
+ # print(f"\n======================================")
811
+ # print(f"Return guess")
812
+ # print(f"======================================\n")
813
+ # print(f"{a1 = }")
814
+ # print(f"{a2 = }")
815
+
816
+ return a1, a2
817
+
818
+ def mrqmin(self, x, y, sig, ndata, a, ma, lista, mfit, covar, alpha, chisq, alamda, amax=0):
819
+
820
+ mmax = 20
821
+
822
+ # print(f"\n======================================")
823
+ # print(f"Run mrqmin | inputs: ")
824
+ # print(f"======================================")
825
+ #
826
+ # print(f"{x = }")
827
+ # print(f"{y = }")
828
+ # print(f"{sig = }")
829
+ # print(f"{self.da = }")
830
+ # print(f"{self.atry = }")
831
+ # print(f"{self.beta = }")
832
+ # print(f"{a = }")
833
+ # print(f"{alpha = }")
834
+
835
+ x = x[:ndata + 1]
836
+ y = y[:ndata + 1]
837
+ sig = sig[:ndata + 1]
838
+
839
+ for j in range(0, ma, 2):
840
+ if abs(2 * a[j]) > amax: # 扩散与尺寸的两倍的最大值,相当于直径 (?)
841
+ amax = abs(2 * a[j])
842
+
843
+ if amax > 30:
844
+ amax = 30
845
+
846
+ if alamda < 0:
847
+ iseed = 1
848
+ kk = mfit + 1
849
+ for j in range(0, ma):
850
+ ihit = 0
851
+ for k in range(1, mfit + 1):
852
+ if lista[k - 1] == j:
853
+ ihit += 1
854
+ if ihit == 0:
855
+ lista[kk - 1] = j
856
+ kk += 1
857
+ elif ihit > 1:
858
+ raise ValueError('ERROR(MRQMIN): improper permutation in lista')
859
+
860
+ if kk != (ma + 1):
861
+ raise ValueError('ERROR(MRQMIN): improper perm. in lista')
862
+
863
+ alamda = 0.001
864
+
865
+ # print(f"\n======================================")
866
+ # print(f"Before run mrqcof | inputs: ")
867
+ # print(f"======================================")
868
+ #
869
+ # print(f"{x = }")
870
+ # print(f"{y = }")
871
+ # print(f"{sig = }")
872
+ # print(f"{ndata = }")
873
+ # print(f"{a = }")
874
+ # print(f"{ma = }")
875
+ # print(f"{lista = }")
876
+ # print(f"{mfit = }")
877
+ # print(f"{alpha = }")
878
+ # print(f"{self.beta = }")
879
+ # print(f"{amax = }")
880
+
881
+ chisq, alpha, self.beta, a = self.mrqcof(x, y, sig, ndata, a, ma, lista, mfit, alpha, self.beta,
882
+ amax)
883
+
884
+ # print(f"{alpha = }")
885
+
886
+ if amax == -1:
887
+ return amax, chisq, alamda, covar, alpha, a, y
888
+
889
+ self.ochisq = chisq
890
+ for j in range(ma):
891
+ self.atry[j] = a[j]
892
+
893
+ for j in range(1, mfit + 1):
894
+ for k in range(1, mfit + 1):
895
+ covar[j - 1, k - 1] = alpha[j - 1, k - 1]
896
+ covar[j - 1, j - 1] = alpha[j - 1, j - 1] * (1 + alamda)
897
+ self.da[j - 1] = self.beta[j - 1]
898
+
899
+
900
+ # print(f"\n======================================")
901
+ # print(f"Before run gaussj | inputs: ")
902
+ # print(f"======================================")
903
+ #
904
+ # print(f"{covar = }")
905
+ # print(f"{mfit = }")
906
+ # print(f"{self.da = }")
907
+ # print(f"{amax = }")
908
+
909
+
910
+ """
911
+ ### 重要:这里gaussj由于浮点数累乘,fortran与python有结果偏差,
912
+ ### Python保留了十六位有效数字,而fortran保留了十七位,进而影响了后续self.atry, alpha, covar等。
913
+ """
914
+
915
+ amax = self.gaussj(covar, mfit, self.da, amax=amax) # (a, n, b)
916
+
917
+ # print(f"{self.da = }")
918
+ # print(f"{amax = }")
919
+
920
+ # self.da = np.array([
921
+ # -0.74462339237294706, -5.4325676972901193E-002, 0.11264123464026662, -0.34299477191764405,
922
+ # -0.58013840179828902, -0.26581668757842275, -0.34280431209811241, -0.25866937785643079,
923
+ # 0.31231250958181944, -0.37302348875611602, -0.72941880170200390, -0.39768996285870495,
924
+ # 4.4803941640740721, 1.0107355396065272, -14.263407247136517, 0.0000000000000000,
925
+ # 0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000,
926
+ # ])
927
+
928
+ if amax == -1:
929
+ return amax, chisq, alamda, covar, alpha, a, y
930
+
931
+ for j in range(0, mfit, 2):
932
+ if abs(self.da[j]) > 8:
933
+ self.da[j] = 8 * np.sign(self.da[j])
934
+ if abs(self.da[j + 1]) > 3:
935
+ self.da[j + 1] = 3 * np.sign(self.da[j + 1])
936
+
937
+ if alamda == 0:
938
+ self.covsrt(covar, ma, lista, mfit)
939
+ return amax, chisq, alamda, covar, alpha, a, y
940
+
941
+ while True:
942
+
943
+ go_to_21 = False
944
+ sum = 0
945
+
946
+ for j in range(0, mfit):
947
+ self.atry[int(lista[j])] = a[int(lista[j])] + self.da[j]
948
+ if j % 2 != 0 and self.atry[int(lista[j])] < -5:
949
+ self.atry[int(lista[j])] = -5
950
+ if j % 2 == 0 and abs(self.atry[int(lista[j])]) > 14:
951
+ self.atry[int(lista[j])] = 14 * np.sign(self.atry[int(lista[j])]) + self.generator.ran1()
952
+
953
+ if ma != mfit:
954
+ for k in range(0, mfit - 1, 2):
955
+ if self.atry[k] >= self.atry[ma - 1] or abs(self.atry[k]) > amax:
956
+ self.da[k] /= 2
957
+ go_to_21 = True
958
+ break
959
+ if go_to_21:
960
+ continue
961
+ else:
962
+ for j in range(0, mfit, 2):
963
+ if abs(self.atry[j]) > amax:
964
+ self.da[j] /= 2
965
+ go_to_21 = True
966
+ break
967
+ if go_to_21:
968
+ continue
969
+
970
+ for k in range(1, mfit, 2):
971
+ sum += (1 + np.tanh(self.atry[k])) / 2
972
+ # print(f"{sum = }")
973
+ if sum >= 1:
974
+ for k in range(1, mfit + 1, 2):
975
+ self.da[k] /= 2
976
+ continue
977
+
978
+ break
979
+
980
+ # print(f"\n======================================")
981
+ # print(f"Before second run mrqcof | inputs: ")
982
+ # print(f"======================================")
983
+ #
984
+ # print(f"{x = }")
985
+ # print(f"{y = }")
986
+ # print(f"{sig = }")
987
+ # print(f"{ndata = }")
988
+ # print(f"{self.atry = }")
989
+ # print(f"{ma = }")
990
+ # print(f"{lista = }")
991
+ # print(f"{mfit = }")
992
+ # print(f"{covar = }")
993
+ # print(f"{self.da = }")
994
+ # print(f"{amax = }")
995
+
996
+ chisq, covar, _, __ = self.mrqcof(x, y, sig, ndata, self.atry, ma, lista, mfit, covar, self.da, amax)
997
+
998
+ # print(f"{covar = }")
999
+
1000
+ if amax == -1:
1001
+ return amax, chisq, alamda, covar, alpha, a, y
1002
+
1003
+ if chisq <= self.ochisq:
1004
+ alamda = 0.1 * alamda
1005
+ self.ochisq = chisq
1006
+ for j in range(mfit):
1007
+ for k in range(mfit):
1008
+ alpha[j, k] = covar[j, k]
1009
+ self.beta[j] = self.da[j]
1010
+ a[int(lista[j])] = self.atry[int(lista[j])]
1011
+ else:
1012
+ alamda = 10 * alamda
1013
+ chisq = self.ochisq
1014
+
1015
+ # print(f"\n======================================")
1016
+ # print(f"Return mrqmin | outputs: ")
1017
+ # print(f"======================================\n")
1018
+ #
1019
+ # print(f"{amax = }")
1020
+ # print(f"{chisq = }")
1021
+ # print(f"{alamda = }")
1022
+ # print(f"{covar = }")
1023
+ # print(f"{alpha = }")
1024
+ # print(f"{a = }")
1025
+ # print(f"{y = }")
1026
+ # print(f"{self.da = }")
1027
+ # print(f"{self.atry = }")
1028
+ # print(f"{self.beta = }")
1029
+
1030
+ return amax, chisq, alamda, covar, alpha, a, y
1031
+
1032
+ def mrqcof(self, x, y, sig, ndata, a, ma, lista, mfit, alpha, beta, amax):
1033
+
1034
+ # print(f"\n======================================")
1035
+ # print(f"Run mrqcof")
1036
+ # print(f"======================================")
1037
+ #
1038
+ # print(f"{x = }")
1039
+ # print(f"{y = }")
1040
+ # print(f"{sig = }")
1041
+ # print(f"{ndata = }")
1042
+ # print(f"{a = }")
1043
+ # print(f"{ma = }")
1044
+ # print(f"{lista = }")
1045
+ # print(f"{mfit = }")
1046
+ # # print(f"{alpha = }")
1047
+ # print(f"{beta = }")
1048
+ # print(f"{amax = }")
1049
+
1050
+ mmax = 20
1051
+ dyda = np.zeros(mmax, dtype=np.float64)
1052
+ a1 = np.zeros(mmax, dtype=np.float64)
1053
+ beta[:mfit] = 0.0
1054
+
1055
+ for j in range(mfit):
1056
+ for k in range(j + 1):
1057
+ alpha[j, k] = 0
1058
+
1059
+ chisq = 0.0
1060
+
1061
+ chisq_list = []
1062
+
1063
+ for i in range(0, ndata):
1064
+ ymod, dyda = self.funcs(x=x[i + 1], b=a, na=ma, a=a1)
1065
+ # print(f"after funcs {ymod = }, after funcs {dyda = }")
1066
+ if amax == -1:
1067
+ chisq = 1000000.0
1068
+ return chisq, alpha, beta, a
1069
+
1070
+ sig2i = 1.0 / (sig[i] ** 2)
1071
+ dy = y[i + 1] - ymod
1072
+ # print(f"{y[i + 1] = }, {sig[i] = }")
1073
+
1074
+ for j in range(mfit):
1075
+ wt = dyda[int(lista[j])] * sig2i
1076
+ # print(f"{dyda[int(lista[j])] = }")
1077
+ for k in range(j + 1):
1078
+ alpha[j, k] += wt * dyda[int(lista[k])]
1079
+ beta[j] += dy * wt
1080
+ # print(f"({i}, {j}) >>> {beta[j]}")
1081
+
1082
+ chisq += dy * dy * sig2i
1083
+ chisq_list.append(dy * dy * sig2i)
1084
+
1085
+ # print(f"{chisq = }, {self.ochisq = }, {y[i + 1] = }, {ymod = }, {sig2i = }")
1086
+ # print(f"after funcs {chisq = }")
1087
+
1088
+ # print(f"{alpha = }")
1089
+ # chisq = kahan_sum(chisq_list)
1090
+
1091
+ for j in range(1, mfit):
1092
+ for k in range(j):
1093
+ alpha[k, j] = alpha[j, k]
1094
+
1095
+ # print(f"\n======================================")
1096
+ # print(f"Return mrqcof")
1097
+ # print(f"======================================")
1098
+ #
1099
+ # print(f"{chisq = }")
1100
+ # print(f"{alpha = }")
1101
+ # print(f"{beta = }")
1102
+ # print(f"{a = }")
1103
+ # print(f"{ymod = }")
1104
+ # print(f"{dyda = }")
1105
+
1106
+ return chisq, alpha, beta, a
1107
+
1108
+ def funcs(self, x, b, na, a):
1109
+
1110
+ # print(f"\n======================================")
1111
+ # print(f"Run funcs")
1112
+ # print(f"======================================")
1113
+ # print(f"{x = }")
1114
+ # print(f"{b = }")
1115
+ # print(f"{na = }")
1116
+ # print(f"{a = }")
1117
+
1118
+ nmax = 21
1119
+ pi = 3.141592654
1120
+
1121
+ if na == 0:
1122
+ return 0, np.zeros(na + 1, dtype=np.float64)
1123
+
1124
+ y = 0.0
1125
+ as_ = 1.0
1126
+ csh = np.zeros(nmax, dtype=np.float64)
1127
+ dyda = np.zeros(na + 1, dtype=np.float64)
1128
+
1129
+ for j in range(0, na, 2):
1130
+ a[j] = np.exp(b[j])
1131
+ a[j + 1] = (1.0 + np.tanh(b[j + 1])) / 2.0
1132
+ csh[j + 1] = 0.5 / np.cosh(b[j + 1]) ** 2
1133
+ as_ -= a[j + 1]
1134
+
1135
+ a[na] = as_ + a[na]
1136
+ if a[na] < 1e-14:
1137
+ a[na] = 1e-14
1138
+
1139
+ b[na] = np.log(a[na])
1140
+
1141
+ for i in range(0, na, 2):
1142
+
1143
+ arg = x / a[i] * 4.0
1144
+ if arg < 0:
1145
+ raise ValueError("arg less than zero")
1146
+
1147
+ if arg <= 0.2827:
1148
+ gf = 2.0 * np.sqrt(arg / pi)
1149
+ else:
1150
+ if (pi / 2) ** 2 * arg > 80:
1151
+ gf = 1.0
1152
+ else:
1153
+ gf = 1.0 - 8.0 / pi ** 2 * np.exp(-(pi / 2) ** 2 * arg)
1154
+
1155
+ dgf = 0.0
1156
+ for j in range(1, 50000, 2):
1157
+ arg1 = (j * pi / 2.0) ** 2 * arg
1158
+ if arg1 > 25:
1159
+ break
1160
+ dgf += 2.0 * np.exp(-arg1)
1161
+
1162
+ y += a[i + 1] * gf
1163
+
1164
+ dyda[i + 1] = gf * csh[i + 1]
1165
+ dyda[i] = -a[i + 1] * dgf * arg
1166
+
1167
+ # print(f"{a[i] = }")
1168
+ # print(f"{a[i + 1] = }")
1169
+ # print(f"{csh[i + 1] = }")
1170
+ # print(f"{gf = }")
1171
+ # print(f"{dgf = }")
1172
+ # print(f"{arg = }")
1173
+
1174
+ a[i] = np.sqrt(a[i])
1175
+
1176
+ # print(f"\n======================================")
1177
+ # print(f"Return funcs")
1178
+ # print(f"======================================")
1179
+ # print(f"{y = }")
1180
+ # print(f"{dyda = }")
1181
+
1182
+ return y, dyda
1183
+
1184
+ def gaussj(self, a, n, b, amax=0):
1185
+
1186
+ # m = b.shape[1]
1187
+
1188
+ nmax = 50
1189
+ ipiv = np.zeros(nmax, dtype=int)
1190
+ indxr = np.zeros(nmax, dtype=int)
1191
+ indxc = np.zeros(nmax, dtype=int)
1192
+
1193
+ # print(f"\n======================================")
1194
+ # print(f"Run gaussj")
1195
+ # print(f"======================================")
1196
+ # print(f"{a = }")
1197
+ # print(f"{n = }")
1198
+ # print(f"{b = }")
1199
+ # print(f"{amax = }")
1200
+
1201
+ for j in range(n):
1202
+ ipiv[j] = 0
1203
+
1204
+ for i in range(n):
1205
+
1206
+ big = 0.0
1207
+ for j in range(n):
1208
+ if ipiv[j] != 1:
1209
+ for k in range(n):
1210
+ if ipiv[k] == 0:
1211
+ if abs(a[j, k]) >= big:
1212
+ big = abs(a[j, k])
1213
+ irow = j
1214
+ icol = k
1215
+ elif ipiv[k] > 1:
1216
+ amax = -1
1217
+ # return a, b, amax
1218
+ return amax
1219
+
1220
+ ipiv[icol] += 1
1221
+ if irow != icol:
1222
+ for v in range(n):
1223
+ dum = a[irow, v]
1224
+ a[irow, v] = a[icol, v]
1225
+ a[icol, v] = dum
1226
+
1227
+ for v in range(1):
1228
+ try:
1229
+ dum = b[v, irow]
1230
+ b[v, irow] = b[v, icol]
1231
+ b[v, icol] = dum
1232
+ except IndexError:
1233
+ dum = b[irow]
1234
+ b[irow] = b[icol]
1235
+ b[icol] = dum
1236
+
1237
+ indxr[i] = irow
1238
+ indxc[i] = icol
1239
+ if a[icol, icol] == 0.0:
1240
+ amax = -1
1241
+
1242
+ return amax
1243
+
1244
+ pivinv = 1.0 / a[icol, icol]
1245
+
1246
+ a[icol, icol] = 1.0
1247
+ a[icol] *= pivinv
1248
+ b[icol] *= pivinv
1249
+
1250
+ """
1251
+ ### 重要:这里gaussj由于浮点数累乘,fortran与python有结果偏差,
1252
+ ### Python保留了十六位有效数字,而fortran保留了十七位,进而影响了后续self.atry, alpha, covar等。
1253
+ """
1254
+
1255
+ for ll in range(n):
1256
+ if ll != icol:
1257
+ dum = a[ll, icol]
1258
+ a[ll, icol] = 0.0
1259
+ a[ll, :] -= a[icol, :] * dum
1260
+ b[ll] -= b[icol] * dum
1261
+
1262
+ for l in range(n - 1, -1, -1):
1263
+ if indxr[l] != indxc[l]:
1264
+ a[:, [indxr[l], indxc[l]]] = a[:, [indxc[l], indxr[l]]]
1265
+
1266
+ # print(f"\n======================================")
1267
+ # print(f"Return gaussj")
1268
+ # print(f"======================================")
1269
+ # print(f"{a = }")
1270
+ # print(f"{n = }")
1271
+ # print(f"{b = }")
1272
+ # print(f"{amax = }")
1273
+
1274
+ return amax
1275
+
1276
+ def covsrt(self, covar, ma, lista, mfit):
1277
+ # covar is expected to be a numpy array of shape (ncvm, ncvm)
1278
+ # lista is expected to be a numpy array of shape (mfit,)
1279
+
1280
+ # Step 1: Zero out the upper triangle
1281
+ for j in range(ma - 1):
1282
+ for i in range(j + 1, ma):
1283
+ covar[i, j] = 0.0
1284
+
1285
+ # Step 2: Reorganize the covariance matrix
1286
+ for i in range(mfit - 1):
1287
+ for j in range(i + 1, mfit):
1288
+ if lista[j] > lista[i]:
1289
+ covar[int(lista[j]), int(lista[i])] = covar[i, j]
1290
+ else:
1291
+ covar[int(lista[j]), int(lista[i])] = covar[i, j]
1292
+
1293
+ # Step 3: Swap and reset diagonal elements
1294
+ swap = covar[0, 0]
1295
+ for j in range(ma):
1296
+ covar[0, j] = covar[j, j]
1297
+ covar[j, j] = 0.0
1298
+
1299
+ covar[int(lista[0]), int(lista[0])] = swap
1300
+
1301
+ for j in range(1, mfit):
1302
+ covar[int(lista[j]), int(lista[j])] = covar[0, j]
1303
+
1304
+ # Step 4: Symmetrize the covariance matrix
1305
+ for j in range(1, ma):
1306
+ for i in range(j):
1307
+ covar[i, j] = covar[j, i]
1308
+
1309
+ return covar
1310
+
1311
+ def indexx(self, arrin):
1312
+
1313
+ n = len(arrin)
1314
+ indx = np.zeros(n, dtype=int)
1315
+
1316
+ for i in range(0, n, 2):
1317
+ indx[i] = i
1318
+ l = int(n / 4) * 2 + 1
1319
+ ir = n - 1
1320
+
1321
+ while True:
1322
+
1323
+ if l > 1:
1324
+ l -= 2
1325
+ indxt = indx[l - 1]
1326
+ q = arrin[indxt]
1327
+ else:
1328
+ indxt = indx[ir - 1]
1329
+ q = arrin[indxt]
1330
+ indx[ir - 1] = indx[1 - 1]
1331
+ ir -= 2
1332
+ if ir == 1:
1333
+ indx[1 - 1] = indxt
1334
+ return indx
1335
+ i = l
1336
+ j = l + l + 1
1337
+ while True:
1338
+ if j <= ir:
1339
+ if j < ir:
1340
+ if arrin[indx[j - 1]] < arrin[indx[j + 2 - 1]]:
1341
+ j += 2
1342
+ if q < arrin[indx[j - 1]]:
1343
+ indx[i - 1] = indx[j - 1]
1344
+ i = j
1345
+ j = j + j + 1
1346
+ else:
1347
+ j = ir + 2
1348
+ continue
1349
+ else:
1350
+ break
1351
+ indx[i - 1] = indxt
1352
+ continue
1353
+
1354
+ def sort3(self, ra, rb, rc):
1355
+ #
1356
+ # print(f"\n======================================")
1357
+ # print(f"Run sort3")
1358
+ # print(f"======================================")
1359
+
1360
+ n = len(ra)
1361
+ iwksp = self.indexx(ra)
1362
+
1363
+ wksp = np.empty(n)
1364
+ wksp[:] = ra[:]
1365
+ for i in range(0, n, 2):
1366
+ ra[i] = wksp[iwksp[i]]
1367
+ ra[i + 1] = wksp[iwksp[i] + 1]
1368
+
1369
+ n = len(rb)
1370
+ wksp = np.empty(n)
1371
+ wksp[:] = rb[:]
1372
+ for i in range(0, n, 2):
1373
+ rb[i] = wksp[iwksp[i]]
1374
+ rb[i + 1] = wksp[iwksp[i] + 1]
1375
+
1376
+ n = len(rc)
1377
+ wksp = np.empty(n)
1378
+ wksp[:] = rc[:]
1379
+ for i in range(0, n, 2):
1380
+ rc[i] = wksp[iwksp[i]]
1381
+ rc[i + 1] = wksp[iwksp[i] + 1]
1382
+
1383
+ # print(f"{n = }")
1384
+ # print(f"{ra = }")
1385
+ # print(f"{rb = }")
1386
+ # print(f"{rc = }")
1387
+ # print(f"{wksp = }")
1388
+ # print(f"{iwksp = }")
1389
+
1390
+ return ra, rb, rc
1391
+
1392
+ def gasdev(self):
1393
+ # Using numpy's random normal distribution generator
1394
+ # return np.random.normal()
1395
+ if self.iset == 0:
1396
+ while True:
1397
+ v1 = 2 * self.generator.ran1() - 1
1398
+ v2 = 2 * self.generator.ran1() - 1
1399
+ r = v1 ** 2 + v2 ** 2
1400
+
1401
+ if r >= 1:
1402
+ continue
1403
+ else:
1404
+ break
1405
+ fac = np.sqrt(-2 * np.log(r) / r)
1406
+ self.gset = v1 * fac
1407
+ res = v2 * fac
1408
+ self.iset = 1
1409
+ else:
1410
+ res = self.gset
1411
+ self.iset = 0
1412
+
1413
+ return res
1414
+
1415
+ def stats(self, xval, xerr, yval, yerr, idum):
1416
+ #
1417
+ # print(f"\n======================================")
1418
+ # print(f"Run stats")
1419
+ # print(f"======================================")
1420
+ #
1421
+ # print(f"{xval = }")
1422
+ # print(f"{xerr = }")
1423
+ # print(f"{yval = }")
1424
+ # print(f"{yerr = }")
1425
+ # print(f"{idum = }")
1426
+
1427
+ rt = 0.938
1428
+ rt1 = np.sqrt(1.0 - rt ** 2)
1429
+
1430
+ gnoise1 = self.gasdev()
1431
+ xran = xval + xerr * gnoise1
1432
+
1433
+ gnoise2 = self.gasdev()
1434
+ yran = yval + yerr * (rt * gnoise1 + rt1 * gnoise2)
1435
+
1436
+ return xran, yran
1437
+
1438
+ def arr(self, e, ord, dzx, fmod, f, telab, tilab, xlogd,
1439
+ ns=200, r=1.987e-3, pi=3.141592654, ee=0.4342944879, acut=0, b=1, imp=1):
1440
+
1441
+ # print(f"{e = }")
1442
+ # print(f"{ord = }")
1443
+ # print(f"{dzx = }")
1444
+ # print(f"{fmod = }")
1445
+ # print(f"{f = }")
1446
+ # print(f"{telab = }")
1447
+ # print(f"{tilab = }")
1448
+ # print(f"{xlogd = }")
1449
+
1450
+ zx = np.zeros(ns + 1, dtype=np.float64)
1451
+ dzx = np.zeros(ns, dtype=np.float64)
1452
+ tab1 = "\t"
1453
+
1454
+ ni = self.ni
1455
+
1456
+ # INVERSION OF 39-F
1457
+ for k in range(ni):
1458
+ if fmod[k] > acut:
1459
+ zx[k + 1] = -np.log(pi ** 2 / b * (1.0 - fmod[k])) / pi ** 2
1460
+ else:
1461
+ zx[k + 1] = pi * (fmod[k] / 4.0) ** 2
1462
+
1463
+ zx[0] = 0.0
1464
+ slop = e * ee / 10000.0 / r
1465
+
1466
+ results_18 = []
1467
+ results_16 = []
1468
+ results_22 = []
1469
+
1470
+ for k in range(ni):
1471
+ dzx[k] = np.log10((zx[k + 1] - zx[k]) / tilab[k] * imp ** 2)
1472
+ tinv = 1.0 / telab[k] * 10000.0
1473
+ xlog = (ord - slop * tinv - dzx[k]) / 2.0
1474
+ results_18.append(f"{fmod[k - 1] * 100:.8f}{tab1}{xlog:.8f}")
1475
+ results_18.append(f"{fmod[k] * 100:.8f}{tab1}{xlog:.8f}")
1476
+ results_16.append(f"{tinv:.8f}{tab1}{dzx[k]:.8f}")
1477
+
1478
+ results_16.append("&")
1479
+ results_18.append("&")
1480
+
1481
+ for k in range(ni):
1482
+ tinv = 1.0 / telab[k] * 10000.0
1483
+ xlogr0 = (ord - slop * tinv - xlogd[k]) / 2.0
1484
+ results_22.append(f"{f[k - 1] * 100:.8f}{tab1}{xlogr0:.8f}")
1485
+ results_22.append(f"{f[k] * 100:.8f}{tab1}{xlogr0:.8f}")
1486
+
1487
+ return dzx, zx
1488
+
1489
+
1490
+ class DiffAgemonFuncs(DiffSample):
1491
+
1492
+ def __init__(self, ni=10, mmax=100, ochisq=0, **kwargs):
1493
+
1494
+ self.ni = ni
1495
+ self.mmax = mmax
1496
+ self.ochisq = ochisq
1497
+
1498
+ super().__init__(**kwargs)
1499
+
1500
+ self.nca = 200
1501
+ self.da = np.zeros(self.ni, dtype=np.float64)
1502
+ self.beta = np.zeros(self.mmax, dtype=np.float64)
1503
+ self.atry = np.zeros(self.mmax, dtype=np.float64)
1504
+
1505
+ # constants
1506
+ self.nwcy = 10
1507
+ self.ncyc = 1
1508
+ self.ntst = 1001
1509
+ self.ns = 200
1510
+ self.nmaxi = np.zeros(self.nwcy, dtype=int)
1511
+ self.nmaxo = np.zeros(self.nwcy, dtype=int)
1512
+ self.tti = np.zeros([self.nwcy, 2, self.ntst], dtype=np.float64)
1513
+ self.tto = np.zeros([self.nwcy, 2, self.ntst], dtype=np.float64)
1514
+ self.agei = np.zeros([self.nwcy, 2, self.ns], dtype=np.float64)
1515
+ self.ageo = np.zeros([self.nwcy, 2, self.ns], dtype=np.float64)
1516
+
1517
+ self.file_ame_in = open(os.path.join(self.loc, f"{self.sname}.ame"), "r") # from arrmulti
1518
+
1519
+ self.file_output_mch = open(os.path.join(self.loc, f"{self.sname}_mch-out.dat"), "w")
1520
+ self.file_output_mages = open(os.path.join(self.loc, f"{self.sname}_mages-out.dat"), "w")
1521
+ self.file_output_agesd = open(os.path.join(self.loc, f"{self.sname}_ages-sd.samp"), "w")
1522
+
1523
+ self.file_output_mch.close()
1524
+ self.file_output_mages.close()
1525
+ self.file_output_agesd.close()
1526
+
1527
+ # parameters
1528
+ self.ns = 200
1529
+ self.nc = 100
1530
+ self.ntst = 1001
1531
+ self.mxi = 350
1532
+ self.nn = 319
1533
+ self.mfit = 10
1534
+ self.nwcy = 10
1535
+ self.nd = 10
1536
+ self.xlambd = 0.0005543
1537
+ self.a = 0
1538
+ self.perc = 0.01
1539
+ self.cht0 = 1.0e-4
1540
+ self.nrun = 5
1541
+ self.maxrun = 15
1542
+ self.nemax = 10
1543
+
1544
+ read_from_file = kwargs.get('read_from_file', False)
1545
+ if read_from_file:
1546
+ self.file_age_in = open(os.path.join(self.loc, f"{self.sname}_age.in"), "r")
1547
+ self.file_sig_in = open(os.path.join(self.loc, f"{self.sname}_sig.in"), "r")
1548
+ self.file_tmp_in = open(os.path.join(self.loc, f"{self.sname}_tmp.in"), "r")
1549
+
1550
+ # 读取加热温度和时间
1551
+ self.ni = int(self.file_tmp_in.readline())
1552
+ self.nit = self.ni
1553
+ self.r39 = np.zeros(self.ni, dtype=np.float64)
1554
+ self.telab = np.zeros(self.ni, dtype=np.float64)
1555
+ self.tilab = np.zeros(self.ni, dtype=np.float64)
1556
+ for i in range(self.ni):
1557
+ self.telab[i] = float(self.file_tmp_in.readline())
1558
+ self.tilab[i] = float(self.file_tmp_in.readline())
1559
+ self.tilab[i] /= 5.256E+11 # 1 Ma = 525600000000 minutes
1560
+ if self.telab[i] > 1373:
1561
+ # go to 11
1562
+ self.ni = i
1563
+ break
1564
+
1565
+ # 读取sig
1566
+ self.sig = np.zeros(self.ns, dtype=np.float64)
1567
+ self.xs = np.zeros(self.ns + 1, dtype=np.float64)
1568
+ self.ya = np.zeros(self.ns + 1, dtype=np.float64)
1569
+ for i in range(self.nit + 1):
1570
+ try:
1571
+ self.sig[i] = float(self.file_sig_in.readline())
1572
+ if self.sig[i] <= 0:
1573
+ raise ValueError("Sigma less than 0")
1574
+ self.xs[i + 1], self.ya[i + 1] = [float(j) for j in filter(lambda x: is_number(x),
1575
+ self.file_age_in.readline().split(' '))]
1576
+ self.xs[i + 1] /= 100
1577
+ if self.ya[i] < 0:
1578
+ self.ya[i] = 0
1579
+ except ValueError:
1580
+ print(f"{i = } error in reading sig file")
1581
+ continue
1582
+
1583
+ self.file_tmp_in.close()
1584
+ self.file_age_in.close()
1585
+ self.file_sig_in.close()
1586
+
1587
+ # 读取
1588
+ nemax = 0
1589
+ self.nst_arr = np.zeros(100, dtype=int)
1590
+ self.e_arr = np.zeros(100, dtype=np.float64)
1591
+ self.d0_arr = np.zeros([100, 20], dtype=np.float64)
1592
+ self.vc_arr = np.zeros([100, 20], dtype=np.float64)
1593
+ self.e = 0
1594
+ self.d0 = np.zeros(self.nd, dtype=np.float64)
1595
+ self.vc = np.zeros(self.nd, dtype=np.float64)
1596
+ kk = 0
1597
+ while True:
1598
+ try:
1599
+ self.nst_arr[kk] = int(self.file_ame_in.readline()) # sequence number
1600
+ # self.nst = int(self.file_ame_in.readline()) # sequence number
1601
+ for i in range(self.nst_arr[kk]):
1602
+ self.e_arr[kk] = float(self.file_ame_in.readline())
1603
+ self.d0_arr[kk, i] = 10 ** float(self.file_ame_in.readline()) / 4 * (24 * 3600 * 365e+6)
1604
+ self.vc_arr[kk, i] = float(self.file_ame_in.readline())
1605
+ # self.e = float(self.file_ame_in.readline())
1606
+ # self.d0[i] = float(self.file_ame_in.readline())
1607
+ # self.vc[i] = float(self.file_ame_in.readline())
1608
+ # self.d0[i] = 10 ** self.d0[i] / 4 * (24 * 3600 * 365e+6)
1609
+ nemax += 1
1610
+ self.atmp = self.file_ame_in.readline()
1611
+ self.atmp = self.file_ame_in.readline()
1612
+ self.atmp = self.file_ame_in.readline()
1613
+ kk += 1
1614
+ except ValueError:
1615
+ break
1616
+ self.kk = kk
1617
+ print(f"{self.kk = }")
1618
+
1619
+
1620
+ self.max_plateau_age = 10
1621
+
1622
+ self.file_ame_in.close()
1623
+
1624
+ def main(self):
1625
+
1626
+ ###
1627
+ # initialize
1628
+ lista = np.zeros(self.nc, dtype=int)
1629
+ c0 = np.zeros(self.nc, dtype=np.float64)
1630
+ c = np.zeros(self.nc, dtype=np.float64)
1631
+ chq = np.zeros(self.nwcy, dtype=np.float64)
1632
+ nchini = 0
1633
+ tt = np.zeros([2, self.ntst + 1], dtype=np.float64)
1634
+ tt[0, 1] = self.max_plateau_age
1635
+
1636
+ for kk in range(self.kk):
1637
+
1638
+ stop_main = False
1639
+
1640
+ print(f"New kk")
1641
+ print(f"{kk = }")
1642
+
1643
+ mcyc = 0
1644
+ agein = tt[0, 1]
1645
+ idem = -1 * tt[0, 1]
1646
+ tt[1, 1] = 500
1647
+ tt[1, 2] = 300
1648
+ tt[0, 2] = tt[0, 1] / 2
1649
+ tt[1, 3] = 0
1650
+ tt[0, 3] = 0
1651
+ self.ncyc = 1
1652
+ chqmin = 1e20
1653
+
1654
+ # calculation of lc
1655
+ self.lc = np.zeros(self.nn, dtype=int)
1656
+ nsq = 2
1657
+ nsum = 0
1658
+ m = -1
1659
+ for mi in range(self.nn):
1660
+ if nsum > 20:
1661
+ nsum = 1
1662
+ nsq *= 2
1663
+ m += nsq
1664
+ if m > 200:
1665
+ nsum += 1
1666
+ self.lc[mi] = m
1667
+
1668
+ self.func = self
1669
+ self.ran1 = Ran1Generator(idum=idem)
1670
+
1671
+ self.r39 = self.r39[:self.ni + 1]
1672
+ self.telab = self.telab[:self.ni]
1673
+ self.tilab = self.tilab[:self.ni]
1674
+ self.lc = self.lc[:self.nn]
1675
+
1676
+ # self.d0 = self.d0[:self.nst]
1677
+ # self.vc = self.vc[:self.nst]
1678
+
1679
+ self.nst = self.nst_arr[kk]
1680
+ self.d0 = self.d0_arr[kk, :self.nst]
1681
+ self.vc = self.vc_arr[kk, :self.nst]
1682
+ self.e = self.e_arr[kk]
1683
+
1684
+ print(f"{self.e = }")
1685
+
1686
+ xmat = np.zeros([self.nd, self.ns + 1, self.nn], dtype=np.float64)
1687
+
1688
+ # call lab
1689
+ self.r39, self.d0, self.e, self.vc, self.telab, self.tilab, self.lc, xmat, self.ni, self.nst, self.nn = \
1690
+ self.lab(self.r39, self.d0, self.e, self.vc, self.telab, self.tilab,
1691
+ self.lc, xmat, self.ni, self.nst, self.nn)
1692
+
1693
+ ys = np.zeros(self.ns + 2, dtype=np.float64)
1694
+ ne = 1
1695
+ self.r39 = np.pad(self.r39, (0, self.nit - self.ni), mode='constant', constant_values=0)
1696
+ self.wt = np.zeros(self.ni + 1, dtype=np.float64)
1697
+ for i in range(self.ni + 1):
1698
+ self.wt[i] = 1 / np.sqrt(abs(self.r39[i + 1] - self.r39[i])) * self.sig[i]
1699
+
1700
+ # call agesamp
1701
+ # print(f"{self.ya = }")
1702
+ # print(f"{ys = }")
1703
+ # print(f"{self.r39 = }")
1704
+ # print(f"{self.xs = }")
1705
+ ys = self.agesamp(self.r39, ys, self.wt, self.nit, ne, self.ya, self.xs)
1706
+ # print(f"{ys = }")
1707
+
1708
+ c = np.zeros(self.nc, dtype=np.float64)
1709
+ _np = 3
1710
+ a = 0
1711
+
1712
+ # call chebft
1713
+ c = self.chebft(a, tt[0, 1], c, self.nc, self.slope, tt, _np)
1714
+
1715
+ # print(f"{c = }")
1716
+ # print(f"{len(c) = }")
1717
+
1718
+ for i in range(self.mfit):
1719
+ lista[i] = i
1720
+ c0[i] = c[i]
1721
+
1722
+ while True:
1723
+
1724
+ # call ranchist
1725
+ c, tt[1, 1] = self.ranchist(c, c0, self.mfit, idem, tt[1, 1])
1726
+
1727
+ # print(f"after ranchist")
1728
+ # print(f"{c = }")
1729
+ # print(f"{len(c) = }")
1730
+
1731
+ dch = 0
1732
+ alamda = -1
1733
+
1734
+ chisq = 0
1735
+ nn1 = self.nn
1736
+ covar = np.zeros([self.nc, self.nc], dtype=np.float64)
1737
+ alpha = np.zeros([self.nc, self.nc], dtype=np.float64)
1738
+
1739
+ # call mrqmin
1740
+ # print(f"{chisq = }")
1741
+
1742
+ print(f"{self.ya = }")
1743
+ # print(f"{self.r39 = }")
1744
+ # print(f"{ys = }")
1745
+ # print(f"{self.wt = }")
1746
+ # print(f"{self.ni = }")
1747
+ # print(f"{c = }")
1748
+ # print(f"{self.nc = }")
1749
+ # print(f"{lista = }")
1750
+ # print(f"{self.mfit = }")
1751
+ # # print(f"{covar = }")
1752
+ # # print(f"{alpha = }")
1753
+ # print(f"{chisq = }")
1754
+ # print(f"{alamda = }")
1755
+ # # print(f"{tt = }")
1756
+ # # print(f"{xmat = }")
1757
+ # print(f"{self.lc = }")
1758
+ # print(f"{self.vc = }")
1759
+ # print(f"{self.d0 = }")
1760
+ # print(f"{self.e = }")
1761
+ # print(f"{self.nst = }")
1762
+ # print(f"{nn1 = }")
1763
+
1764
+
1765
+
1766
+ self.r39, ys, self.wt, self.ni, c, self.nc, lista, self.mfit, covar, alpha, self.nc, chisq, alamda, tt, xmat, self.lc, self.vc, self.d0, self.e, self.nst, nn1 = \
1767
+ self.func.mrqmin_agemon(self.r39, ys, self.wt, self.ni, c, self.nc, lista, self.mfit, covar,
1768
+ alpha, self.nc, chisq, alamda, tt, xmat, self.lc, self.vc, self.d0,
1769
+ self.e, self.nst, nn1)
1770
+ # print(f"{chisq = }")
1771
+
1772
+ # print(f"{c = }")
1773
+ # print(f"{len(c) = }")
1774
+
1775
+ k = 1
1776
+ itst = 0
1777
+
1778
+ alam = alamda
1779
+ while True:
1780
+
1781
+ print(f"it #= {k}, {alamda = }, {chisq = }, ochisq = {self.ochisq}")
1782
+
1783
+ if dch > 0:
1784
+ print(f"chi-squared = {self.ni * chisq}")
1785
+
1786
+ k += 1
1787
+ ochisq = chisq
1788
+
1789
+ # print(f"{self.r39 = }")
1790
+ # print(f"{ys = }")
1791
+ # print(f"{self.wt = }")
1792
+ # print(f"{self.ni = }")
1793
+ # print(f"{c = }")
1794
+ # print(f"{self.nc = }")
1795
+ # print(f"{lista = }")
1796
+ # print(f"{self.mfit = }")
1797
+ # # print(f"{covar = }")
1798
+ # # print(f"{alpha = }")
1799
+ # print(f"{chisq = }")
1800
+ # print(f"{alamda = }")
1801
+ # # print(f"{tt = }")
1802
+ # # print(f"{xmat = }")
1803
+ # print(f"{self.lc = }")
1804
+ # print(f"{self.vc = }")
1805
+ # print(f"{self.d0 = }")
1806
+ # print(f"{self.e = }")
1807
+ # print(f"{self.nst = }")
1808
+ # print(f"{nn1 = }")
1809
+
1810
+
1811
+ # call mrqmin
1812
+ self.r39, ys, self.wt, self.ni, c, self.nc, lista, self.mfit, covar, alpha, self.nc, chisq, alamda, tt, xmat, self.lc, self.vc, self.d0, self.e, self.nst, nn1 = \
1813
+ self.func.mrqmin_agemon(self.r39, ys, self.wt, self.ni, c, self.nc, lista, self.mfit, covar,
1814
+ alpha, self.nc, chisq, alamda, tt, xmat, self.lc, self.vc, self.d0,
1815
+ self.e, self.nst, nn1)
1816
+
1817
+ dch = abs(ochisq - chisq)
1818
+ cht = self.cht0 * chisq
1819
+
1820
+ if dch < cht and alamda < alam:
1821
+ itst += 1
1822
+ # print(f"{itst = }")
1823
+
1824
+ alam = alamda
1825
+ if itst < 3:
1826
+ continue
1827
+ else:
1828
+ break
1829
+ #
1830
+ # print(f"{ochisq = }")
1831
+ # print(f"{chisq = }")
1832
+ print(f"difference = {(ochisq - chisq) * self.ni}")
1833
+
1834
+ chq[self.ncyc] = chisq
1835
+ aq = (self.ni - 2) / 2
1836
+ # q = gammq(aq, self.ni * chisq / 2)
1837
+ q = self.func.gammq(aq, self.ni * chisq / 2)
1838
+
1839
+ print(f"chisq = {self.ni * chisq}, GOF = {q}")
1840
+
1841
+ alamda = 0
1842
+ c40 = 1 - np.exp(-self.xlambd * tt[0, 1])
1843
+
1844
+ # call zita
1845
+ xi = np.zeros([2 * self.nc + 1, self.nd, self.mxi], dtype=np.float64)
1846
+
1847
+ c, xi = self.func.zita_agemon(
1848
+ c, self.nc, lista, self.mfit, self.lc, xi, tt[0, 1],
1849
+ self.d0, self.e, tt, self.nst, self.nn, self.perc, alamda)
1850
+
1851
+ ymod = 0
1852
+ dyda = np.zeros(self.mfit, dtype=np.float64)
1853
+ for i in range(1, self.ni + 1):
1854
+ # call age
1855
+ ymod, dyda = self.func.age(
1856
+ i, c, ymod, dyda, self.nc, lista, self.mfit,
1857
+ self.vc, xmat, self.r39, xi, c40, self.nn,
1858
+ self.nst, self.ni, self.perc, alamda)
1859
+ # print(f"after age funcs {alamda = }")
1860
+
1861
+ continue
1862
+
1863
+ # print(f"{nchini = }, {chisq = }")
1864
+
1865
+ if nchini == 0:
1866
+ chqmin = chisq
1867
+ nchini += 1
1868
+
1869
+ print(f"new cycle: {nchini}")
1870
+ print(f"{self.ncyc = }, {nchini = }")
1871
+
1872
+ # 1, 1
1873
+ # 2, 2
1874
+ # 3, 3
1875
+ # 4, 4
1876
+ # 5, 5
1877
+
1878
+ # print(f"{chq = }")
1879
+ # print(f"{chqmin = }")
1880
+
1881
+ self.file_output_mch = open(os.path.join(self.loc, f"{self.sname}_mch-out.dat"), "a+")
1882
+ self.file_output_mages = open(os.path.join(self.loc, f"{self.sname}_mages-out.dat"), "a+")
1883
+ if kk == 0 and nchini == 1:
1884
+ self.file_output_agesd = open(os.path.join(self.loc, f"{self.sname}_ages-sd.samp"), "a+")
1885
+
1886
+ if self.ncyc == self.nwcy or nchini >= self.nrun:
1887
+ if self.ncyc == nchini:
1888
+ for i in range(1, self.ncyc + 1):
1889
+ if chq[i] < chqmin:
1890
+ chqmin = chq[i]
1891
+ for i in range(1, self.ncyc + 1):
1892
+
1893
+ kcyc = nchini - self.ncyc + i
1894
+
1895
+ print(f"{chq[i] = }, {chqmin = }")
1896
+
1897
+ if chq[i] < chqmin * 1.5:
1898
+ mcyc += 1
1899
+ n1 = 0
1900
+
1901
+ for j in range(self.nmaxo[i]):
1902
+ line = f"{self.tto[i - 1, 0, j]}\t{self.tto[i - 1, 1, j]}"
1903
+ self.file_output_mch.writelines(line + "\n")
1904
+
1905
+ continue
1906
+
1907
+ for j in range(self.ni):
1908
+ line = f"{self.ageo[i - 1, 0, j]}\t{self.ageo[i - 1, 1, j]}"
1909
+ self.file_output_mages.writelines(line + "\n")
1910
+ line = f"{self.ageo[i - 1, 0, j + 1]}\t{self.ageo[i - 1, 1, j]}"
1911
+ self.file_output_mages.writelines(line + "\n")
1912
+
1913
+ line = f"& cycle # {kcyc}, chisq = {chq[i] * self.ni}, e = {self.e}"
1914
+ self.file_output_mages.writelines(line + "\n")
1915
+ line = f"& cycle # {kcyc}, chisq = {chq[i] * self.ni}, e = {self.e}"
1916
+ self.file_output_mch.writelines(line + "\n")
1917
+ print(line)
1918
+
1919
+ continue
1920
+
1921
+ self.ncyc = 1
1922
+ else:
1923
+ self.ncyc += 1
1924
+
1925
+ self.file_output_mch.close()
1926
+ self.file_output_mages.close()
1927
+ self.file_output_agesd.close()
1928
+
1929
+ # if nchini != self.nrun:
1930
+ # # goto 34
1931
+ # pass # 被注释了
1932
+
1933
+ print(f"{mcyc = }, {nchini = }")
1934
+
1935
+ if mcyc < self.nrun and nchini < self.maxrun:
1936
+ # nrun = 5; maxrun = 15
1937
+ # goto 34
1938
+ continue
1939
+ else:
1940
+ nchini = 0
1941
+ ne += 1
1942
+ if ne > self.nemax:
1943
+ stop_main = True
1944
+ break # goto 1001
1945
+ break # goto 1000
1946
+
1947
+ if stop_main:
1948
+ break
1949
+
1950
+ return self.ageo, self.tto
1951
+
1952
+ def lab(self, r39, d0, e, vc, telab, tilab, lc, xmat, ni, nst, nn):
1953
+ # r39, d0, e, vc, telab, tilab, lc, xmat, ni, nst, nn
1954
+
1955
+ print(f"\n== Run lab ==\n")
1956
+ print(f"{r39 = }")
1957
+ print(f"{d0 = }")
1958
+ print(f"{e = }")
1959
+ print(f"{vc = }")
1960
+ print(f"{telab = }")
1961
+ print(f"{tilab = }")
1962
+ print(f"{lc = }")
1963
+ # print(f"{xmat = }")
1964
+ print(f"{ni = }")
1965
+ print(f"{nst = }")
1966
+ print(f"{nn = }")
1967
+
1968
+ # 3d array: xmat
1969
+ # 1d array: lc, zita, r39, tilab, telab, d0, vc
1970
+
1971
+ # lab()
1972
+ pi = 3.14159265359
1973
+ imp = 2
1974
+ b = 8
1975
+ ns = 200
1976
+ r = 1.987e-3
1977
+ nd = 10
1978
+ zita = np.zeros(ns + 1, np.float64)
1979
+
1980
+ nsq = 2
1981
+ nsq1 = 1
1982
+ for i in range(nn):
1983
+ an2 = (lc[i] * pi) ** 2
1984
+ xmat[0, ni + 1, i] = b / an2
1985
+
1986
+ an2 = an2
1987
+
1988
+ if i >= 120:
1989
+ if (i - 120) % 20 == 0:
1990
+ nsq *= 2
1991
+ nsq2 = int(nsq / imp)
1992
+ for mi in range(1, nsq1):
1993
+ an = ((lc[i] - mi * imp) * pi) ** 2
1994
+ xmat[0, ni + 1, i] += b / an * (nsq1 - mi) / nsq1
1995
+ if i == nn - 1:
1996
+ # go to 60
1997
+ continue
1998
+ for mi in range(1, nsq2):
1999
+ an = ((lc[i] + mi * imp) * pi) ** 2
2000
+ xmat[0, ni + 1, i] += b / an * (nsq2 - mi) / nsq2
2001
+ nsq1 = nsq2
2002
+
2003
+ for k in range(nst):
2004
+ for nt in range(1, ni + 1):
2005
+ if k == 0:
2006
+ r39[nt] = 0
2007
+ zita[nt] = zita[nt - 1] + d0[k] * tilab[nt - 1] * np.exp(-e / (r * telab[nt - 1]))
2008
+ nsq = 2
2009
+ nsq1 = 1
2010
+ for j in range(nn):
2011
+ an2 = (lc[j] * pi) ** 2
2012
+ if an2 * zita[nt] > 60:
2013
+ for jx in range(j, nn): # 注意这里的索引
2014
+ xmat[k, nt, jx] = xmat[0, ni + 1, jx]
2015
+ # go to 72
2016
+ break
2017
+ else:
2018
+ xmat[k, nt, j] = xmat[0, ni + 1, j] - b * np.exp(-an2 * zita[nt]) / an2
2019
+
2020
+ if j >= 120:
2021
+ if (j - 120) % 20 == 0:
2022
+ nsq *= 2
2023
+ nsq2 = int(nsq / imp)
2024
+ for mi in range(1, nsq1):
2025
+ an = ((lc[j] - mi * imp) * pi) ** 2
2026
+ xmat[k, nt, j] -= b * np.exp(-an * zita[nt]) / an * (nsq1 - mi) / nsq1
2027
+ if j == nn - 1:
2028
+ continue
2029
+ for mi in range(1, nsq2):
2030
+ an = ((lc[j] + mi * imp) * pi) ** 2
2031
+ xmat[k, nt, j] -= b * np.exp(-an * zita[nt]) / an * (nsq2 - mi) / nsq2
2032
+
2033
+ # print(f"\n{j = }")
2034
+ # print(f"{an = }")
2035
+ # print(f"{zita[nt] = }")
2036
+ # print(f"{nsq1 = }")
2037
+ # print(f"{nsq2 = }")
2038
+ # print(f"{imp = }")
2039
+ # print(f"{lc[j] = }")
2040
+ # print(f"{xmat[k, nt, j] = }")
2041
+ # iiii = 1
2042
+ # print(f"{k = }, {nt = }, {j = }")
2043
+ # print(f"{xmat[k, nt, j] - xmat[k, nt-1, j] = }")
2044
+
2045
+ nsq1 = nsq2
2046
+
2047
+ # _ = np.square(np.array(range(1, 80000+1, imp)) * pi)
2048
+ # _ = np.where(zita[nt] * _ > 100, (b * vc[k]) / _, (b * vc[k]) / _ * (1 - np.exp(-zita[nt] * _)))
2049
+ # r39[nt] = np.sum(_) + r39[nt]
2050
+
2051
+ for k1 in range(1, 80000 + 1, imp):
2052
+ an2 = (k1 * pi) ** 2
2053
+ if zita[nt] * an2 > 100:
2054
+ ab = 0
2055
+ else:
2056
+ ab = np.exp(-zita[nt] * an2)
2057
+
2058
+ # print(f"{ab = }")
2059
+ # print(f"{b = }")
2060
+ # print(f"{an2 = }")
2061
+ # print(f"{vc[k] = }")
2062
+
2063
+ r39[nt] += (b * vc[k]) / an2 * (1 - ab)
2064
+
2065
+ # print(f"{r39[nt] = }")
2066
+
2067
+ continue
2068
+ continue
2069
+ # end loop
2070
+
2071
+ # print(f"\n== Return lab ==\n")
2072
+ # print(f"{r39 = }")
2073
+ # print(f"{d0 = }")
2074
+ # print(f"{e = }")
2075
+ # print(f"{vc = }")
2076
+ # print(f"{telab = }")
2077
+ # print(f"{tilab = }")
2078
+ # print(f"{lc = }")
2079
+ # # print(f"{xmat = }")
2080
+ # print(f"{ni = }")
2081
+ # print(f"{nst = }")
2082
+ # print(f"{nn = }")
2083
+
2084
+ return r39, d0, e, vc, telab, tilab, lc, xmat, ni, nst, nn
2085
+
2086
+ def agesamp(self, r39, ys, wt, ni, ne, ya, xs):
2087
+
2088
+ # print(f"\n== Run agesamp ==\n")
2089
+ # print(f"{r39 = }")
2090
+ # # print(f"{wt = }")
2091
+ # # print(f"{self.sig = }")
2092
+ # print(f"{ys = }")
2093
+ # print(f"{ni = }") # ni = 42 for 12h
2094
+ # print(f"{ya = }")
2095
+ # print(f"{xs = }")
2096
+
2097
+ self.file_output_agesd = open(os.path.join(self.loc, f"{self.sname}_ages-sd.samp"), "a+")
2098
+
2099
+ for j in range(1, ni + 1):
2100
+ if ne == 1:
2101
+ line = f"{xs[j - 1] * 100} {ya[j] + self.sig[j - 1]}"
2102
+ self.file_output_agesd.writelines(line + "\n")
2103
+ line = f"{xs[j] * 100} {ya[j] + self.sig[j - 1]}"
2104
+ self.file_output_agesd.writelines(line + "\n")
2105
+ # xs[j] /= 100
2106
+ if ya[j] < 0:
2107
+ ya[j] = 0
2108
+
2109
+ if ne == 1:
2110
+ for k in range(1, ni):
2111
+ line = f"{xs[ni - k + 1] * 100} {ya[ni - k + 1] - self.sig[ni - k]}"
2112
+ self.file_output_agesd.writelines(line + "\n")
2113
+ line = f"{xs[ni - k] * 100} {ya[ni - k + 1] - self.sig[ni - k]}"
2114
+ self.file_output_agesd.writelines(line + "\n")
2115
+ line = f"{xs[0]} {ya[1] + self.sig[0]}"
2116
+ self.file_output_agesd.writelines(line + "\n")
2117
+
2118
+ self.file_output_agesd.close()
2119
+
2120
+ ya[0] = ya[1]
2121
+ xs[ni + 1] = 1
2122
+ ys[ni + 1] = ys[ni]
2123
+ jold = 1
2124
+ for k in range(1, ni + 1):
2125
+ ys[k] = 0
2126
+ # print(f"{jold = }, {r39[k] = }")
2127
+ for j in range(jold, ni + 2):
2128
+ # print(f"{xs[j - 1] = }, {r39[k] = }, {xs[j] = }")
2129
+ if xs[j - 1] < r39[k] and xs[j] > r39[k]:
2130
+ if jold == j:
2131
+ ys[k] = ya[j]
2132
+ else:
2133
+ for jm in range(jold + 1, j):
2134
+ ys[k] = ya[jm] * (xs[jm] - xs[jm - 1]) + ys[k]
2135
+ ys[k] += ya[jold] * (xs[jold] - r39[k - 1]) + ya[j] * (r39[k] - xs[j - 1])
2136
+ ys[k] /= (r39[k] - r39[k - 1])
2137
+ jold = j
2138
+ # go to 30
2139
+ break
2140
+ # end if
2141
+ # print(f"{ys[k] = }")
2142
+ continue
2143
+
2144
+ # print(f"\n== Return agesamp ==\n")
2145
+ # print(f"{ys = }")
2146
+ # print(f"{r39 = }")
2147
+ # print(f"{wt = }")
2148
+ # print(f"{ni = }")
2149
+ # print(f"{ne = }")
2150
+ # print(f"{ya = }")
2151
+ # print(f"{xs = }")
2152
+
2153
+ return ys
2154
+
2155
+ def chebft(self, a, b, c, n, func, tt, _np):
2156
+
2157
+ # print(f"\n== Return chebft ==\n")
2158
+ # print(f"{a = }")
2159
+ # print(f"{b = }")
2160
+ # print(f"{c = }")
2161
+ # print(f"{n = }")
2162
+ # print(f"{tt = }")
2163
+
2164
+ nmax = 100
2165
+ pi = 3.141592653589793
2166
+ f = np.zeros(nmax, dtype=np.float64)
2167
+
2168
+ # c[n], f[namx], tt[2, 0:np]
2169
+
2170
+ bma = 0.5 * (b - a)
2171
+ bpa = 0.5 * (b + a)
2172
+
2173
+ for k in range(n):
2174
+ y = np.cos(pi * (k + 0.5) / n)
2175
+ f[k] = func(tt, _np, y * bma + bpa)
2176
+
2177
+ fac = 2 / n
2178
+ for j in range(n):
2179
+ sum = 0
2180
+ for k in range(n):
2181
+ sum += f[k] * np.cos(pi * j * (k + 0.5) / n)
2182
+ c[j] = fac * sum
2183
+
2184
+ # print(f"\n== Return chebft ==\n")
2185
+ # print(f"{c = }")
2186
+
2187
+ return c
2188
+
2189
+ def slope(self, a, n, x):
2190
+ a = a[:2, :n + 1]
2191
+ res = 0
2192
+ for j in range(2, n + 1):
2193
+ if a[0, j] < x and a[0, j - 1] > x:
2194
+ res = np.sqrt(abs((a[1, j - 1] - a[1, j]) / (a[0, j - 1] - a[0, j])))
2195
+ break
2196
+
2197
+ return res
2198
+
2199
+ def ranchist(self, c, c0, mc, idem, tini):
2200
+ # c, c0, mfit, idem, tt[1, 1]
2201
+
2202
+ # print(f"\n== Run ranchist ==")
2203
+ # print(f"{c0 = }")
2204
+ # print(f"{tini = }")
2205
+ # fsum2 = 0
2206
+
2207
+ # print(f"{mc = }")
2208
+
2209
+ for i in range(mc):
2210
+ perc = 5 * self.ran1.ran1() * (0.6 - self.ran1.ran1())
2211
+ c[i] = c0[i] + perc
2212
+ tini = (0.5 - self.ran1.ran1()) * 200 + 400
2213
+
2214
+ # print(f"\n== Return ranchist ==")
2215
+ # print(f"{c = }")
2216
+ # print(f"{tini = }")
2217
+
2218
+ return c, tini
2219
+
2220
+ def mrqmin_agemon(self, x, y, sig, ndata, a, ma, lista, mfit, covar, alpha, nca,
2221
+ chisq, alamda, tt, xmat, lc, vc, d0, e, nst, nn):
2222
+ # def mrqmin(self,r39,ys,wt,ni,c,nc,lista,mfit,covar,alpha,nc,chisq,alamda,tt,xmat,lc,vc,d0,E,nst,nn1):
2223
+ # print(f"\n======================================")
2224
+ # print(f"Run mrqmin_agemon")
2225
+ # print(f"======================================")
2226
+ #
2227
+ # print(f"{x = }")
2228
+ # print(f"{y = }")
2229
+ # print(f"{sig = }")
2230
+ # print(f"{ndata = }")
2231
+ # print(f"{a = }")
2232
+ # print(f"{ma = }")
2233
+ # print(f"{lista = }")
2234
+ # print(f"{mfit = }")
2235
+ # # print(f"{covar = }")
2236
+ # # print(f"{alpha = }")
2237
+ # print(f"{nca = }")
2238
+ # print(f"{chisq = }")
2239
+ # print(f"{alamda = }")
2240
+ # print(f"{tt = }")
2241
+ # print(f"{xmat = }")
2242
+
2243
+ # print(f"in mrqmin {alamda = }, {chisq = }, {self.ochisq = }")
2244
+
2245
+ mmax = 100
2246
+ ntst = 1001
2247
+ nd = 10
2248
+ ns = 200
2249
+ covaux = np.zeros([mmax, mmax], dtype=np.float64)
2250
+ daux = np.zeros(mmax, dtype=np.float64)
2251
+
2252
+ if alamda < 0:
2253
+ kk = mfit
2254
+ for j in range(ma):
2255
+ ihit = 0
2256
+ for k in range(mfit):
2257
+ if lista[k] == j:
2258
+ ihit += 1
2259
+ if ihit == 0:
2260
+ lista[kk] = j
2261
+ kk += 1
2262
+ elif ihit > 1:
2263
+ pass
2264
+ if kk != ma:
2265
+ pass
2266
+ # call mrqcof
2267
+ chisq, alpha, self.beta = \
2268
+ self.mrqcof_agemon(x, y, sig, ndata, a, ma, lista, mfit, alpha,
2269
+ self.beta, nca, chisq, tt, xmat, lc, vc, d0, e, nst, nn, alamda)
2270
+ # print(f"xxxxxxxxxxxxxxxxxx {self.beta = }")
2271
+ alamda = 0.001
2272
+ self.ochisq = chisq
2273
+ for j in range(ma):
2274
+ self.atry[j] = a[j]
2275
+ # end if
2276
+
2277
+ # print(f"in mrqmin 001 {chisq = }, {self.ochisq = }")
2278
+
2279
+ for j in range(mfit):
2280
+ for k in range(mfit):
2281
+ covar[j, k] = alpha[j, k]
2282
+ covar[j, j] = alpha[j, j] * (1 + alamda)
2283
+ self.da[j] = self.beta[j]
2284
+ ng = 1
2285
+ # call gaussj(covar, mfit, nca, da, ng, 1)
2286
+ # print(f"call gaussj")
2287
+ # print(f"xxxxxxxxxx before gaussj {self.da[0] = }")
2288
+ # print(f"xxxxxxxxxx before gaussj {covar[0] = }")
2289
+
2290
+ # with open("c:\\Users\\Young\\Desktop\\newdata.txt") as f:
2291
+ # line = f.readline()
2292
+ # _covar = [float(i) for i in line.split(",")]
2293
+ # covar = np.array(_covar).reshape([100, 100])
2294
+ # line = f.readline()
2295
+ # _da = [float(i) for i in line.split(",")]
2296
+ # self.da = np.array(_da)
2297
+
2298
+
2299
+ ng = self.gaussj(covar, mfit, self.da, ng) ########### covar 这里跟 C++不对
2300
+ # print(f"xxxxxxxxxx after gaussj {self.da[0] = }")
2301
+ # print(f"xxxxxxxxxx before gaussj {covar[0] = }")
2302
+ # print(f"end gaussj")
2303
+ # print(f"{ng = }")
2304
+ if ng == -1:
2305
+ raise ValueError('Singular Matrix')
2306
+ if alamda == 0:
2307
+ # call covsrt(covar, nca, ma, lista, mfit)
2308
+ covar = self.covsrt(covar, ma, lista, mfit)
2309
+ return x, y, sig, ndata, a, ma, lista, mfit, covar, alpha, nca, chisq, alamda, tt, xmat, lc, vc, d0, e, nst, nn
2310
+
2311
+ # print(f"xxxxxxxxxx before mrqcof {a[0] = }")
2312
+ # print(f"xxxxxxxxxx before mrqcof {self.da[0] = }")
2313
+ # print(f"xxxxxxxxxx before mrqcof {self.beta[0] = }")
2314
+
2315
+ for j in range(mfit):
2316
+ if alamda >= 1e20:
2317
+ self.da[j] = 0
2318
+ # print(f"{a[int(lista[j])] = }, {self.da[j] = }")
2319
+ self.atry[int(lista[j])] = a[int(lista[j])] + self.da[j]
2320
+
2321
+ # print(f"in mrqmin 002 {chisq = }, {self.ochisq = }")
2322
+
2323
+ # call mrqcof(x,y,sig,ndata,atry,ma,lista,mfit,covar,da,nca,chisq,tt,xmat,lc,vc,d0,e,nst,nn,alamda)
2324
+ # print(f"xxxxxxxxxx before mrqcof {self.atry[0] = }")
2325
+ chisq, covar, self.da = \
2326
+ self.mrqcof_agemon(x, y, sig, ndata, self.atry, ma, lista, mfit, covar,
2327
+ self.da, nca, chisq, tt, xmat, lc, vc, d0, e, nst, nn, alamda)
2328
+ # print(f"xxxxxxxxxx after mrqcof {self.atry[0] = }")
2329
+
2330
+ # print(f"xxxxxxxxxx after mrqcof {self.atry = }")
2331
+
2332
+ # print(f"in mrqmin 003 {chisq = }, {self.ochisq = }")
2333
+
2334
+ # print(f"{self.ochisq = }")
2335
+ if chisq <= self.ochisq:
2336
+ for j in range(mfit):
2337
+ for k in range(mfit):
2338
+ covaux[j, k] = covar[j, k]
2339
+ daux[j] = self.da[j]
2340
+ # call gaussj(covaux,mfit,nca,daux,ng,1)
2341
+ ng = self.gaussj(covaux, mfit, daux, ng)
2342
+ if ng == -1:
2343
+ alamda = 10 * alamda
2344
+ chisq = self.ochisq
2345
+ ng = 1
2346
+ return x, y, sig, ndata, a, ma, lista, mfit, covar, alpha, nca, chisq, alamda, tt, xmat, lc, vc, d0, e, nst, nn
2347
+ alamda = 0.1 * alamda
2348
+ self.ochisq = chisq
2349
+ for j in range(mfit):
2350
+ for k in range(mfit):
2351
+ alpha[j, k] = covar[j, k]
2352
+ self.beta[j] = self.da[j]
2353
+ a[int(lista[j])] = self.atry[int(lista[j])]
2354
+ else:
2355
+ alamda = 10 * alamda
2356
+ chisq = self.ochisq
2357
+ # end if
2358
+
2359
+ # print(f"\n======================================")
2360
+ # print(f"Return mrqmin_agemon")
2361
+ # print(f"======================================")
2362
+ #
2363
+ # print(f"{alamda = }")
2364
+ # print(f"{chisq = }")
2365
+ # print(f"{ng = }")
2366
+ # print(f"{covar = }")
2367
+ # print(f"{alpha = }")
2368
+ # print(f"{self.beta = }")
2369
+
2370
+ return x, y, sig, ndata, a, ma, lista, mfit, covar, alpha, nca, chisq, alamda, tt, xmat, lc, vc, d0, e, nst, nn
2371
+
2372
+ def mrqcof_agemon(self, x, y, sig, ndata, a, ma, lista, mfit, alpha,
2373
+ beta, nalp, chisq, tt, xmat, lc, vc, d0, e, nst, nn, al):
2374
+
2375
+ # print(f"\n======================================")
2376
+ # print(f"Run mrqcof")
2377
+ # print(f"======================================")
2378
+ #
2379
+ # print(f"{x = }")
2380
+ # print(f"{y = }")
2381
+ # print(f"{sig = }")
2382
+ # print(f"{ndata = }")
2383
+ # print(f"{a = }")
2384
+ # print(f"{ma = }")
2385
+ # print(f"{lista = }")
2386
+ # print(f"{mfit = }")
2387
+ # print(f"{alpha = }")
2388
+ # print(f"{beta = }")
2389
+
2390
+ mmax = 100
2391
+ ntst = 1001
2392
+ perc = 0.01
2393
+ xlambd = 0.0005543
2394
+ nc = 100
2395
+ mxi = 500
2396
+ nd = 10
2397
+ ns = 200
2398
+
2399
+ t0 = tt[0, 1]
2400
+ c40 = 1 - np.exp(-xlambd * t0)
2401
+
2402
+ for j in range(mfit):
2403
+ for k in range(j + 1):
2404
+ alpha[j, k] = 0
2405
+ beta[j] = 0
2406
+
2407
+ xi = np.zeros([2 * nc + 1, nd, mxi], dtype=np.float64)
2408
+
2409
+ # print(f"before zita {tt[0] = }")
2410
+ # print(f"xxxxxxxxxx before zita {a[0] = }")
2411
+ a, xi = self.zita_agemon(a, ma, lista, mfit, lc, xi, t0, d0, e, tt, nst, nn, perc, al)
2412
+ # print(f"xxxxxxxxxx before zita {a[0] = }")
2413
+ # print(f"end zita")
2414
+ # print(f"after zita {tt[0] = }")
2415
+
2416
+ if tt[1, ntst] == -1:
2417
+ tt[1, ntst] = 0
2418
+ chisq = chisq * 2
2419
+ return
2420
+ # end if
2421
+ chisq = 0
2422
+ for i in range(1, ndata + 1):
2423
+ ymod = 0
2424
+ dyda = np.zeros(mfit, dtype=np.float64)
2425
+ # ymod, dyda = call age(i,a,ymod,dyda,ma,lista,mfit,vc,xmat,x,xi,c40,nn,nst,ndata,perc,al)
2426
+ # print(f"in mrqcof_agemon funcs, {i = }, {al = }")
2427
+ ymod, dyda = self.age(i, a, ymod, dyda, ma, lista, mfit, vc, xmat, x, xi, c40, nn, nst, ndata, perc, al)
2428
+ # print(f"{ymod = }")
2429
+ sig2i = 1 / (sig[i - 1] * sig[i - 1])
2430
+
2431
+ # print(f"{dyda = }")
2432
+ # print(f"{sig2i = }") # 检查这里是不是对的 alpha输入是零,输出有误差,导致gaussj计算不对
2433
+
2434
+ dy = y[i] - ymod
2435
+ for j in range(mfit):
2436
+ wt = dyda[lista[j]] * sig2i
2437
+ for k in range(j + 1):
2438
+ alpha[j, k] = alpha[j, k] + wt * dyda[lista[k]]
2439
+ beta[j] = beta[j] + dy * wt
2440
+ # print(f"{dy = }")
2441
+ # print(f"{sig2i = }")
2442
+ chisq = chisq + dy * dy * sig2i
2443
+ # print(f"{i = }, {dy = }, {sig2i = }, {ymod = }, {y[i] = }")
2444
+ # print(f"mrqcof {chisq = }")
2445
+ for j in range(1, mfit):
2446
+ for k in range(j):
2447
+ alpha[k, j] = alpha[j, k]
2448
+
2449
+ # print(f"\n======================================")
2450
+ # print(f"Return mrqcof")
2451
+ # print(f"======================================")
2452
+ #
2453
+ # print(f"{x = }")
2454
+ # print(f"{y = }")
2455
+ # print(f"{sig = }")
2456
+ # print(f"{ndata = }")
2457
+ # print(f"{a = }")
2458
+ # print(f"{ma = }")
2459
+ # print(f"{lista = }")
2460
+ # print(f"{mfit = }")
2461
+ # # print(f"{alpha = }")
2462
+ # print(f"{beta = }")
2463
+
2464
+ return chisq, alpha, beta
2465
+
2466
+ def zita_agemon(self, c, mc, lista, mfit, lc, xi, t0, d0, e, tt, nst, nn, perc, al):
2467
+
2468
+ # print("\n== Run zita_agemon ==\n")
2469
+ # print(f"{len(c) = }")
2470
+ # print(f"{c = }")
2471
+ # print(f"{mc = }")
2472
+ # print(f"{lista = }")
2473
+ # print(f"{mfit = }")
2474
+ # print(f"{lc = }")
2475
+ # print(f"{xi = }")
2476
+ # print(f"{t0 = }")
2477
+ # print(f"{d0 = }")
2478
+ # print(f"{e = }")
2479
+ # print(f"{tt = }")
2480
+ # print(f"{nst = }")
2481
+ # print(f"{nn = }")
2482
+ # print(f"{perc = }")
2483
+ # print(f"{al = }")
2484
+
2485
+ def chebev(a, b, c, m, x):
2486
+ # a,b 是定义函数的定义域
2487
+ # c 是切比雪夫多项式展开系数数组
2488
+ # m 是多项式阶数
2489
+ # x 是需要计算的点
2490
+ # 切比雪夫多项式(Chebyshev polynomials)求值
2491
+ # if (x - a) * (x - b) > 0:
2492
+ # pass
2493
+
2494
+ # print(f"{a = }, {b = }, {m = }, {x = }")
2495
+ # print(f"{c = }")
2496
+
2497
+ d = 0
2498
+ dd = 0
2499
+ y = (2 * x - a - b) / (b - a) # 将 x 映射到切比雪夫多项式的标准定义域 [-1, 1] 上
2500
+ y2 = 2 * y
2501
+ for j in range(m, 1, -1):
2502
+ sv = d
2503
+ d = y2 * d - dd + c[j - 1]
2504
+ dd = sv
2505
+
2506
+ return y * d - dd + 0.5 * c[0]
2507
+
2508
+ def sched(a, t0, c, m, tt, i):
2509
+
2510
+ # print("\n== Run sched ==\n")
2511
+ # print(f"{a = }")
2512
+ # print(f"{t0 = }")
2513
+ # print(f"{c = }")
2514
+ # print(f"{m = }")
2515
+ # print(f"{tt = }")
2516
+ # print(f"{i = }")
2517
+
2518
+ step = 4
2519
+ nt = 10000
2520
+ ntst = 1001
2521
+ tmax = 100
2522
+ i = 1
2523
+ slp = (chebev(a, t0, c, m, t0)) ** 2
2524
+ dt = t0 / nt
2525
+ sum = slp * dt / 2
2526
+ for j in range(1, nt + 1):
2527
+ xj = t0 - j * dt
2528
+ if j == nt:
2529
+ xj = 0
2530
+ slp = (chebev(a, t0, c, m, xj)) ** 2
2531
+ sum += slp * dt / 2
2532
+
2533
+ # print(f"{j = }, {sum = }")
2534
+
2535
+ if sum >= step or xj == 0:
2536
+ tt[1, i + 1] = tt[1, i] - sum
2537
+ tt[0, i + 1] = xj
2538
+ sum = 0
2539
+
2540
+ # print(f"{i = }, {tt[1, i + 1] = }, {tt[0, i + 1] = }, {j = }")
2541
+
2542
+ i += 1
2543
+ if tt[1, i] <= tmax:
2544
+ tt[1, i] = 0
2545
+ tt[0, i] = 0
2546
+ break
2547
+ sum += slp * dt / 2
2548
+
2549
+ # step = 4
2550
+ # nt = 10000
2551
+ # ntst = 1001
2552
+ # tmax = 100
2553
+ # i = 1
2554
+ # slp = (chebev(a, t0, c, m, t0)) ** 2
2555
+ # dt = t0 / nt
2556
+ # _sum = slp * dt / 2
2557
+ #
2558
+ # j = np.linspace(1, nt, nt, dtype=int)
2559
+ # xj = t0 - j * dt
2560
+ # xj[nt] = 0
2561
+ # slp = (chebev(a, t0, c, m, xj)) ** 2
2562
+ # _sum = _sum + sum(slp * dt / 2)
2563
+ #
2564
+ # for j in range(1, nt + 1):
2565
+ # xj = t0 - j * dt
2566
+ # if j == nt:
2567
+ # xj = 0
2568
+ # slp = (chebev(a, t0, c, m, xj)) ** 2
2569
+ # sum += slp * dt / 2
2570
+ # if sum >= step or xj == 0:
2571
+ # tt[1, i + 1] = tt[1, i] - sum
2572
+ # tt[0, i + 1] = xj
2573
+ # sum = 0
2574
+ # print(f"{i = }, {tt[1, i + 1] = }, {tt[0, i + 1] = }, {j = }")
2575
+ # i += 1
2576
+ # if tt[1, i] <= tmax:
2577
+ # tt[1, i] = 0
2578
+ # tt[0, i] = 0
2579
+ # break
2580
+ # sum += slp * dt / 2
2581
+
2582
+ # step = 4
2583
+ # nt = 10000
2584
+ # tmax = 100
2585
+ #
2586
+ # slp = chebev(a, t0, c, m, t0) ** 2
2587
+ # dt = t0 / nt
2588
+ # sum_arr = np.zeros(nt + 1)
2589
+ # xj_arr = t0 - np.arange(nt + 1) * dt
2590
+ # xj_arr[-1] = 0 # ensure the last element is exactly zero
2591
+ #
2592
+ # slp_arr = chebev(a, t0, c, m, xj_arr) ** 2
2593
+ # sum_arr[1:] = np.cumsum(slp_arr[:-1] + slp_arr[1:]) * dt / 2
2594
+ # sum_arr[0] = slp * dt / 2
2595
+ #
2596
+ # # Use boolean mask to find the steps
2597
+ # mask = sum_arr >= step
2598
+ # mask[-1] = True # make sure the last element is considered
2599
+ #
2600
+ # indices = np.where(mask)[0]
2601
+ #
2602
+ # for idx in indices:
2603
+ # if idx == 0:
2604
+ # continue
2605
+ # sum_val = sum_arr[idx]
2606
+ # xj = xj_arr[idx]
2607
+ # tt[1, i + 1] = tt[1, i] - sum_val
2608
+ # tt[0, i + 1] = xj
2609
+ # sum_arr[idx:] -= sum_val
2610
+ # print(f"{i = }, {tt[1, i + 1] = }, {tt[0, i + 1] = }")
2611
+ # i += 1
2612
+ # if tt[1, i] <= tmax:
2613
+ # tt[1, i] = 0
2614
+ # tt[0, i] = 0
2615
+ # break
2616
+
2617
+ # print("\n== Return sched ==\n")
2618
+ # print(f"{i = }")
2619
+
2620
+ return tt, i
2621
+
2622
+ def sched2(a, t0, c, m, tt, i):
2623
+ nt = 10000
2624
+ tmax = 100
2625
+ i = 1
2626
+ slp = (chebev(a, t0, c, m, t0)) ** 2
2627
+ dt = t0 / nt
2628
+ sum = slp * dt / 2
2629
+ for j in range(1, nt + 1):
2630
+ xj = t0 - j * dt
2631
+ if j == nt:
2632
+ xj = 0
2633
+ slp = (chebev(a, t0, c, m, xj)) ** 2
2634
+ sum += slp * dt / 2
2635
+ if xj == tt[0, i + 1]:
2636
+ tt[1, i + 1] = tt[1, i] - sum
2637
+ sum = 0
2638
+ i += 1
2639
+ if tt[1, i] <= tmax:
2640
+ tt[1, i] = 0
2641
+ tt[0, i] = 0
2642
+ break
2643
+ sum += slp * dt / 2
2644
+ return tt, i
2645
+
2646
+ # def geosec_new(imax,d0,e,tt,xi,nn,lc,nst,j1):
2647
+ #
2648
+ # start_time = time.time()
2649
+ #
2650
+ # # print("\n== Run geosec ==\n")
2651
+ # # print(f"{imax = }")
2652
+ # # print(f"{d0 = }")
2653
+ # # print(f"{e = }")
2654
+ # # print(f"{tt = }")
2655
+ # # # print(f"{xi = }")
2656
+ # # print(f"{nn = }")
2657
+ # # print(f"{lc = }")
2658
+ # # print(f"{nst = }")
2659
+ # # print(f"{j1 = }")
2660
+ #
2661
+ # xlambd = 5.543e-4
2662
+ # r = 1.987e-3
2663
+ # max = 1002
2664
+ # pi = 3.14159265359
2665
+ # nc = 100
2666
+ #
2667
+ # d = np.zeros(max, dtype=np.float64)
2668
+ # dzita = np.zeros(max, dtype=np.float64)
2669
+ # nend = imax - 1
2670
+ #
2671
+ # # print(f"{max = }")
2672
+ # # print(f"{nend = }")
2673
+ #
2674
+ # dzita[nend+1] = 0
2675
+ #
2676
+ # # print(f"循环次数 = {nst * (int(nend) + nend + nn * nend)}")
2677
+ #
2678
+ # avtemp = (tt[1, :-1] + tt[1, 1:]) / 2 + 273
2679
+ # d = np.zeros(max, dtype=np.float64)
2680
+ # d[1:] = np.where(e / r / avtemp > 80, np.exp(-e / r / avtemp), 0)
2681
+ # d = d0.reshape(-1, 1) @ avtemp.reshape(1, -1)
2682
+ #
2683
+ # xal = tt[0, 1:-1] - tt[0, 2:]
2684
+ #
2685
+ # for k in range(nst):
2686
+ #
2687
+ # # for j in range(int(nend)):
2688
+ # # avtemp = (tt[1,j+2]+tt[1,j+1])/2 + 273
2689
+ # # if e / r / avtemp > 80:
2690
+ # # d[j + 1] = 0
2691
+ # # # go to 10
2692
+ # # continue
2693
+ # # d[j + 1] = d0[k] * np.exp(-e / r / avtemp)
2694
+ #
2695
+ # # dzita[nend+1] = 0
2696
+ #
2697
+ # for j in range(nend, 0, -1):
2698
+ #
2699
+ # dzita[j] = dzita[j + 1] + abs(tt[0, j+1] - tt[0, j]) * d[k, j]
2700
+ #
2701
+ # for mi in range(nn):
2702
+ # xlogm = 2 * np.log(lc[mi] * pi)
2703
+ # # sum = 0
2704
+ #
2705
+ # uplus = (lc[mi] * pi) ** 2 * dzita[2:] + xlambd * (tt[0, 1] - tt[0, 2:])
2706
+ #
2707
+ # al = (lc[mi] * pi) ** 2 * d[k, 1:] - xlambd
2708
+ # #
2709
+ # # print(uplus.shape)
2710
+ # # print(xal.shape)
2711
+ #
2712
+ # camal = np.where(abs(xal) > 30, 1, np.where(abs(xal) > 0.001, (1 - np.exp(-xal * al)) / al, xal * (1 - xal * al / 2 + xal ** 2 / 6)))
2713
+ #
2714
+ # _sum = sum(d[k, 1:] * np.exp(-uplus) * camal)
2715
+ #
2716
+ #
2717
+ # # for n in range(1, nend + 1):
2718
+ # # if d[n] == 0:
2719
+ # # # go to 40
2720
+ # # continue
2721
+ # # uplus = (lc[mi]*pi)**2*dzita[n+1]+xlambd*(tt[0,1]-tt[0,n+1])
2722
+ # # if uplus - xlogm > 25:
2723
+ # # # go to 40
2724
+ # # continue
2725
+ # # al = (lc[mi]*pi)**2*d[n]-xlambd
2726
+ # # xal = al * (tt[0, n] - tt[0, n + 1])
2727
+ # # if abs(xal) > 30:
2728
+ # # camal = 1 / al
2729
+ # # else:
2730
+ # # if abs(xal) > 0.001:
2731
+ # # camal = (1 - np.exp(-xal)) / al
2732
+ # # else:
2733
+ # # camal = (tt[0,n]-tt[0,n+1])*(1-xal/2+xal**2/6)
2734
+ # # sum += d[n]*np.exp(-uplus)*camal
2735
+ # tzita = dzita[1] * (pi * lc[mi]) ** 2
2736
+ # if tzita < 30:
2737
+ # xfact = np.exp(-tzita)
2738
+ # else:
2739
+ # xfact = 0
2740
+ # xi[j1, k, mi] = _sum * (pi * lc[mi]) ** 2 + xfact
2741
+ # continue
2742
+ #
2743
+ # print(f"geosec 耗时 : {time.time() - start_time} 秒")
2744
+ #
2745
+ # return imax,d0,e,tt,xi,nn,lc,nst,j1
2746
+
2747
+ def geosec(imax, d0, e, tt, xi, nn, lc, nst, j1):
2748
+
2749
+ # print("\n== Run geosec ==\n")
2750
+ # print(f"{imax = }")
2751
+ # print(f"{d0 = }")
2752
+ # print(f"{e = }")
2753
+ # print(f"{tt = }")
2754
+ # print(f"{xi = }")
2755
+ # print(f"{nn = }")
2756
+ # print(f"{lc = }")
2757
+ # print(f"{nst = }")
2758
+ # print(f"{j1 = }")
2759
+
2760
+ # start_time = time.time()
2761
+
2762
+ xlambd = 5.543e-4
2763
+ r = 1.987e-3
2764
+ max = 1002
2765
+ pi = 3.14159265359
2766
+ nc = 100
2767
+
2768
+ d = np.zeros(max + 1, dtype=np.float64)
2769
+ dzita = np.zeros(max + 1, dtype=np.float64)
2770
+ nend = imax - 1
2771
+
2772
+ dzita[nend + 1] = 0
2773
+
2774
+ # print(f"循环次数 = {nst * (int(nend) + nend + nn * nend)}")
2775
+
2776
+ for k in range(nst):
2777
+
2778
+ for j in range(int(nend)):
2779
+ avtemp = (tt[1, j + 2] + tt[1, j + 1]) / 2 + 273
2780
+ if e / r / avtemp > 80:
2781
+ d[j + 1] = 0
2782
+ # go to 10
2783
+ continue
2784
+ d[j + 1] = d0[k] * np.exp(-e / r / avtemp)
2785
+
2786
+ dzita[nend + 1] = 0
2787
+
2788
+ for j in range(nend, 0, -1):
2789
+ dzita[j] = dzita[j + 1] + abs(tt[0, j + 1] - tt[0, j]) * d[j]
2790
+
2791
+ for mi in range(nn):
2792
+ xlogm = 2 * np.log(lc[mi] * pi)
2793
+ sum = 0
2794
+ for n in range(1, nend + 1):
2795
+ if d[n] == 0:
2796
+ # go to 40
2797
+ continue
2798
+ uplus = (lc[mi] * pi) ** 2 * dzita[n + 1] + xlambd * (tt[0, 1] - tt[0, n + 1])
2799
+ if uplus - xlogm > 25:
2800
+ # go to 40
2801
+ continue
2802
+ al = (lc[mi] * pi) ** 2 * d[n] - xlambd
2803
+ xal = al * (tt[0, n] - tt[0, n + 1])
2804
+ if abs(xal) > 30:
2805
+ camal = 1 / al
2806
+ else:
2807
+ if abs(xal) > 0.001:
2808
+ camal = (1 - np.exp(-xal)) / al
2809
+ else:
2810
+ camal = (tt[0, n] - tt[0, n + 1]) * (1 - xal / 2 + xal ** 2 / 6)
2811
+ sum += d[n] * np.exp(-uplus) * camal
2812
+ tzita = dzita[1] * (pi * lc[mi]) ** 2
2813
+ if tzita < 30:
2814
+ xfact = np.exp(-tzita)
2815
+ else:
2816
+ xfact = 0
2817
+ xi[j1, k, mi] = sum * (pi * lc[mi]) ** 2 + xfact
2818
+ continue
2819
+ continue
2820
+
2821
+ # print(f"geosec 耗时 : {time.time() - start_time} 秒")
2822
+
2823
+ # print("\n== Return geosec ==\n")
2824
+ # print(f"{imax = }")
2825
+ # print(f"{d0 = }")
2826
+ # print(f"{e = }")
2827
+ # print(f"{tt = }")
2828
+ # print(f"{xi = }")
2829
+ # print(f"{nn = }")
2830
+ # print(f"{lc = }")
2831
+ # print(f"{nst = }")
2832
+ # print(f"{j1 = }")
2833
+
2834
+ return imax, d0, e, tt, xi, nn, lc, nst, j1
2835
+
2836
+ start_time_1 = time.time()
2837
+
2838
+ ntst = 1001
2839
+ a = 0
2840
+ nc = 100
2841
+ nwcy = 10
2842
+ ns = 200
2843
+
2844
+ n = 0
2845
+ imax = 0
2846
+
2847
+ # print(f"before sched {tt[0] = }")
2848
+ # imax = call sched(a, t0, c, mc, tt, imax)
2849
+ # print("before sched")
2850
+ tt, imax = sched(a, t0, c, mc, tt, imax)
2851
+ # print(f"after sched {tt[0] = }")
2852
+ # print(f"{xi = }")
2853
+ # call geosec(imax, d0, E, tt, xi, nn, lc, nst, n)
2854
+ # print("before geosec")
2855
+ imax, d0, e, tt, xi, nn, lc, nst, n = geosec(imax, d0, e, tt, xi, nn, lc, nst, n)
2856
+
2857
+ if al <= 0:
2858
+ if al > 0:
2859
+ self.nmaxi[self.ncyc] = imax
2860
+ else:
2861
+ self.nmaxo[self.ncyc] = imax
2862
+ for j in range(imax):
2863
+ if al < 0:
2864
+ self.tti[self.ncyc - 1, 0, j] = tt[0, j + 1]
2865
+ self.tti[self.ncyc - 1, 1, j] = tt[1, j + 1]
2866
+ else:
2867
+ self.tto[self.ncyc - 1, 0, j] = tt[0, j + 1]
2868
+ self.tto[self.ncyc - 1, 1, j] = tt[1, j + 1]
2869
+
2870
+ for k in range(mfit):
2871
+ csk = c[lista[k]]
2872
+ dc = perc * abs(c[lista[k]])
2873
+ for js in range(1, 3, 1):
2874
+ n += 1
2875
+ c[lista[k]] += (-1) ** js * dc
2876
+ # call ched2(a,t0,c,mc,tt,imax)
2877
+ # print("before sched")
2878
+ # print(f"before sched2 {tt[0] = }")
2879
+ tt, imax = sched2(a, t0, c, mc, tt, imax)
2880
+ # print(f"after sched2 {tt[0] = }")
2881
+
2882
+ # call geosec(imax,d0,E,tt,xi,nn,lc,nst,n)
2883
+ # print("before geosec")
2884
+ imax, d0, e, tt, xi, nn, lc, nst, n = geosec(imax, d0, e, tt, xi, nn, lc, nst, n)
2885
+ c[lista[k]] = csk
2886
+
2887
+ # print("\n== Return zita_agemon ==\n")
2888
+ # # print(f"{xi = }")
2889
+ # print(f"{c = }")
2890
+
2891
+ print(f"zita 耗时 : {time.time() - start_time_1} 秒")
2892
+ # print(f"{xi[0][0][0] = }")
2893
+
2894
+ # print(f"{c = }")
2895
+ # print(f"{xi = }")
2896
+ # print(f"{tt = }")
2897
+
2898
+ return c, xi
2899
+
2900
+ def gaussj(self, a, n, b, m):
2901
+ # m = b.shape[1]
2902
+
2903
+ nmax = 100
2904
+ ipiv = np.zeros(nmax, dtype=int)
2905
+ indxr = np.zeros(nmax, dtype=int)
2906
+ indxc = np.zeros(nmax, dtype=int)
2907
+
2908
+ # print(f"\n======================================")
2909
+ # print(f"Run gaussj")
2910
+ # print(f"======================================")
2911
+ # print(f"{a = }")
2912
+ # print(f"{n = }")
2913
+ # print(f"{b = }")
2914
+ # print(f"{m = }")
2915
+
2916
+ for j in range(n):
2917
+ ipiv[j] = 0
2918
+
2919
+ for i in range(n):
2920
+ big = 0.0
2921
+ for j in range(n):
2922
+ if ipiv[j] != 1:
2923
+ for k in range(n):
2924
+ if ipiv[k] == 0:
2925
+ if abs(a[j, k]) >= big:
2926
+ big = abs(a[j, k])
2927
+ irow = j
2928
+ icol = k
2929
+ elif ipiv[k] > 1:
2930
+ m = -1
2931
+ return m
2932
+
2933
+ ipiv[icol] += 1
2934
+ if irow != icol:
2935
+ for l in range(n):
2936
+ dum = a[irow, l]
2937
+ a[irow, l] = a[icol, l]
2938
+ a[icol, l] = dum
2939
+
2940
+ for l in range(1):
2941
+ # dum = b[v, irow]
2942
+ # b[v, irow] = b[v, icol]
2943
+ # b[v, icol] = dum
2944
+ dum = b[irow]
2945
+ b[irow] = b[icol]
2946
+ b[icol] = dum
2947
+
2948
+ indxr[i] = irow
2949
+ indxc[i] = icol
2950
+ if a[icol, icol] == 0:
2951
+ m = -1
2952
+ return m
2953
+
2954
+ pivinv = 1 / a[icol, icol]
2955
+
2956
+ a[icol, icol] = 1
2957
+ a[icol] *= pivinv
2958
+ b[icol] *= pivinv
2959
+
2960
+ for ll in range(n):
2961
+ if ll != icol:
2962
+ dum = a[ll, icol]
2963
+ a[ll, icol] = 0
2964
+ a[ll, :] -= a[icol, :] * dum
2965
+ b[ll] -= b[icol] * dum
2966
+
2967
+ for l in range(n - 1, -1, -1):
2968
+ if indxr[l] != indxc[l]:
2969
+ a[:, [indxr[l], indxc[l]]] = a[:, [indxc[l], indxr[l]]]
2970
+
2971
+ # print(f"\n======================================")
2972
+ # print(f"Return gaussj")
2973
+ # print(f"======================================")
2974
+ # print(f"{a = }")
2975
+ # print(f"{n = }")
2976
+ # print(f"{b = }")
2977
+ # print(f"{m = }")
2978
+
2979
+ return m
2980
+
2981
+ def age(self, nt, c, y, dyda, mc, lista, mfit, vc, xmat, r39, xi, c40, nn, nst, ndata, perc, al):
2982
+
2983
+ # print(f"\n== Run age ==\n")
2984
+ # print(f"{c40 = }")
2985
+ # print(f"{r39 = }")
2986
+ # print(f"{nt = }")
2987
+ # print(f"{nst = }")
2988
+ # print(f"{nn = }")
2989
+ # print(f"{vc = }")
2990
+ # print(f"{xi = }")
2991
+ # print(f"{xmat = }")
2992
+
2993
+ xlambd = 0.0005543
2994
+ nc = 100
2995
+ nd = 10
2996
+ ns = 200
2997
+ nwcy = 10
2998
+ ntst = 1001
2999
+
3000
+ dya = 0
3001
+
3002
+ c39wd = 1 - c40
3003
+ s1 = 0
3004
+
3005
+ # print(f"{xmat[0, 1, 0] - xmat[0, 0, 0] = }")
3006
+ # print(f"{xmat[0, 2, 0] - xmat[0, 1, 0] = }")
3007
+ # print(f"{xmat[0, 3, 0] - xmat[0, 2, 0] = }")
3008
+ # print(f"{xmat[0, 4, 0] - xmat[0, 3, 0] = }")
3009
+ # print(f"{xi[0][0][0] = }")
3010
+ for k in range(nst):
3011
+ for m in range(nn):
3012
+ s1 += vc[k] * xi[0, k, m] * (xmat[k, nt, m] - xmat[k, nt - 1, m])
3013
+
3014
+ # if m == 300 and nt == 2:
3015
+ # print(f"{vc[k] = }, {xi[0, k, m] = }, {xmat[k, nt, m] = }, {xmat[k, nt - 1, m] = }")
3016
+ # y = y
3017
+ # if nt == 2:
3018
+ # print(f"{vc[k] = }, {xi[0, k, m] = }, {xmat[k, nt, m] = }, {xmat[k, nt - 1, m] = }")
3019
+ # y = y
3020
+
3021
+ # print(f"{nt = }, {s1 = }")
3022
+
3023
+ dr39 = r39[nt] - r39[nt - 1]
3024
+ dr40 = dr39 * (c40 - 1) + s1
3025
+
3026
+ y = 0
3027
+ if dr40 / dr39 > 0:
3028
+ y = np.log(1 + dr40 / dr39 / c39wd) / xlambd
3029
+ dya = 1 / (dr39 * c39wd + dr40) / xlambd
3030
+
3031
+ # print(f"{dr40 = }, {dr39 = }, {c39wd = }")
3032
+
3033
+ if nt == 2:
3034
+ nt = nt
3035
+ if al < 0:
3036
+ self.agei[self.ncyc - 1, 0, nt] = r39[nt] * 100
3037
+ self.agei[self.ncyc - 1, 1, nt - 1] = y
3038
+ elif al == 0:
3039
+ self.ageo[self.ncyc - 1, 0, nt] = r39[nt] * 100
3040
+ self.ageo[self.ncyc - 1, 1, nt - 1] = y
3041
+
3042
+ # print(f"{self.ageo[self.ncyc - 1, 1, nt - 1] = }")
3043
+
3044
+ for ls in range(1, mfit + 1):
3045
+ l = ls * 2 - 1
3046
+ dc = perc * abs(c[lista[ls - 1]])
3047
+ s1 = 0
3048
+ s1_list = []
3049
+ for k in range(nst):
3050
+ for m in range(nn):
3051
+ dxi = (xi[l + 1, k, m] - xi[l, k, m]) / (2 * dc)
3052
+ s1 += vc[k] * (xmat[k, nt, m] - xmat[k, nt - 1, m]) * dxi
3053
+ s1_list.append(vc[k] * (xmat[k, nt, m] - xmat[k, nt - 1, m]) * dxi)
3054
+ # print(f"{vc[k] = }")
3055
+ # print(f"{xmat[k, nt, m] = }")
3056
+ # print(f"{xmat[k, nt - 1, m] = }")
3057
+ # print(f"{dxi = }")
3058
+ # print(f"{xi[l + 1, k, m] = }")
3059
+ # print(f"{xi[l, k, m] = }")
3060
+ # print(f"{dc = }")
3061
+
3062
+ # print(f"{s1 = }")
3063
+ # print(f"{kahan_sum(s1_list) = }")
3064
+ # print(f"{dya = }")
3065
+
3066
+ dyda[lista[ls - 1]] = s1 * dya
3067
+
3068
+ # print(f"\n== Return age ==\n")
3069
+ # print(f"{s1 = }")
3070
+ # print(f"{dr39 = }")
3071
+ # print(f"{dr40 = }")
3072
+ # # print(f"{y = }")
3073
+ # # print(f"{dyda = }")
3074
+
3075
+ return y, dyda
3076
+
3077
+ def covsrt(self, covar, ma, lista, mfit):
3078
+ # covar is expected to be a numpy array of shape (ncvm, ncvm)
3079
+ # lista is expected to be a numpy array of shape (mfit,)
3080
+
3081
+ # Step 1: Zero out the upper triangle
3082
+ for j in range(ma - 1):
3083
+ for i in range(j + 1, ma):
3084
+ covar[i, j] = 0.0
3085
+
3086
+ # Step 2: Reorganize the covariance matrix
3087
+ for i in range(mfit - 1):
3088
+ for j in range(i + 1, mfit):
3089
+ if lista[j] > lista[i]:
3090
+ covar[int(lista[j]), int(lista[i])] = covar[i, j]
3091
+ else:
3092
+ covar[int(lista[i]), int(lista[j])] = covar[i, j]
3093
+
3094
+ # Step 3: Swap and reset diagonal elements
3095
+ swap = covar[0, 0]
3096
+ for j in range(ma):
3097
+ covar[0, j] = covar[j, j]
3098
+ covar[j, j] = 0.0
3099
+
3100
+ covar[int(lista[0]), int(lista[0])] = swap
3101
+
3102
+ for j in range(1, mfit):
3103
+ covar[int(lista[j]), int(lista[j])] = covar[0, j]
3104
+
3105
+ # Step 4: Symmetrize the covariance matrix
3106
+ for j in range(1, ma):
3107
+ for i in range(j):
3108
+ covar[i, j] = covar[j, i]
3109
+
3110
+ return covar
3111
+
3112
+ def gammq(self, a, x):
3113
+ if x < 0 or a <= 0:
3114
+ raise ValueError("ERROR(GAMMQ): x < 0 or a <= 0")
3115
+
3116
+ if x < a + 1:
3117
+ gamser, gln = self.gser(a, x)
3118
+ return 1.0 - gamser
3119
+ else:
3120
+ gammcf, gln = self.gcf(a, x)
3121
+ return gammcf
3122
+
3123
+ def gser(self, a, x, itmax=100, eps=3e-7):
3124
+ gln = self.gammln(a)
3125
+ if x <= 0:
3126
+ if x < 0:
3127
+ raise ValueError("ERROR(GSER): x < 0")
3128
+ return 0.0, gln
3129
+
3130
+ ap = a
3131
+ sum_ = 1.0 / a
3132
+ delta = sum_
3133
+ for n in range(1, itmax + 1):
3134
+ ap += 1
3135
+ delta *= x / ap
3136
+ sum_ += delta
3137
+ if abs(delta) < abs(sum_) * eps:
3138
+ break
3139
+ else:
3140
+ raise RuntimeError("ERROR(GSER): a too large, itmax too small")
3141
+
3142
+ gamser = sum_ * np.exp(-x + a * np.log(x) - gln)
3143
+ return gamser, gln
3144
+
3145
+ def gcf(self, a, x, itmax=100, eps=3e-7):
3146
+ gln = self.gammln(a)
3147
+ gold = 0.0
3148
+ a0 = 1.0
3149
+ a1 = x
3150
+ b0 = 0.0
3151
+ b1 = 1.0
3152
+ fac = 1.0
3153
+ for n in range(1, itmax + 1):
3154
+ an = float(n)
3155
+ ana = an - a
3156
+ a0 = (a1 + a0 * ana) * fac
3157
+ b0 = (b1 + b0 * ana) * fac
3158
+ anf = an * fac
3159
+ a1 = x * a0 + anf * a1
3160
+ b1 = x * b0 + anf * b1
3161
+ if a1 != 0:
3162
+ fac = 1.0 / a1
3163
+ g = b1 * fac
3164
+ if abs((g - gold) / g) < eps:
3165
+ return g * np.exp(-x + a * np.log(x) - gln), gln
3166
+ gold = g
3167
+ else:
3168
+ raise RuntimeError("ERROR(GCF): a too large, itmax too small")
3169
+
3170
+ def gammln(self, xx):
3171
+ cof = np.array([76.18009173, -86.50532033, 24.01409822,
3172
+ -1.231739516, 0.00120858003, -0.00000536382])
3173
+ stp = 2.50662827465
3174
+ half = 0.5
3175
+ one = 1.0
3176
+ fpf = 5.5
3177
+
3178
+ x = xx - one
3179
+ tmp = x + fpf
3180
+ tmp = (x + half) * np.log(tmp) - tmp
3181
+ ser = one
3182
+ for j in range(6):
3183
+ x += one
3184
+ ser += cof[j] / x
3185
+
3186
+ return tmp + np.log(stp * ser)
3187
+
3188
+
3189
+ class DiffDraw(DiffSample):
3190
+ def __init__(self, **kwargs):
3191
+
3192
+ self.sname = ""
3193
+ self.loc = "D:\\PythonProjects\\ararpy_package\\ararpy\\examples\\20240710_24FY51a"
3194
+
3195
+ super().__init__(**kwargs)
3196
+
3197
+ self.file_mages_in = open(os.path.join(self.loc, f"{self.sname}_mages-out.dat"), "r")
3198
+ self.file_mch_in = open(os.path.join(self.loc, f"{self.sname}_mch-out.dat"), "r")
3199
+ self.file_agesd_in = open(os.path.join(self.loc, f"{self.sname}_ages-sd.samp"), "r")
3200
+
3201
+ ns = 100
3202
+ k = 0
3203
+
3204
+
3205
+ read_from_ins = kwargs.get('read_from_ins', False)
3206
+
3207
+ # 读取sig
3208
+ self.f = np.zeros(ns, dtype=np.float64)
3209
+ self.age = np.zeros(ns, dtype=np.float64)
3210
+ for i in range(ns):
3211
+ try:
3212
+ self.f[i], self.age[i] = [float(j) for j in filter(lambda x: is_number(x),
3213
+ [m for k in self.file_agesd_in.readline().split('\t')
3214
+ for m in str(k).split(' ')])]
3215
+ k += 1
3216
+ except ValueError:
3217
+ pass
3218
+ continue
3219
+
3220
+ # print(f"{self.f = }")
3221
+ # print(f"{self.age = }")
3222
+
3223
+ if read_from_ins:
3224
+
3225
+ self.file_tmp_in = open(os.path.join(self.loc, f"{self.sname}_tmp.in"), "r")
3226
+ self.file_fj_in = open(os.path.join(self.loc, f"{self.sname}_fj.in"), "r")
3227
+ self.file_a39_in = open(os.path.join(self.loc, f"{self.sname}_a39.in"), "r")
3228
+ self.file_age_in = open(os.path.join(self.loc, f"{self.sname}_age.in"), "r")
3229
+ self.file_sig_in = open(os.path.join(self.loc, f"{self.sname}_sig.in"), "r")
3230
+
3231
+ self.ni = int(self.file_tmp_in.readline()) # sequence number
3232
+
3233
+ self.f = np.zeros(self.ni, dtype=np.float64)
3234
+ self.age = np.zeros(self.ni, dtype=np.float64)
3235
+ self.sage = np.zeros(self.ni, dtype=np.float64)
3236
+ self.a39 = np.zeros(self.ni, dtype=np.float64)
3237
+ self.sig39 = np.zeros(self.ni, dtype=np.float64)
3238
+ self.telab = np.zeros(self.ni, dtype=np.float64)
3239
+ self.tilab = np.zeros(self.ni, dtype=np.float64)
3240
+
3241
+ for i in range(self.ni):
3242
+ try:
3243
+ f, age = [float(j) for j in filter(lambda x: is_number(x),
3244
+ [m for k in self.file_age_in.readline().split('\t') for m in
3245
+ str(k).split(' ')])]
3246
+ sage = float(self.file_sig_in.readline()) # age error
3247
+ te = float(self.file_tmp_in.readline()) # heating temperature in Kelvin
3248
+ ti = float(self.file_tmp_in.readline()) * 60 # heating time in second.
3249
+ v, sv = [float(j) for j in filter(lambda x: is_number(x),
3250
+ [m for k in self.file_a39_in.readline().split('\t') for m in
3251
+ str(k).split(' ')])]
3252
+ except ValueError as e:
3253
+ continue
3254
+ else:
3255
+ self.f[i], self.age[i], self.sage[i] = f, age, sage
3256
+ self.telab[i] = te
3257
+ self.tilab[i] = ti
3258
+ self.a39[i], self.sig39[i] = float(v), float(sv)
3259
+
3260
+ self.mf = np.zeros([100, 1000], dtype=np.float64)
3261
+ self.mage = np.zeros([100, 1000], dtype=np.float64)
3262
+ self.mcte = np.zeros([100, 1000], dtype=np.float64)
3263
+ self.mcage = np.zeros([100, 1000], dtype=np.float64)
3264
+
3265
+ self.mcyc = 0
3266
+ max_count = 0
3267
+ for cyc in range(100):
3268
+ count = 0
3269
+ for j in range(1000):
3270
+ try:
3271
+ line = self.file_mages_in.readline().rstrip("\n")
3272
+ # print(list(filter(lambda x: is_number(x), [m for k in self.file_mages_in.readline().split('\t') for m in str(k).split(' ')])))
3273
+ f, age = [float(l) for l in
3274
+ filter(lambda x: is_number(x), [m for k in line.split('\t') for m in str(k).split(' ')])]
3275
+ except ValueError as e:
3276
+ break
3277
+ else:
3278
+ self.mf[cyc, j], self.mage[cyc, j] = f, age
3279
+ count += 1
3280
+ max_count = count if count > max_count else max_count
3281
+ if line == "":
3282
+ break
3283
+ self.mcyc += 1
3284
+
3285
+ self.mf = self.mf[:self.mcyc, :max_count]
3286
+ self.mage = self.mage[:self.mcyc, :max_count]
3287
+
3288
+ self.count = np.zeros(self.mcyc, dtype=int)
3289
+ for cyc in range(self.mcyc):
3290
+ for j in range(1000):
3291
+ try:
3292
+ cage, cte = [float(l) for l in filter(lambda x: is_number(x),
3293
+ [m for k in self.file_mch_in.readline().split('\t') for m in
3294
+ str(k).split(' ')])]
3295
+ except ValueError as e:
3296
+ # print(e)
3297
+ break
3298
+ else:
3299
+ self.mcte[cyc, j], self.mcage[cyc, j] = cte, cage
3300
+ self.count[cyc] += 1
3301
+
3302
+ # 每一组count不一样 下面的语句会裁剪
3303
+ # self.mcte = self.mcte[:self.mch, :self.mcyc, :count]
3304
+ # self.mcage = self.mcage[:self.mch, :self.mcyc, :count]
3305
+
3306
+ # self.max_age = 75
3307
+ # self.min_age = 30
3308
+ # self.age_step = self.max_age - self.min_age
3309
+
3310
+ # print(f"{self.ni = }")
3311
+ # print(f"{self.f = }")
3312
+ # print(f"{self.age = }")
3313
+ # print(f"{self.a39 = }")
3314
+ # print(f"{self.sig39 = }")
3315
+ # print(f"{self.telab = }")
3316
+ # print(f"{self.tilab = }")
3317
+ # print(f"{self.mf = }")
3318
+ # print(f"{self.mage = }")
3319
+ # print(f"{self.mcte = }")
3320
+ # print(f"{self.mcage = }")
3321
+
3322
+ def get_plot_data(self):
3323
+
3324
+ k1 = [x, y1, y2] = ap.calc.spectra.get_data(self.age, self.sage, [i * 100 for i in self.f], cumulative=True)
3325
+ k2 = []
3326
+ k3 = []
3327
+ for cyc in range(self.mcyc):
3328
+ x, y1, y2 = ap.calc.spectra.get_data(
3329
+ self.mage[cyc, :], np.zeros(self.mage[cyc, :].size), self.mf[cyc, :], cumulative=True)
3330
+ k2.append([x, y1, y2])
3331
+ k3.append([self.mcage[cyc, :], self.mcte[cyc, :]])
3332
+
3333
+ # confidence
3334
+ (_b, _c) = self.mcage.shape
3335
+ k4 = [x_conf, y1_conf, y2_conf, y3_conf, y4_conf] = conf(
3336
+ self.mcage.reshape([_b, _c]), self.mcte.reshape([_b, _c]),
3337
+ count=self.count.flatten(), using_normal=True)
3338
+
3339
+ return k1, k2, k3, k4
3340
+
3341
+ def main(self):
3342
+
3343
+ data = self.get_plot_data()
3344
+ # print(f"{self.mcyc = }")
3345
+ fig, [axs, axs2] = plt.subplots(2, 1)
3346
+ fig.set_size_inches(w=6, h=9)
3347
+
3348
+ axs.set_title(f'Age spectra')
3349
+ axs.set_ylabel(f'Apparent age (Ma)')
3350
+ axs.set_xlabel(f'Cumulative 39Ar%')
3351
+ axs.set_xlim(0, 100)
3352
+ axs.set_ylim(0, 80)
3353
+
3354
+ axs.plot(data[0][0], data[0][2], c='blue')
3355
+ axs.plot(data[0][0], data[0][1], c='blue')
3356
+
3357
+ for cyc in range(self.mcyc):
3358
+ # x, y1, y2 = ap.calc.spectra.get_data(self.mage[cyc, :], np.zeros(self.mage[cyc, :].size), self.mf[cyc, :],
3359
+ # cumulative=True)
3360
+ axs.plot(data[1][cyc][0], data[1][cyc][2], c='red')
3361
+ axs.plot(data[1][cyc][0], data[1][cyc][1], c='red')
3362
+
3363
+ axs.legend()
3364
+ # axs.text(0, 0, f'{self.sname}')
3365
+
3366
+ axs2.set_title(f'Cooling histories')
3367
+ axs2.set_ylabel(f'Temperature')
3368
+ axs2.set_xlabel(f'Age (Ma)')
3369
+ # axs2.set_xlim(30, 75)
3370
+ # axs2.set_ylim(0, 500)
3371
+ for cyc in range(self.mcyc):
3372
+ # axs2.plot(self.mcage[cyc, :], self.mcte[cyc, :], c='grey')
3373
+ axs2.plot(data[2][cyc][0], data[2][cyc][1], c='grey')
3374
+
3375
+ # print(f"{self.mcage = }")
3376
+
3377
+ # (_b, _c) = self.mcage.shape
3378
+ # x_conf, y1_conf, y2_conf, y3_conf, y4_conf = conf(
3379
+ # self.mcage.reshape([_b, _c]), self.mcte.reshape([_b, _c]),
3380
+ # count=self.count.flatten(), using_normal=True)
3381
+ x_conf, y1_conf, y2_conf, y3_conf, y4_conf = data[3]
3382
+
3383
+ self.file_confmed_out = open(os.path.join(self.loc, f"{self.sname}_confmed.dat"), "w")
3384
+ for i in range(len(x_conf)):
3385
+ line = f"{x_conf[i]} {y1_conf[i]} {y2_conf[i]} {y3_conf[i]} {y4_conf[i]}"
3386
+ self.file_confmed_out.writelines(line + "\n")
3387
+ self.file_confmed_out.close()
3388
+
3389
+ axs2.plot(x_conf, y1_conf, c='red')
3390
+ axs2.plot(x_conf, y2_conf, c='red')
3391
+ axs2.plot(x_conf, y3_conf, c='red')
3392
+ axs2.plot(x_conf, y4_conf, c='red')
3393
+
3394
+ fig.tight_layout()
3395
+ plt.show()
3396
+
3397
+
3398
+ class HeatingSequence:
3399
+ def __init__(self, SP, ST, ET, LB, LMin, LMax, LMean, LSD, UMin, UMax, UMean, USD,
3400
+ x0, x1, x2, x3, x4, x5, x6, r2, Rise, Increment, MaxTime):
3401
+ self.SP, self.ST, self.ET, self.LB = SP, ST, ET, LB
3402
+ self.LMin, self.LMax, self.LMean, self.LSD = LMin, LMax, LMean, LSD
3403
+ self.UMin, self.UMax, self.UMean, self.USD = UMin, UMax, UMean, USD
3404
+ self.x0, self.x1, self.x2, self.x3, self.x4, self.x5, self.x6, self.r2 = x0, x1, x2, x3, x4, x5, x6, r2
3405
+ self.Rise, self.Increment, self.MaxTime = Rise, Increment, MaxTime
3406
+
3407
+ self.x = [self.x0, self.x1, self.x2, self.x3, self.x4, self.x5, self.x6]
3408
+
3409
+
3410
+ class InsideTemperatureCalibration:
3411
+ def __init__(self):
3412
+
3413
+ self.loc = r'D:\DjangoProjects\webarar\static\settings'
3414
+ self.temp_regression_res = self.calculate_temp_conf()
3415
+
3416
+ def get_seq(self, degree: int, increment=None, r2=0.5, minTime=0):
3417
+
3418
+ if degree == 600 and increment is not None:
3419
+ increment = 500
3420
+
3421
+ if increment is None:
3422
+ locs = np.where(
3423
+ [str(i.SP) == str(degree) and float(i.r2) >= float(r2) and float(i.MaxTime) >= float(minTime) for i in
3424
+ self.sequences])
3425
+ else:
3426
+ locs = np.where([str(i.SP) == str(degree) and float(i.r2) >= float(r2) and float(i.MaxTime) >= float(
3427
+ minTime) and str(i.Increment) == str(increment) for i in self.sequences])
3428
+
3429
+ return self.sequences[locs]
3430
+
3431
+ def plot(self):
3432
+
3433
+ path = r"/static/settings/Oven_log_regression_results.txt"
3434
+
3435
+ file_in = open(path, "r")
3436
+ sequences = np.empty(10000, dtype=HeatingSequence)
3437
+ i = 0
3438
+ while True:
3439
+ line = file_in.readline().rstrip("\n")
3440
+ if line == "":
3441
+ break
3442
+ if line.startswith("SP"):
3443
+ continue
3444
+ values = line.split(",")
3445
+ sequences[i] = HeatingSequence(*values)
3446
+ i += 1
3447
+
3448
+ file_in.close()
3449
+
3450
+ sequences = sequences[:i]
3451
+ locs = np.where([i.Rise == "True" and int(i.Increment) >= 0 for i in sequences])
3452
+ self.sequences = sequences[locs]
3453
+
3454
+ degrees = [600, 650, 700, 750, 800, 850, 900, 950, 1000,
3455
+ 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500]
3456
+
3457
+ fig, axs = plt.subplots(4, 5)
3458
+ fig.set_size_inches(w=12, h=10)
3459
+
3460
+ file_out = open(os.path.join(self.loc, f"conf_temperature_out.txt"), "w")
3461
+ file2_out = open(os.path.join(self.loc, f"conf_temperature_regression_out.txt"), "w")
3462
+
3463
+ for index, ax in enumerate(axs.flatten()):
3464
+
3465
+ if index >= len(degrees):
3466
+ break
3467
+
3468
+ x_list = []
3469
+ y_list = []
3470
+
3471
+ for seq in self.get_seq(degree=degrees[index], increment=50):
3472
+ x = np.linspace(0, int(seq.MaxTime), num=100)
3473
+ x_ = np.array([x ** 0, x ** 1, x ** 2, x ** 3, x ** 4, x ** 5, x ** 6]).transpose()
3474
+
3475
+ y = np.sum(np.array(seq.x).astype(np.float64) * x_, axis=1)
3476
+ ax.plot(x, y, c='grey', alpha=0.5)
3477
+ ax.set_title(f'{degrees[index]} °C')
3478
+
3479
+ x_list.append(x)
3480
+ y_list.append(y)
3481
+
3482
+ # 拟合最优曲线
3483
+
3484
+ # 参考 :
3485
+ # https://www.zhihu.com/question/346773540/answer/2033802234
3486
+ # https://blog.csdn.net/weixin_46713695/article/details/126644568
3487
+
3488
+ try:
3489
+ x_conf, y1_conf, y2_conf, y3_conf, y4_conf = conf(x_list, y_list, num=100, using_binom=True)
3490
+ except (ValueError, IndexError) as e:
3491
+ pass
3492
+ else:
3493
+ ax.plot(x_conf, y1_conf, c='red')
3494
+ ax.plot(x_conf, y2_conf, c='red')
3495
+ ax.plot(x_conf, y3_conf, c='red')
3496
+ ax.plot(x_conf, y4_conf, c='red')
3497
+
3498
+ degree = 6
3499
+ x_conf = np.array(x_conf)
3500
+
3501
+ file_out.writelines(f"{seq.SP = }, {seq.MaxTime = }, conf MaxTime = {max(x_conf)} \n")
3502
+ file2_out.writelines(f"SP = {seq.SP}, MaxTime = {max(x_conf)} \n")
3503
+
3504
+ beta = ap.calc.regression.polynomial(y1_conf, x_conf, degree=degree)[5]
3505
+ ax.plot(x_conf, np.sum(beta * np.array([x_conf ** i for i in range(degree + 1)]).transpose(), axis=1),
3506
+ c='blue')
3507
+ file_out.writelines("BetaY1\t" + "\t".join([str(i) for i in beta]) + "\n")
3508
+ file2_out.writelines("\t".join([str(i) for i in beta]) + "\n")
3509
+
3510
+ beta = ap.calc.regression.polynomial(y2_conf, x_conf, degree=degree)[5]
3511
+ ax.plot(x_conf, np.sum(beta * np.array([x_conf ** i for i in range(degree + 1)]).transpose(), axis=1),
3512
+ c='blue')
3513
+ file_out.writelines("BetaY2\t" + "\t".join([str(i) for i in beta]) + "\n")
3514
+ file2_out.writelines("\t".join([str(i) for i in beta]) + "\n")
3515
+
3516
+ beta = ap.calc.regression.polynomial(y3_conf, x_conf, degree=degree)[5]
3517
+ ax.plot(x_conf, np.sum(beta * np.array([x_conf ** i for i in range(degree + 1)]).transpose(), axis=1),
3518
+ c='blue')
3519
+ file_out.writelines("BetaY3\t" + "\t".join([str(i) for i in beta]) + "\n")
3520
+ file2_out.writelines("\t".join([str(i) for i in beta]) + "\n")
3521
+
3522
+ beta = ap.calc.regression.polynomial(y4_conf, x_conf, degree=degree)[5]
3523
+ ax.plot(x_conf, np.sum(beta * np.array([x_conf ** i for i in range(degree + 1)]).transpose(), axis=1),
3524
+ c='blue')
3525
+ file_out.writelines("BetaY4\t" + "\t".join([str(i) for i in beta]) + "\n")
3526
+ file2_out.writelines("\t".join([str(i) for i in beta]) + "\n")
3527
+
3528
+ for i in range(len(x_conf)):
3529
+ line = f"{x_conf[i]}\t{y1_conf[i]}\t{y2_conf[i]}\t{y3_conf[i]}\t{y4_conf[i]}"
3530
+ file_out.writelines(line + "\n")
3531
+
3532
+ file_out.close()
3533
+ file2_out.close()
3534
+
3535
+ fig.tight_layout()
3536
+ plt.show()
3537
+
3538
+ def plot_confidence(self):
3539
+
3540
+ fig, ax = plt.subplots()
3541
+ fig.set_size_inches(w=12, h=10)
3542
+
3543
+ file_in = open(os.path.join(self.loc, f"conf_temperature_out.txt"), "r")
3544
+
3545
+ x_start = 0
3546
+ k = 0
3547
+ conf_x_max = 0
3548
+
3549
+ while True:
3550
+ try:
3551
+ line = file_in.readline()
3552
+
3553
+ if line.startswith("Beta"):
3554
+ beta = [float(j) for j in
3555
+ filter(lambda x: is_number(x), [m for k in line.split('\t') for m in str(k).split(' ')])]
3556
+ k += 1
3557
+
3558
+ if "conf MaxTime" in line:
3559
+ conf_x_max = float(line.split('conf MaxTime = ')[-1])
3560
+
3561
+ if 0 < k <= 2:
3562
+ x = np.linspace(start=0, stop=conf_x_max, num=100)
3563
+
3564
+ _x = np.array([x ** 0, x ** 1, x ** 2, x ** 3, x ** 4, x ** 5, x ** 6]).transpose()
3565
+ y = np.sum(beta * _x, axis=1)
3566
+
3567
+ ax.plot(x + x_start, y, c='blue')
3568
+
3569
+ elif k == 4:
3570
+ k = 0
3571
+ x_start += conf_x_max
3572
+
3573
+ if line == "":
3574
+ break
3575
+
3576
+ except Exception as e:
3577
+ print(e)
3578
+ break
3579
+
3580
+ file_in.close()
3581
+
3582
+ fig.tight_layout()
3583
+ plt.show()
3584
+
3585
+ def plot_libano_log(self, libano_path: str):
3586
+
3587
+ libano_log = open(libano_path, "r")
3588
+ log_time = []
3589
+ log_sp = []
3590
+ log_ap = []
3591
+ conf_ap1 = []
3592
+ conf_ap2 = []
3593
+
3594
+ n = 0
3595
+ while True:
3596
+ line = libano_log.readline().rstrip("\n")
3597
+ if line == "":
3598
+ break
3599
+ k = line.split(";")
3600
+ log_time.append(dt.strptime(k[0], "%Y-%m-%dT%H:%M:%S%z").timestamp())
3601
+ log_sp.append(int(k[1]))
3602
+ log_ap.append(int(k[2]))
3603
+ # set time starts with zero
3604
+ log_time = [i - log_time[0] for i in log_time]
3605
+ libano_log.close()
3606
+
3607
+ start_sp = -999
3608
+ start_time = 0
3609
+ for index, sp in enumerate(log_sp):
3610
+ if sp != start_sp:
3611
+ start_time = log_time[index]
3612
+ start_sp = sp
3613
+ try:
3614
+ ap1, ap2 = self.get_calibrated_temp(log_time[index] - start_time, sp)
3615
+ except (KeyError, ValueError):
3616
+ ap1, ap2 = 0, 0
3617
+ conf_ap1.append(ap1)
3618
+ conf_ap2.append(ap2)
3619
+
3620
+ fig, ax = plt.subplots()
3621
+ fig.set_size_inches(w=12, h=10)
3622
+ ax.plot(log_time, log_sp, c='green')
3623
+ ax.plot(log_time, log_ap, c='blue')
3624
+ ax.plot(log_time, conf_ap1, c='red')
3625
+ ax.plot(log_time, conf_ap2, c='red')
3626
+ fig.tight_layout()
3627
+ plt.show()
3628
+
3629
+ def calculate_temp_conf(self):
3630
+
3631
+ file_in = open(os.path.join(self.loc, f"conf_temperature_regression_out.txt"), "r")
3632
+ k = 0
3633
+ conf_x_max = 0
3634
+
3635
+ funcs = {}
3636
+
3637
+ while True:
3638
+
3639
+ line = file_in.readline().rstrip("\n")
3640
+ if line == "":
3641
+ break
3642
+
3643
+ if line.startswith("SP"):
3644
+ pattern = r"SP = (\d+), MaxTime = (\d+\.\d+)"
3645
+ _ = re.search(pattern, line)
3646
+ conf_sp = float(_.groups()[0])
3647
+ conf_x_max = float(_.groups()[1])
3648
+ funcs[int(conf_sp)] = {"max_x": conf_x_max}
3649
+ k = 0
3650
+ pass
3651
+ else:
3652
+ beta = [float(j) for j in
3653
+ filter(lambda x: is_number(x), [m for k in line.split('\t') for m in str(k).split(' ')])]
3654
+ k += 1
3655
+
3656
+ if k == 1:
3657
+ funcs[int(conf_sp)].update({1: beta})
3658
+ if k == 2:
3659
+ funcs[int(conf_sp)].update({2: beta})
3660
+ if k == 4:
3661
+ k = 0
3662
+
3663
+ file_in.close()
3664
+
3665
+ return funcs
3666
+
3667
+ def get_calibrated_temp(self, time, sp):
3668
+ funcs = self.temp_regression_res
3669
+ f1 = lambda x: sum(
3670
+ np.array(funcs[int(sp)][1]) * np.array([x ** 0, x ** 1, x ** 2, x ** 3, x ** 4, x ** 5, x ** 6]))
3671
+ f2 = lambda x: sum(
3672
+ np.array(funcs[int(sp)][2]) * np.array([x ** 0, x ** 1, x ** 2, x ** 3, x ** 4, x ** 5, x ** 6]))
3673
+ max_x = funcs[int(sp)]['max_x']
3674
+ ap1, ap2 = f1(time) if 0 <= time <= max_x else f1(max_x) if time > max_x else f1(0), f2(
3675
+ time) if 0 <= time <= max_x else f2(max_x) if time > max_x else f2(0)
3676
+ return ap1, ap2
3677
+
3678
+
3679
+ class SmpTemperatureCalibration:
3680
+ def __init__(self, arr_path="", helix_log_path="", libano_log_path=None,
3681
+ name="smp_example", loc=r'D:\DjangoProjects\webarar\static\settings'):
3682
+
3683
+ self.name = name
3684
+ self.smp = ap.from_arr(file_path=arr_path)
3685
+ if isinstance(self.smp, Sample):
3686
+ self.name = self.smp.name()
3687
+
3688
+ self.loc = loc
3689
+
3690
+ self.helix_log_path = []
3691
+ if isinstance(helix_log_path, str):
3692
+ self.helix_log_path = [helix_log_path]
3693
+ elif isinstance(helix_log_path, list):
3694
+ self.helix_log_path = helix_log_path
3695
+ self.helix_log_path.sort()
3696
+
3697
+ self.libano_log_path = []
3698
+ if isinstance(libano_log_path, str):
3699
+ self.libano_log_path = [libano_log_path]
3700
+ elif isinstance(libano_log_path, list):
3701
+ self.libano_log_path = libano_log_path
3702
+ self.libano_log_path.sort()
3703
+
3704
+ temp_calibrator = InsideTemperatureCalibration()
3705
+
3706
+ # read libano log files
3707
+ log_time = []
3708
+ log_outside_ap = []
3709
+ log_outside_sp = []
3710
+ libano_log = []
3711
+ last_sp = -1
3712
+ last_sp_index = 0
3713
+ n = 0
3714
+ for path in self.libano_log_path:
3715
+ libano_file = open(path, "r")
3716
+ while True:
3717
+ line = libano_file.readline().rstrip("\n")
3718
+ if line == "":
3719
+ break
3720
+ k = line.split(";")
3721
+ time = dt.strptime(k[0], "%Y-%m-%dT%H:%M:%S%z").timestamp()
3722
+ cumulative_time = 0
3723
+ if int(k[1]) != last_sp:
3724
+ last_sp = int(k[1])
3725
+ last_sp_index = n
3726
+ else:
3727
+ cumulative_time = time - libano_log[last_sp_index][0]
3728
+ log_time.append(time)
3729
+ log_outside_sp.append(int(k[1]))
3730
+ log_outside_ap.append(int(k[2]))
3731
+ try:
3732
+ inside_temp = temp_calibrator.get_calibrated_temp(time=cumulative_time, sp=int(k[1]))
3733
+ except KeyError:
3734
+ inside_temp = [0, 0]
3735
+
3736
+ libano_log.append([time, int(k[1]), int(k[2]), cumulative_time, inside_temp[0], inside_temp[1]])
3737
+ n += 1
3738
+
3739
+ libano_file.close()
3740
+ libano_log = np.array(libano_log).transpose()
3741
+
3742
+ # # set time starts with zero
3743
+ # log_time = [i - log_time[0] for i in log_time]
3744
+
3745
+ self.start_time = log_time[0]
3746
+ self.end_time = log_time[-1]
3747
+
3748
+ # read helix log files
3749
+ helix_log = [[], [], [], [], # start experiment, gas_in_end, gas_in, end experiment,
3750
+ [], [], [], [], [], []], # start_temp, s, end_temp, s, med_temp, s, sp, heating time
3751
+ helix_log = [[], [], [], [], [], [], [], [], [], [], [], []]
3752
+ nstep = 0
3753
+
3754
+ keys = {
3755
+ "start_buildup": "GenWorkflow-BuildUp.cs: line 1: Clock reset",
3756
+ "set_temp": "GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = ",
3757
+ "end_sampling": "GenWorkflow-Prepare.cs: line 1: CLOSE for VUcleaningline/VINL2",
3758
+ "start_sampling": "GenWorkflow-Prepare.cs: line 14: CLOSE for VUcleaningline/VGP5",
3759
+ "end_sequence": "GenWorkflow-PostAcquisition.cs: line 7: Starting Acquisition",
3760
+ "get_setpoint": "GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = ",
3761
+ }
3762
+
3763
+ # for Y56a
3764
+ if "Y56" in self.name:
3765
+ keys = {
3766
+ "start_buildup": "GenWorkflow-BuildUp.cs: line 1: Clock reset",
3767
+ "set_temp": "GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = ",
3768
+ "end_sampling": "GenWorkflow-Prepare.cs: line 1: CLOSE for VUcleaningline/VGP5",
3769
+ "start_sampling": "GenWorkflow-Sampling.cs: line 1: CLOSE for VUcleaningline/VGP5",
3770
+ "end_sequence": "GenWorkflow-PostAcquisition.cs: line 7: Starting Acquisition",
3771
+ "get_setpoint": "GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = ",
3772
+ }
3773
+
3774
+ for file in self.helix_log_path:
3775
+ lines = open(file, 'r', encoding='utf-8-sig').readlines()
3776
+ for line in lines:
3777
+
3778
+ if "|UserInfo|" not in line:
3779
+ continue
3780
+
3781
+ dt_str, helix, system, service, scripting, userinfo, message1, message2 = line.split("|")
3782
+ dt_utc = dt_str[:26] + dt_str[27:]
3783
+ dt_utc = dt.fromisoformat(str(dt_utc)).timestamp()
3784
+
3785
+ if not (self.start_time <= dt_utc <= self.end_time):
3786
+ continue
3787
+ if message1.startswith(keys["start_buildup"]):
3788
+ ### start buildup
3789
+ buildup_start = dt_utc
3790
+ helix_log[0].append(dt_utc)
3791
+ if message1.startswith(keys["set_temp"]):
3792
+ ### Close VGP5, not important
3793
+ temp_value = message1.split(keys["get_setpoint"])[-1]
3794
+ helix_log[10].append(int(temp_value))
3795
+ if message1.startswith(keys["end_sampling"]):
3796
+ # 关闭vinlet2,60秒进质谱,之后开vinlet2,90秒抽气
3797
+ gas_collection_end = dt_utc
3798
+ helix_log[1].append(dt_utc)
3799
+ if message1.startswith(keys["start_sampling"]):
3800
+ # Close VGP5, start peak centering and measurement, IMPORTANT: start to sampling
3801
+ gas_collection_start = dt_utc
3802
+ helix_log[2].append(dt_utc)
3803
+ if message1.startswith(keys["end_sequence"]):
3804
+ # The End of the entire measurement
3805
+ postacquisition_end = dt_utc
3806
+ helix_log[3].append(dt_utc)
3807
+ helix_log[4].append(0)
3808
+ helix_log[5].append(0)
3809
+ helix_log[6].append(0)
3810
+ helix_log[7].append(0)
3811
+ helix_log[8].append(0)
3812
+ helix_log[9].append(0)
3813
+ helix_log[11].append(0)
3814
+ nstep += 1
3815
+
3816
+ for i in helix_log:
3817
+ print(len(i))
3818
+ print(i)
3819
+ helix_log = np.array(helix_log)
3820
+
3821
+
3822
+ file_out = open(os.path.join(self.loc, f"{self.name}.txt"), "w")
3823
+
3824
+ line = f"#\tSP\tHeatingTime\tCalibratedStartTemp\tError\tCalibratedEndTemp\tError\tCalibratedMedTemp\tError\n"
3825
+ file_out.writelines(line)
3826
+
3827
+ yellow_data_index = []
3828
+
3829
+ for i in range(nstep):
3830
+ if i == 0:
3831
+ gas_in_start = helix_log[0, 0]
3832
+ else:
3833
+ gas_in_start = helix_log[2, i - 1]
3834
+
3835
+ # IMPORTANT, for Y56a
3836
+ if "Y56" in self.name:
3837
+ gas_in_start = helix_log[2, i]
3838
+
3839
+ gas_in_end = helix_log[1, i]
3840
+ _index = [index for index, j in enumerate(libano_log[0]) if gas_in_start <= j <= gas_in_end]
3841
+ if len(_index) == 0:
3842
+ continue
3843
+
3844
+ yellow_data_index.append(_index)
3845
+
3846
+ med = int((_index[0] + _index[-1]) / 2)
3847
+ helix_log[4, i] = (libano_log[4, _index][0] + libano_log[5, _index][0]) / 2
3848
+ helix_log[5, i] = abs(libano_log[4, _index][0] - libano_log[5, _index][0]) / 2
3849
+ helix_log[6, i] = (libano_log[4, _index][-1] + libano_log[5, _index][-1]) / 2
3850
+ helix_log[7, i] = abs(libano_log[4, _index][-1] - libano_log[5, _index][-1]) / 2
3851
+ helix_log[8, i] = (libano_log[4, med] + libano_log[5, med]) / 2
3852
+ helix_log[9, i] = abs(libano_log[4, med] - libano_log[5, med]) / 2
3853
+ helix_log[11, i] = gas_in_end - gas_in_start
3854
+
3855
+ line = f"{i + 1}\t{helix_log[10, i]}\t{helix_log[11, i]}\t" + '\t'.join(
3856
+ [str(j) for j in helix_log[4:10, i]]) + "\n"
3857
+ file_out.writelines(line)
3858
+
3859
+ file_out.close()
3860
+
3861
+
3862
+ fig, ax = plt.subplots()
3863
+ fig.set_size_inches(w=12, h=10)
3864
+
3865
+ ax.plot(libano_log[0], libano_log[1], c='green')
3866
+ ax.plot(libano_log[0], libano_log[2], c='blue')
3867
+ ax.plot(libano_log[0], libano_log[4], c='red')
3868
+ ax.plot(libano_log[0], libano_log[5], c='red')
3869
+ for i in range(nstep):
3870
+ _index = yellow_data_index[i]
3871
+ ax.plot(libano_log[0, _index], libano_log[4, _index], c='yellow')
3872
+ ax.plot(libano_log[0, _index], libano_log[5, _index], c='yellow')
3873
+
3874
+ fig.tight_layout()
3875
+ plt.show()
3876
+
3877
+
3878
+ np.savetxt(os.path.join(self.loc, f"{self.name}-temp.txt"), libano_log, delimiter=',')
3879
+ heating_out = open(os.path.join(self.loc, f"{self.name}-heated-index.txt"), "w")
3880
+ heating_out.writelines([','.join([str(j) for j in i]) for i in yellow_data_index])
3881
+ heating_out.close()
3882
+
3883
+
3884
+ #
3885
+ # helix_times = self.read_helix_log()
3886
+ # gas_collection_start = helix_times['GasCollectionStart']
3887
+ # gas_collection_end = helix_times['GasCollectionEnd']
3888
+ # buildup_start = helix_times['01-Buildup-Time']
3889
+ # temperature_value = helix_times['Temperature Value']
3890
+ # postacquisiton_time = helix_times['10-Postacquisition-Part3-Time']
3891
+ #
3892
+ # temp_calibrator = ap.calc.diffusion_funcs.InsideTemperatureCalibration()
3893
+ #
3894
+ # heating_sequence = []
3895
+ # helix_log_data = [[], [], [], [], []]
3896
+ # last_sp = -1
3897
+ # for index, buildup in enumerate(buildup_start):
3898
+ # sp = temperature_value[index]
3899
+ # if index == 0:
3900
+ # _start = buildup # 收集气体的时间
3901
+ # else:
3902
+ # _start = gas_collection_start[index - 1]
3903
+ #
3904
+ # gas_collection_time = gas_collection_end[index] - _start # 收集气体的时间
3905
+ #
3906
+ # if last_sp != sp:
3907
+ # _before = _start - log_time[log_outside_sp.index(sp)]
3908
+ # last_sp = sp
3909
+ # else:
3910
+ # _before = heating_sequence[index - 1]['cumulative_time'] + heating_sequence[index - 1]['heating_time'] / 2
3911
+ # cumulative_time = gas_collection_time / 2 + _before
3912
+ #
3913
+ # heating_sequence.append({
3914
+ # "sp": sp, "heating_time": gas_collection_time, "cumulative_time": cumulative_time
3915
+ # })
3916
+ #
3917
+ # n = 50
3918
+ # for i in range(n):
3919
+ # helix_log_data[0].append(sp) # sp
3920
+ # helix_log_data[1].append(gas_collection_time / n * i + _before) # cumulative_time
3921
+ # try:
3922
+ # if sp == 1500:
3923
+ # print(gas_collection_time / n * i + _before)
3924
+ # k1, k2 = temp_calibrator.get_calibrated_temp(time=gas_collection_time / n * i + _before, sp=sp)
3925
+ # except KeyError:
3926
+ # pass
3927
+ # else:
3928
+ # helix_log_data[2].append(gas_collection_time * 1 / n + helix_log_data[2][-1] if len(helix_log_data[2]) >= 1 else gas_collection_time * 1 / n + _before) # plot_time
3929
+ # helix_log_data[3].append(k1) # k1
3930
+ # helix_log_data[4].append(k2) # k2
3931
+ #
3932
+ #
3933
+ # file_out = open(os.path.join(self.loc, f"{self.name}.txt"), "w")
3934
+ #
3935
+ # line = f"#\tSP\tHeatingTime\tCalibratedTemp\tError\n"
3936
+ # file_out.writelines(line)
3937
+ #
3938
+ # log_inside_ap = []
3939
+ # log_inside_time = []
3940
+ # for index, temp in enumerate(heating_sequence):
3941
+ # print(f"{temp}")
3942
+ # try:
3943
+ # k1, k2 = temp_calibrator.get_calibrated_temp(time=temp["cumulative_time"], sp=temp["sp"])
3944
+ # except KeyError:
3945
+ # k1 = -999
3946
+ # k2 = -999
3947
+ # else:
3948
+ # log_inside_ap.append([k1, k2])
3949
+ #
3950
+ # line = f"{index + 1}\t{temp['sp']}\t{temp['heating_time']}\t{round((k1 + k2) / 2, 0)}\t{round(abs(k2 - k1) / 2, 0)}\n"
3951
+ # file_out.writelines(line)
3952
+ #
3953
+ #
3954
+ # file_out.close()
3955
+ #
3956
+ # fig, ax = plt.subplots()
3957
+ # fig.set_size_inches(w=12, h=10)
3958
+ # ax.plot([i - buildup_start[0] for i in log_time], log_outside_ap, c='blue')
3959
+ # ax.plot([i - buildup_start[0] for i in log_time], log_outside_sp, c='green')
3960
+ # ax.plot(helix_log_data[2], helix_log_data[3], c='red')
3961
+ # ax.plot(helix_log_data[2], helix_log_data[4], c='red')
3962
+ # fig.tight_layout()
3963
+ # plt.show()
3964
+
3965
+ def read_helix_log(self):
3966
+
3967
+ files = self.helix_log_path
3968
+
3969
+ times = {
3970
+ "01-Buildup-Time": [],
3971
+ "02-Presampling-Time": [],
3972
+ "03-Sampling-Time": [],
3973
+ "GasCollectionStart": [],
3974
+ "05-Inlet-Time": [],
3975
+ "GasCollectionEnd": [],
3976
+ "07-Acquisition-Time": [],
3977
+ "08-Postacquisition-Part1-Time": [],
3978
+ "09-Postacquisition-Part2-Time": [],
3979
+ "10-Postacquisition-Part3-Time": [],
3980
+ "Temperature Value": []
3981
+ }
3982
+
3983
+ for file in files:
3984
+ lines = open(file, 'r', encoding='utf-8-sig').readlines()
3985
+ for line in lines:
3986
+ if "|UserInfo|" not in line:
3987
+ continue
3988
+ dt_str, helix, system, service, scripting, userinfo, message1, message2 = line.split("|")
3989
+ message2 = ""
3990
+ time = ""
3991
+ dt_utc = dt_str[:26] + dt_str[27:]
3992
+ dt_utc = dt.fromisoformat(str(dt_utc)).timestamp()
3993
+ if dt_utc < self.start_time or dt_utc > self.end_time:
3994
+ continue
3995
+ if message1.startswith("GenWorkflow-BuildUp.cs: line 1: Clock reset"):
3996
+ message2 = "10-Postacquisition-Part3-Time"
3997
+ buildup_start = dt_utc
3998
+ times[message2].append(dt_utc)
3999
+ if message1.startswith("GenWorkflow-Sampling.cs: line 1: OPEN for VUcleaningline/VGP1"):
4000
+ message2 = "01-Buildup-Time"
4001
+ times[message2].append(dt_utc)
4002
+ if message1.startswith("GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = "):
4003
+ message2 = "Temperature Value"
4004
+ temp_value = \
4005
+ message1.split("GenWorkflow-Sampling.cs: Target temperature: key = Intensity, value = ")[-1]
4006
+ times[message2].append(int(temp_value))
4007
+ # if message1.startswith("GenWorkflow-Sampling.cs: line 1: CLOSE for VUcleaningline/VGP5"):
4008
+ # message2 = "02-Presampling-Time"
4009
+ # times[message2].append(dt_utc)
4010
+ # if message1.startswith("GenWorkflow-Prepare.cs: line 1: CLOSE for VUcleaningline/VGP3"):
4011
+ # message2 = "03-Sampling-Time"
4012
+ # times[message2].append(dt_utc)
4013
+ if message1.startswith("GenWorkflow-Prepare.cs: line 1: CLOSE for VUcleaningline/VINL2"):
4014
+ message2 = "GasCollectionEnd"
4015
+ times[message2].append(dt_utc)
4016
+ # if message1.startswith("GenWorkflow-Prepare.cs: line 15: Starting Acquisition"):
4017
+ # message2 = "05-Inlet-Time"
4018
+ # times[message2].append(dt_utc)
4019
+ if message1.startswith("GenWorkflow-Prepare.cs: line 14: CLOSE for VUcleaningline/VGP5"):
4020
+ message2 = "GasCollectionStart"
4021
+ times[message2].append(dt_utc)
4022
+ # if message1.startswith("GenWorkflow-PostAcquisition.cs: line 1: OPEN for HelixMC/Valve Ion Pump Set"):
4023
+ # message2 = "07-Acquisition-Time"
4024
+ # times[message2].append(dt_utc)
4025
+ # if message1.startswith("GenWorkflow-PostAcquisition.cs: line 5: Starting Acquisition"):
4026
+ # message2 = "08-Postacquisition-Part1-Time"
4027
+ # times[message2].append(dt_utc)
4028
+ # if message1.startswith("GenWorkflow-PostAcquisition.cs: line 1: OPEN for VUcleaningline/VPIP"):
4029
+ # message2 = "09-Postacquisition-Part2-Time"
4030
+ # times[message2].append(dt_utc)
4031
+
4032
+ return times
4033
+
4034
+
4035
+ class ArrSmpMDD:
4036
+
4037
+ def __init__(self, smp: Sample):
4038
+ self.smp = smp
4039
+
4040
+ def initial(self, loc=""):
4041
+ if loc != "":
4042
+ self.diff = DiffSample(smp=self.smp, loc=loc)
4043
+ else:
4044
+ self.diff = DiffSample(smp=self.smp)
4045
+
4046
+ def diffmulti(self, loc=""):
4047
+ if loc != "":
4048
+ self.diff_smp = DiffArrmultiFunc(smp=self.smp, loc=loc)
4049
+ else:
4050
+ self.diff_smp = DiffArrmultiFunc(smp=self.smp)
4051
+ k = self.diff_smp.main()
4052
+
4053
+ def agemon(self, loc=""):
4054
+ if loc != "":
4055
+ self.diff_smp = DiffAgemonFuncs(smp=self.smp, loc=loc)
4056
+ else:
4057
+ self.diff_smp = DiffAgemonFuncs(smp=self.smp)
4058
+ k = self.diff_smp.main()
4059
+
4060
+ def plot(self, loc=""):
4061
+ if loc != "":
4062
+ self.diff_smp = DiffDraw(smp=self.smp, loc=loc)
4063
+ else:
4064
+ self.diff_smp = DiffDraw(smp=self.smp)
4065
+ # self.diff_smp.loc = "D:\\PythonProjects\\ararpy_package\\ararpy\\examples"
4066
+ k = self.diff_smp.main()
4067
+
4068
+
4069
+ class Ran1Generator:
4070
+ def __init__(self, idum):
4071
+ self.m1 = 259200
4072
+ self.ia1 = 7141
4073
+ self.ic1 = 54773
4074
+ self.rm1 = 3.8580247e-6
4075
+
4076
+ self.m2 = 134456
4077
+ self.ia2 = 8121
4078
+ self.ic2 = 28411
4079
+ self.rm2 = 7.4373773e-6
4080
+
4081
+ self.m3 = 243000
4082
+ self.ia3 = 4561
4083
+ self.ic3 = 51349
4084
+
4085
+ self.r = np.zeros(97, dtype=np.float64)
4086
+ self.iff = 0
4087
+ self.ix1, self.ix2, self.ix3 = 0, 0, 0
4088
+
4089
+ self.count = 0
4090
+
4091
+ self.idum = idum
4092
+ self.initialize()
4093
+
4094
+ def initialize(self):
4095
+ if self.idum < 0 or self.iff == 0:
4096
+ self.iff = 1
4097
+ self.ix1 = (self.ic1 - self.idum) % self.m1
4098
+ self.ix1 = (self.ia1 * self.ix1 + self.ic1) % self.m1
4099
+ self.ix2 = self.ix1 % self.m2
4100
+ self.ix1 = (self.ia1 * self.ix1 + self.ic1) % self.m1
4101
+ self.ix3 = self.ix1 % self.m3
4102
+ for j in range(97):
4103
+ self.ix1 = (self.ia1 * self.ix1 + self.ic1) % self.m1
4104
+ self.ix2 = (self.ia2 * self.ix2 + self.ic2) % self.m2
4105
+ self.r[j] = (float(self.ix1) + float(self.ix2) * self.rm2) * self.rm1
4106
+ self.idum = 1
4107
+
4108
+ def ran1(self):
4109
+ # LCG算法生成随机数
4110
+ self.ix1 = (self.ia1 * self.ix1 + self.ic1) % self.m1
4111
+ self.ix2 = (self.ia2 * self.ix2 + self.ic2) % self.m2
4112
+ self.ix3 = (self.ia3 * self.ix3 + self.ic3) % self.m3
4113
+ j = 1 + int((97 * self.ix3) / self.m3)
4114
+ if j > 97 or j < 1:
4115
+ input('Press Enter to continue...')
4116
+ ran1 = self.r[j - 1] # Adjust index for Python's 0-based indexing
4117
+
4118
+ self.r[j - 1] = (float(self.ix1) + float(self.ix2) * self.rm2) * self.rm1
4119
+
4120
+ self.count += 1
4121
+
4122
+ print(f"{ran1 = }, {self.count = }")
4123
+
4124
+ return ran1
4125
+
4126
+
4127
+
4128
+
4129
+ def fit(x, y, sigx, sigy, ndata=None):
4130
+
4131
+ print(f"{x = }")
4132
+ print(f"{y = }")
4133
+ print(f"{sigx = }")
4134
+ print(f"{sigy = }")
4135
+
4136
+ if ndata is None:
4137
+ ndata = len(x)
4138
+ nd = 20
4139
+ imax = 20
4140
+ xerr = 0.001
4141
+ wt = []
4142
+ r = 0.
4143
+ a = 0
4144
+ b = -1.
4145
+ siga = 0
4146
+ sigb = 0
4147
+ chi2 = 0
4148
+ q = 0
4149
+ iter = 0
4150
+
4151
+ while iter <= imax:
4152
+ sx = 0.
4153
+ sy = 0.
4154
+ st2 = 0.
4155
+ st3 = 0.
4156
+ ss = 0.
4157
+ b0 = b
4158
+
4159
+ for i in range(ndata):
4160
+ wt.append(0)
4161
+ wt[i] = 1. / (sigy[i] ** 2 + b ** 2 * sigx[i] ** 2 - 2 * r * sigx[i] * sigy[i])
4162
+ ss = ss + wt[i]
4163
+ sx = sx + x[i] * wt[i]
4164
+ sy = sy + y[i] * wt[i]
4165
+
4166
+ # print(f"{x[i] = }, {y[i] = }, {wt[i] = }")
4167
+
4168
+ sxoss = sx / ss
4169
+ syoss = sy / ss
4170
+
4171
+ for i in range(ndata):
4172
+ t1 = (x[i] - sxoss) * sigy[i] ** 2
4173
+ t2 = (y[i] - syoss) * sigx[i] ** 2 * b
4174
+ t3 = sigx[i] * sigy[i] * r
4175
+ st2 = st2 + wt[i] ** 2 * (y[i] - syoss) * (t1 + t2 - t3 * (y[i] - syoss))
4176
+ st3 = st3 + wt[i] ** 2 * (x[i] - sxoss) * (t1 + t2 - b * t3 * (x[i] - sxoss))
4177
+
4178
+ b = st2 / st3
4179
+ iter = iter + 1
4180
+
4181
+ # print(f"{sxoss = }, {syoss = }, {b = }, {abs(b0 - b) = }")
4182
+
4183
+ if abs(b0 - b) > xerr:
4184
+ continue
4185
+
4186
+ a = (syoss - sxoss * b)
4187
+ # print(f"{a = }, {b = }")
4188
+ sgt1 = 0.
4189
+ sgt2 = 0.
4190
+
4191
+ for i in range(ndata):
4192
+ sgt1 = sgt1 + wt[i] * (x[i] - sxoss) ** 2
4193
+ sgt2 = sgt2 + wt[i] * x[i] ** 2
4194
+
4195
+ sigb = (1. / sgt1) ** 0.5
4196
+ siga = sigb * (sgt2 / ss) ** 0.5
4197
+ chi2 = 0.
4198
+
4199
+ for i in range(ndata):
4200
+ chi2 = chi2 + wt[i] * (y[i] - a - b * x[i]) ** 2
4201
+
4202
+ q = gammq(0.5 * (ndata - 2), 0.5 * chi2)
4203
+
4204
+ if abs(b0 - b) <= xerr:
4205
+ break
4206
+
4207
+ return a, b, siga, sigb, chi2, q
4208
+
4209
+ def gammq(a, x):
4210
+ if x < 0 or a <= 0:
4211
+ raise ValueError("ERROR(GAMMQ): x < 0 or a <= 0")
4212
+
4213
+ if x < a + 1:
4214
+ gamser, gln = gser(a, x)
4215
+ return 1.0 - gamser
4216
+ else:
4217
+ gammcf, gln = gcf(a, x)
4218
+ return gammcf
4219
+
4220
+ def gser(a, x, itmax=100, eps=3e-7):
4221
+ gln = gammln(a)
4222
+ if x <= 0:
4223
+ if x < 0:
4224
+ raise ValueError("ERROR(GSER): x < 0")
4225
+ return 0.0, gln
4226
+
4227
+ ap = a
4228
+ sum_ = 1.0 / a
4229
+ delta = sum_
4230
+ for n in range(1, itmax + 1):
4231
+ ap += 1
4232
+ delta *= x / ap
4233
+ sum_ += delta
4234
+ if abs(delta) < abs(sum_) * eps:
4235
+ break
4236
+ else:
4237
+ raise RuntimeError("ERROR(GSER): a too large, itmax too small")
4238
+
4239
+ gamser = sum_ * np.exp(-x + a * np.log(x) - gln)
4240
+ return gamser, gln
4241
+
4242
+ def gcf(a, x, itmax=100, eps=3e-7):
4243
+ gln = gammln(a)
4244
+ gold = 0.0
4245
+ a0 = 1.0
4246
+ a1 = x
4247
+ b0 = 0.0
4248
+ b1 = 1.0
4249
+ fac = 1.0
4250
+ for n in range(1, itmax + 1):
4251
+ an = float(n)
4252
+ ana = an - a
4253
+ a0 = (a1 + a0 * ana) * fac
4254
+ b0 = (b1 + b0 * ana) * fac
4255
+ anf = an * fac
4256
+ a1 = x * a0 + anf * a1
4257
+ b1 = x * b0 + anf * b1
4258
+ if a1 != 0:
4259
+ fac = 1.0 / a1
4260
+ g = b1 * fac
4261
+ if abs((g - gold) / g) < eps:
4262
+ return g * np.exp(-x + a * np.log(x) - gln), gln
4263
+ gold = g
4264
+ else:
4265
+ raise RuntimeError("ERROR(GCF): a too large, itmax too small")
4266
+
4267
+ def gammln(xx):
4268
+ cof = np.array([76.18009173, -86.50532033, 24.01409822,
4269
+ -1.231739516, 0.00120858003, -0.00000536382])
4270
+ stp = 2.50662827465
4271
+ half = 0.5
4272
+ one = 1.0
4273
+ fpf = 5.5
4274
+
4275
+ x = xx - one
4276
+ tmp = x + fpf
4277
+ tmp = (x + half) * np.log(tmp) - tmp
4278
+ ser = one
4279
+ for j in range(6):
4280
+ x += one
4281
+ ser += cof[j] / x
4282
+
4283
+ return tmp + np.log(stp * ser)
4284
+
4285
+
4286
+
4287
+
4288
+
4289
+ def conf(input_x, input_y, count=None, num=None, using_binom=False, using_normal=False):
4290
+ """
4291
+ Calculate 90% confident interval of the given distribution of cooling histories.
4292
+ Parameters
4293
+ ----------
4294
+ input_x: x, array like 2D
4295
+ input_y: y, array like 2D
4296
+ count:
4297
+
4298
+ Returns
4299
+ -------
4300
+
4301
+ """
4302
+
4303
+ input_x = np.array(input_x)
4304
+ input_y = np.array(input_y)
4305
+
4306
+ if count is None:
4307
+ try:
4308
+ count = [input_x.shape[1]] * input_x.shape[0]
4309
+ except:
4310
+ return [], [], [], [], []
4311
+
4312
+ x_start = min([min(xi) for xi in input_x])
4313
+ x_end = max([max(xi) for xi in input_x])
4314
+ x_steps_num = int(x_end - x_start) if num is None else num
4315
+ dx = (x_end - x_start) / x_steps_num
4316
+
4317
+ x_conf = []
4318
+ y1_conf = []
4319
+ y2_conf = []
4320
+ y3_conf = []
4321
+ y4_conf = []
4322
+
4323
+ for i in range(x_steps_num + 1):
4324
+ data = []
4325
+ # 置信曲线的x,即age
4326
+ xi = x_start + i * dx
4327
+ # 获取各个冷却曲线中对应age的温度temp,用临近两个年龄的斜率插值计算
4328
+ for j in range(len(input_x)):
4329
+ if xi > max(input_x[j]):
4330
+ continue
4331
+ yi = 0
4332
+ if xi == input_x[j, 0]:
4333
+ yi = input_y[j, 0]
4334
+ elif xi == input_x[j, count[j] - 1]:
4335
+ yi = input_y[j, count[j] - 1]
4336
+ else:
4337
+ for k in range(1, count[j]):
4338
+ if (input_x[j, k] > xi >= input_x[j, k - 1]) or input_x[j, k - 1] > xi >= input_x[j, k]:
4339
+ slope = (input_y[j, k] - input_y[j, k - 1]) / (input_x[j, k] - input_x[j, k - 1])
4340
+ yi = input_y[j, k - 1] + slope * (xi - input_x[j, k - 1])
4341
+ break
4342
+ data.append(yi)
4343
+
4344
+ data = np.array(data)
4345
+ n = len(data)
4346
+
4347
+ if n < 15:
4348
+ continue
4349
+
4350
+ ave = np.average(data)
4351
+ dev = data - ave
4352
+ adev = sum(abs(dev)) / n
4353
+ var = sum(dev ** 2) / (n - 1)
4354
+ sdev = np.sqrt(var)
4355
+ skew = sum(dev ** 3) / (n * sdev ** 3) if var != 0 else 0
4356
+ curt = sum(dev ** 4) / (n * var ** 2) - 3 if var != 0 else 0
4357
+
4358
+ # 中位数
4359
+ x_med = np.median(data)
4360
+
4361
+ data.sort()
4362
+
4363
+ if using_binom:
4364
+ # 计算二项分布百分位点
4365
+ try:
4366
+ j1, j2 = binom(n + 1)
4367
+ except ValueError:
4368
+ continue
4369
+
4370
+ nperc = round(n * 0.05)
4371
+
4372
+ x_conf.append(xi)
4373
+ y1_conf.append(data[j1 - 1])
4374
+ y2_conf.append(data[j2 - 1])
4375
+ y3_conf.append(data[int(nperc) - 1])
4376
+ y4_conf.append(data[int(n - nperc) - 1])
4377
+
4378
+ elif using_normal:
4379
+ mean = np.mean(data)
4380
+ var = np.var(data)
4381
+ std = np.std(data)
4382
+
4383
+ x_conf.append(xi)
4384
+ y1_conf.append(mean - std)
4385
+ y2_conf.append(mean + std)
4386
+ y3_conf.append(mean - 2 * std)
4387
+ y4_conf.append(mean + 2 * std)
4388
+
4389
+ return x_conf, y1_conf, y2_conf, y3_conf, y4_conf
4390
+
4391
+
4392
+ def binom(n):
4393
+ # 95% 置信区间百分位点
4394
+
4395
+ def factln(n):
4396
+ return math.lgamma(n + 1)
4397
+
4398
+ def bico(n, k):
4399
+ return math.exp(factln(n) - factln(k) - factln(n - k))
4400
+
4401
+ if n % 2 == 0:
4402
+ nmed = n // 2
4403
+ else:
4404
+ nmed = (n + 1) // 2
4405
+
4406
+ f = 0
4407
+ j1 = f
4408
+
4409
+ # SEARCH FOR F(M)=0.5
4410
+ for j in range(nmed, 0, -1):
4411
+ faux = f
4412
+ f = 0.0
4413
+ j1 = j
4414
+ for k in range(1, j + 1):
4415
+ f += bico(n, k) * 0.5 ** n
4416
+
4417
+ if f <= 0.05:
4418
+ if abs(faux - 0.05) < abs(f - 0.05):
4419
+ j1 = j1 + 1
4420
+ break
4421
+
4422
+ for j in range(nmed + 1, n + 1):
4423
+ faux = f
4424
+ f = 0.0
4425
+ j2 = j
4426
+ for k in range(1, j + 1):
4427
+ f += bico(n, k) * 0.5 ** n
4428
+
4429
+ if f >= 0.95:
4430
+ if abs(faux - 0.95) < abs(f - 0.95):
4431
+ j2 = j2 - 1
4432
+ return j1, j2
4433
+
4434
+ raise ValueError("Error on binom subroutine")
4435
+
4436
+
4437
+ def kahan_sum(input):
4438
+ sum = 0
4439
+ c = 0 # A running compensation for lost low-order bits.
4440
+ for i in input:
4441
+ y = i - c # So far, so good: c is zero.
4442
+ t = sum + y # Alas, sum is big, y small, so low-order digits of y are lost.
4443
+ c = (t - sum) - y # (t - sum) recovers the high-order part of y; subtracting y recovers -(low part of y)
4444
+ sum = t # Algebraically, c should always be zero. Beware eagerly optimising compilers!
4445
+ return sum
4446
+
4447
+
4448
+ def get_random_index(length: int = 7):
4449
+ return ''.join(random.choices(string.digits, k=length))
4450
+
4451
+
4452
+ def get_random_dir(path: str, length=7, random_index = ""):
4453
+ try:
4454
+ if random_index == "":
4455
+ random_index = get_random_index(length=length)
4456
+ destination_folder = os.path.join(path, random_index)
4457
+ os.makedirs(destination_folder, exist_ok=False)
4458
+ return destination_folder, random_index
4459
+ except FileExistsError:
4460
+ random_index = ""
4461
+ return get_random_dir(path=path, length=length)
4462
+
4463
+
4464
+ def run_agemon_dll(sample: Sample, source_dll_path: str, loc: str, data, max_age: float = 30.):
4465
+ # 加载 DLL
4466
+ # 获取源 DLL 文件名和扩展名
4467
+ base_name, ext = os.path.splitext(os.path.basename(source_dll_path))
4468
+ # 构建新的 DLL 文件名
4469
+ new_dll_path = os.path.join(loc, f"{base_name}{ext}")
4470
+ # 复制并重命名 DLL 文件
4471
+ shutil.copy(source_dll_path, new_dll_path)
4472
+
4473
+ agemon = DiffAgemonFuncs(smp=sample, loc=loc)
4474
+
4475
+ agemon.ni = len(data)
4476
+ agemon.nit = agemon.ni
4477
+ agemon.max_plateau_age = max_age
4478
+ data = ap.calc.arr.transpose(data)
4479
+ agemon.telab = [i + 273.15 for i in data[3]]
4480
+ agemon.tilab = [i / 5.256E+11 for i in data[4]] # 1 Ma = 525600000000 minutes
4481
+ for i in range(agemon.nit):
4482
+ if agemon.telab[i] > 1373:
4483
+ agemon.ni = i
4484
+ break
4485
+ agemon.ya = data[5]
4486
+ agemon.sig = data[6]
4487
+ agemon.a39 = data[7]
4488
+ agemon.sig39 = data[8]
4489
+ agemon.xs = data[9]
4490
+ agemon.xs.insert(0, 0)
4491
+ agemon.ya.insert(0, 0)
4492
+
4493
+ agemon.xs = np.array(agemon.xs)
4494
+ agemon.xs = np.where(agemon.xs >= 1, 0.9999999999999999, agemon.xs)
4495
+ # agemon.xs[-1] = 0.9999999999999999 if agemon.xs[-1] >= 1 else agemon.xs[-1]
4496
+
4497
+ xs = agemon.xs # array
4498
+ age = agemon.ya # array
4499
+ sig = agemon.sig # array
4500
+ e = agemon.e_arr # array
4501
+ d0 = agemon.d0_arr # array
4502
+ vc = agemon.vc_arr # array
4503
+ nsts = agemon.nst_arr # array
4504
+ temp = agemon.telab # array
4505
+ heating_time = agemon.tilab # array
4506
+ kk = agemon.kk # int
4507
+ max_age = agemon.max_plateau_age # double
4508
+ nsteps = agemon.ni # int
4509
+
4510
+ # print(f"{xs = }")
4511
+ # print(f"{age = }")
4512
+ # print(f"{sig = }")
4513
+ # print(f"{e = }")
4514
+ # print(f"{d0 = }")
4515
+ # print(f"{vc = }")
4516
+ # print(f"{nsts = }")
4517
+ # print(f"{temp = }")
4518
+ # print(f"{heating_time = }")
4519
+ # print(f"{kk = }")
4520
+ # print(f"{max_age = }")
4521
+ # print(f"{nsteps = }")
4522
+
4523
+ d0_flatten = d0.flatten()
4524
+ vc_flatten = vc.flatten()
4525
+
4526
+ # filepath = "D:\\DjangoProjects\\webarar\\private\\mdd"
4527
+ # print(filepath.encode())
4528
+ filepath = bytes(loc, "utf-8")
4529
+ samplename = bytes(sample.name(), "utf-8")
4530
+
4531
+ mylib = ctypes.CDLL(new_dll_path)
4532
+ try:
4533
+ run = mylib.run
4534
+ run.restype = None
4535
+ result = run(
4536
+ (ctypes.c_double * len(xs))(*xs), ctypes.c_int(len(xs)),
4537
+ (ctypes.c_double * len(age))(*age), ctypes.c_int(len(age)),
4538
+ (ctypes.c_double * len(sig))(*sig), ctypes.c_int(len(sig)),
4539
+ (ctypes.c_double * len(e))(*e), ctypes.c_int(len(e)),
4540
+ (ctypes.c_double * len(d0_flatten))(*d0_flatten), ctypes.c_int(d0.shape[0]), ctypes.c_int(d0.shape[1]),
4541
+ (ctypes.c_double * len(vc_flatten))(*vc_flatten), ctypes.c_int(vc.shape[0]), ctypes.c_int(vc.shape[1]),
4542
+ (ctypes.c_int * len(nsts))(*nsts), ctypes.c_int(len(nsts)),
4543
+ (ctypes.c_double * len(temp))(*temp), ctypes.c_int(len(temp)),
4544
+ (ctypes.c_double * len(heating_time))(*heating_time), ctypes.c_int(len(heating_time)),
4545
+ ctypes.c_int(kk),
4546
+ ctypes.c_double(max_age),
4547
+ ctypes.c_int(nsteps),
4548
+ ctypes.c_char_p(filepath),
4549
+ ctypes.c_char_p(samplename)
4550
+ )
4551
+ except:
4552
+ pass
4553
+ else:
4554
+ del mylib
4555
+ gc.collect()
4556
+
4557
+ return
4558
+
4559
+
4560
+ def dr2_popov(f, ti):
4561
+ """
4562
+
4563
+ Parameters
4564
+ ----------
4565
+ f: cumulative 39Ar released, array
4566
+ ti: heating time, array
4567
+
4568
+ Returns
4569
+ -------
4570
+
4571
+ """
4572
+
4573
+ # =IF(M4<85,( (-6/(PI()^(3/2))+SQRT(36/(PI()^3)-4*M4/100*3/(PI()^2)))/(-6/(PI()^2)))^2/(PI()^2 )/D4/60,(LN(((M4)/100-1)/(-6/PI()^2))/(-PI()^2))/D4/60)
4574
+
4575
+ # =IF(M5<85,( 2/PI()^2*( SQRT(PI()^2-(PI()^3)*M4/100/3)-SQRT(PI()^2-(PI()^3)*M5/100/3)) +M4/100/3-M5/100/3 )/D5/60, LN((1-M4/100)/(1-M5/100))/PI()^2/D5/60)
4576
+
4577
+ f = np.array(f)
4578
+ ti = np.array(ti)
4579
+ n = min(len(f), len(ti))
4580
+ ti = ti * 60 # in seconds
4581
+ pi = math.pi
4582
+ pi = 3.141592654
4583
+ dr2 = np.zeros(n)
4584
+
4585
+ if f[-1] >= 1:
4586
+ f[-1] = 0.99999999
4587
+
4588
+ # Popov 2020
4589
+ a, b = 0, 0
4590
+ for i in range(len(f)):
4591
+ if i == 0:
4592
+ if f[i] < 85:
4593
+ a = 2 / pi ** 2 * math.sqrt(pi ** 2 - (pi ** 3) * f[i] / 3) + f[i] / 3
4594
+ dr2[i] = ((-6 / (pi ** 1.5) + math.sqrt(36 / pi ** 3 - 4 * f[i] * 3 / pi ** 2)) / (
4595
+ -6 / pi ** 2)) ** 2 / pi ** 2 / ti[i]
4596
+ else:
4597
+ a = 1 - f[i]
4598
+ dr2[i] = (math.log((f[i] - 1) / (-6 / pi ** 2)) / pi ** 2) / ti[i]
4599
+ else:
4600
+ if f[i] < 85:
4601
+ a = 2 / pi ** 2 * math.sqrt(pi ** 2 - (pi ** 3) * f[i] / 3) + f[i] / 3
4602
+ dr2[i] = (b - a) / ti[i]
4603
+ else:
4604
+ dr2[i] = math.log((1 - f[i - 1]) / (1 - f[i])) / pi ** 2 / ti[i]
4605
+ b = a
4606
+
4607
+ print(f"popov {dr2 = }")
4608
+
4609
+ return dr2, np.log(dr2)
4610
+
4611
+
4612
+ def dr2_lovera(f, ti, ar, sar):
4613
+ # Lovera
4614
+ f = np.array(f)
4615
+ ti = np.array(ti)
4616
+ ar = np.array(ar)
4617
+ sar = np.array(sar)
4618
+ ti = ti * 60 # in seconds
4619
+ pi = math.pi
4620
+ pi = 3.141592654
4621
+
4622
+ # sf = sqrt(b ** 2 * siga ** 2 + a ** 2 * sigb ** 2) / (a + b) ** 2
4623
+ sf = [math.sqrt(sar[i + 1:].sum() ** 2 * (sar[:i + 1] ** 2).sum() + ar[:i + 1].sum() ** 2 * (sar[i + 1:] ** 2).sum()) / ar.sum() ** 2 for i in range(len(ar) - 1)]
4624
+ sf.append(0)
4625
+
4626
+ f = np.where(f >= 1, 0.9999999999999999, f)
4627
+
4628
+ imp = 2
4629
+ # imp = 1
4630
+ dtr2 = [pi * (fi / 4) ** 2 if fi <= 0.5 else math.log((1 - fi) * pi ** 2 / 8) / (- pi ** 2) for fi in f]
4631
+ dr2 = [(dtr2[i] - (dtr2[i - 1] if i > 0 else 0)) / ti[i] * imp ** 2 for i in range(len(dtr2))]
4632
+ xlogd = [np.log10(i) for i in dr2]
4633
+
4634
+ wt = errcal(f, ti, a39=ar, sig39=sar)
4635
+
4636
+ return dr2, xlogd, wt
4637
+
4638
+
4639
+ def dr2_yang(f, ti):
4640
+ f = np.array(f)
4641
+ ti = np.array(ti)
4642
+ n = min(len(f), len(ti))
4643
+ ti = ti * 60 # in seconds
4644
+ pi = math.pi
4645
+ pi = 3.141592654
4646
+ dr2 = np.zeros(n)
4647
+
4648
+ if f[-1] >= 1:
4649
+ f[-1] = 0.99999999
4650
+
4651
+ def _dr2(_fi):
4652
+ if _fi <= 0.85:
4653
+ return (1 - math.sqrt(1 - pi * _fi / 3)) ** 2 / pi
4654
+ else:
4655
+ return math.log((1 - _fi) / (6 / pi ** 2)) / - (pi ** 2)
4656
+
4657
+ for i in range(len(f)):
4658
+ if i == 0:
4659
+ dr2[i] = _dr2(f[i]) / ti[i]
4660
+ else:
4661
+ dr2[i] = _dr2((f[i] - f[i - 1]) / (1 - f[i - 1])) / ti[i]
4662
+
4663
+ print(f"yang {dr2 = }")
4664
+
4665
+ return dr2, np.log(dr2)
4666
+
4667
+
4668
+ def errcal(f, ti, a39, sig39):
4669
+
4670
+ # ns = 200
4671
+ # r = 1.987E-3
4672
+ # a0 = -0.19354
4673
+ # a1 = -0.62946
4674
+ # a2 = 0.13505
4675
+ # a3 = -0.01528
4676
+
4677
+ f = np.array(f)
4678
+ ti = np.array(ti) # in seconds
4679
+
4680
+ ee = 0.4342944819
4681
+ sigt0 = 90.
4682
+
4683
+ ni = len(f)
4684
+ sumat = sum(a39)
4685
+ sigsm = [i / sumat for i in sig39]
4686
+ siga = [sig39[i] / a39[i] for i in range(ni)]
4687
+
4688
+ an1 = math.pi ** 2
4689
+ sigat = 0.
4690
+ swt = 0.
4691
+ sigzit = [0.]
4692
+ sigf = [0]
4693
+ wt = []
4694
+
4695
+ for i in range(ni):
4696
+ sigat += sigsm[i] ** 2
4697
+ sigf.append(sigat)
4698
+
4699
+ f = np.insert(f, 0, 0)
4700
+
4701
+ for i in range(1, ni + 1):
4702
+ sigzit.append(0)
4703
+ if f[i] <= 0.5:
4704
+ fp = f[i] + f[i - 1]
4705
+ as1 = 1. / fp ** 2 - 2. / fp
4706
+ as2 = (f[i] ** 2 - 2 * f[i] * (f[i] ** 2 - f[i - 1] ** 2)) / fp ** 2
4707
+ sigzit[i] = 4. * (sigat + sigf[i - 1] * as1 + siga[i - 1] ** 2 * as2)
4708
+ else:
4709
+ dzit2 = (np.log((1 - f[i]) / (1 - f[i - 1])) / an1) ** 2
4710
+ as1 = ((f[i] - f[i - 1]) / an1) ** 2 / (1 - f[i - 1]) ** 2
4711
+ sigzit[i] = ((sigat - sigf[i]) / (1 - f[i]) ** 2 + siga[i - 1] ** 2) * as1
4712
+ sigzit[i] = sigzit[i] / dzit2
4713
+
4714
+ print(f"{sigzit = }")
4715
+
4716
+ for i in range(ni):
4717
+ sigt = (sigt0 / ti[i]) ** 2
4718
+ wt.append(ee * (sigt + sigzit[i + 1]) ** 0.5)
4719
+ swt = swt + wt[i]
4720
+ rate = (sigzit[i + 1] / sigt) ** 0.5
4721
+
4722
+ print(f"lovera {wt = }")
4723
+
4724
+
4725
+ ## 下面是我重新改写 计算的 与lovera的结果接近但不一致
4726
+
4727
+ # a39 = np.insert(a39, 0, 0)
4728
+ # sig39 = np.insert(sig39, 0, 0)
4729
+ #
4730
+ # wt = []
4731
+ # for i in range(0, ni):
4732
+ #
4733
+ # if f[i + 1] <= 0.5:
4734
+ # sigt = (sigt0 / ti[i]) ** 2
4735
+ # fp = (f[i + 1] + f[i])
4736
+ # a = sig39[i + 1] / a39[i + 1]
4737
+ # wt.append(ee * (sigt + 4 * (a ** 2 - 2 * a / a39.sum() + sigat) / (a39.sum() * fp) ** 2) ** 0.5)
4738
+ # else:
4739
+ # sigt = (sigt0 / ti[i]) ** 2
4740
+ # sigf = (a39[i + 1] ** 2 / a39[i + 2:].sum() ** 2 * sig39[i + 2:].sum() ** 2 + sig39[i + 1] ** 2) / a39[i + 1:].sum() ** 2
4741
+ # wt.append(ee * (sigt + (1 / math.log((1 - f[i + 1]) / (1 - f[i]))) ** 2 * sigf) ** 0.5)
4742
+ #
4743
+ # print(f"new function {wt = }")
4744
+
4745
+ return wt