D2MatE Top
実行例: [tkprog_X_path]/optimize/optimize_peakfit/optimize_peakfit.py
以下に典型的な実行例を示す。代表的なmode引数は、--modeが不要。
実行ディレクトリ: [tkprog_X_path]/optimize/optimize_peakfit/test
入力データ: [tkprog_X_path]/optimize/optimize_peakfit/test/xrd.xlsx
入力ファイルのデフォルトは peaks.xlsx になっている。
変更する場合は、起動時引数 --infile=path名 で指定する。
特徴: 複数本のピークをLorentz関数でフィッティングする。Kα1とKα2の分離は行わない。
ピークサーチにより回折角度と半値幅を推測し、線形最小二乗法により強度の初期値を推測するため、
フィッティングパラメータ設定ファイル optimize_peakfit1_fit_config.xlsx
が不要。
- 既に実行したファイルがある場合は削除する
test> python ..\optimize_peakfit.py clean
ファイルを削除するかどうか聞いてくるので、
・ すべて削除する場合は all
・ 聞かれているファイル群だけ削除する場合は yes
・ 削除しない場合は no
を入力し、ENTERを押す
- 初期化: 設定ファイル xrd.in、フィッティング変数ファイル
xrd_parameters.csv を作成
全範囲でピークサーチをすると多くなりすぎるので、2θ
(x) = 20~40°で初期化を行う。
実行に必要なファイル: xrd.xlsx
test> python ..\optimize_peakfit.py init --xmin=20
--xmax=40
initの前段でcleanを実行するため、1と同じことを聞かれるので、all/yes/noを回答する。
ピークサーチにより回折角度と半値幅を推測し、線形最小二乗法により強度の初期値を推測し、
フィッティグパラメータファイル xrd_parameters.csv
を作成する。
出力例(抜粋):
Linear variables:
varname : ['bg_c0', 'I01', 'I02', 'I03', 'I04', 'I05', 'I06', 'I07', 'I08']
optid : [0, 1, 1, 1, 1, 1, 1, 1, 1]
fitting parameters: [0.0, 50125.053555801125, 1143036.7927514615, 195476.18598536804, 241762.52547497716, 228528.25955055628, 12674.147402271818, 391628.07759082154, 130794.33228714138]
constants:
xc: None 24.1 29.88 30.46 31.08 32.74 33.84 37.32 37.8
w: None 0.2 0.22 0.4 0.2 0.2 0.12 0.22 0.18
mlsq_general_optid:
nvars = 9
nmatrix = 8
ai = 0 5.01e+04 1.14e+06 1.95e+05 2.42e+05 2.29e+05 1.27e+04 3.92e+05 1.31e+05
linid = 0 1 1 1 1 1 1 1 1
matrix index= - 0 1 2 3 4 5 6 7
nData = 1001
optimiz_mup.mslq_general3:: Vector and Matrix:
Si = 8.517e+05, 1.939e+07, 1.587e+07, 5.439e+06, 4.044e+06, 3.45e+05, 6.872e+06, 3.329e+06
Sij= 15.71, 0.0863, 0.1843, 0.05132, 0.03351, 0.01267, 0.01646, 0.01133
0.0863, 17.28, 11.89, 1.796, 0.3473, 0.08922, 0.05996, 0.03935
0.1843, 11.89, 31.42, 10.13, 1.356, 0.3351, 0.1797, 0.1202
0.05132, 1.796, 10.13, 15.71, 0.8619, 0.1562, 0.07396, 0.04721
0.03351, 0.3473, 1.356, 0.8619, 15.71, 0.9192, 0.1369, 0.08315
0.01267, 0.08922, 0.3351, 0.1562, 0.9192, 9.425, 0.1152, 0.06439
0.01646, 0.05996, 0.1797, 0.07396, 0.1369, 0.1152, 17.28, 6.372
0.01133, 0.03935, 0.1202, 0.04721, 0.08315, 0.06439, 6.372, 14.14
ai(new)= 4.651e+04, 1.082e+06, 2.069e+04, 1.953e+05, 2.176e+05, -3820, 3.673e+05, 6.483e+04
ai(org)= 0, 5.013e+04, 1.143e+06, 1.955e+05, 2.418e+05, 2.285e+05, 1.267e+04, 3.916e+05, 1.308e+05
ai_all= 0, 4.651e+04, 1.082e+06, 2.069e+04, 1.953e+05, 2.176e+05, -3820, 3.673e+05, 6.483e+04
linear fit results:
varname : bg_c0 I01 I02 I03 I04 I05 I06 I07 I08
ai_new : 4.651e+04 1.082e+06 2.069e+04 1.953e+05 2.176e+05 -3820 3.673e+05 6.483e+04
ai_all : 0 4.651e+04 1.082e+06 2.069e+04 1.953e+05 2.176e+05 -3820 3.673e+05 6.483e+04
optid_lin : 0 1 1 1 1 1 1 1 1
all parameters:
varname : bg_c0 I01 xc1 w1 I02 xc2 w2 I03 xc3 w3 I04 xc4 w4 I05 xc5 w5 I06 xc6 w6 I07 xc7 w7 I08 xc8 w8
fit.pk(org) : 0 5.013e+04 24.1 0.2 1.143e+06 29.88 0.22 1.955e+05 30.46 0.4 2.418e+05 31.08 0.2 2.285e+05 32.74 0.2 1.267e+04 33.84 0.12 3.916e+05 37.32 0.22 1.308e+05 37.8 0.18
pk_all(new) : 0 4.651e+04 24.1 0.2 1.082e+06 29.88 0.22 2.069e+04 30.46 0.4 1.953e+05 31.08 0.2 2.176e+05 32.74 0.2 -3820 33.84 0.12 3.673e+05 37.32 0.22 6.483e+04 37.8 0.18
Save configuration parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd.in]
Error in tkfile.open(): [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd.in] does not exist
Warning in tkinifile.WriteString: Can not read [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd.in]
Save fitting parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd_parameters.csv] (save_parameters)
time at startup: 24/11/19 13:39:25
time at end: 24/11/19 13:39:28
Elapsed time from startup to end: 2.93004 sec
作成されるファイル:
config parameter file : D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit1\test\peaks.in
fitting parameter file: D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit1\test\peaks_parameters.csv
- 入力データの確認: 入力データファイル peaks.xlsx
を読み込み、プロットする
test> python ..\optimize_peakfit1.py plot --xmin=20
--xmax=40
- フィッティング変数の初期値の確認:
入力データファイル peaks.xlsx
とフィッティング変数ファイル peaks_parameters.csv
を読み込み、
入力データとシミュレーション結果をプロットする
test> python ..\optimize_peakfit1.py sim --xmin=20
--xmax=40
- フィッティング: 非線形最小二乗法を実行する
test> python ..\optimize_peakfit1.py fit
- コンソール出力 (peaks-out.txt):
Final parameters:
00: bg_c0= -1084.17 (id=1) (linear=0) penality: 1 * (-1e+10 - 1e+10)
01: I01= 49836.8 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
02: xc1= 24.0783 (id=1) (linear=0) penality: 1 * (0 - 180)
03: w1= 0.192073 (id=1) (linear=0) penality: 1 * (0 - 100)
04: I02= 1.11443e+06 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
05: xc2= 29.8781 (id=1) (linear=0) penality: 1 * (0 - 180)
06: w2= 0.196387 (id=1) (linear=0) penality: 1 * (0 - 100)
07: I03= 58210.9 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
08: xc3= 30.3935 (id=1) (linear=0) penality: 1 * (0 - 180)
09: w3= 0.423976 (id=1) (linear=0) penality: 1 * (0 - 100)
10: I04= 196342 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
11: xc4= 31.0659 (id=1) (linear=0) penality: 1 * (0 - 180)
12: w4= 0.186371 (id=1) (linear=0) penality: 1 * (0 - 100)
13: I05= 221120 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
14: xc5= 32.7201 (id=1) (linear=0) penality: 1 * (0 - 180)
15: w5= 0.199356 (id=1) (linear=0) penality: 1 * (0 - 100)
16: I06= 1032.92 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
17: xc6= 66.0772 (id=1) (linear=0) penality: 1 * (0 - 180)
18: w6= 0 (id=1) (linear=0) penality: 1 * (0 - 100)
19: I07= 375113 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
20: xc7= 37.3201 (id=1) (linear=0) penality: 1 * (0 - 180)
21: w7= 0.201038 (id=1) (linear=0) penality: 1 * (0 - 100)
22: I08= 72114.5 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
23: xc8= 37.7768 (id=1) (linear=0) penality: 1 * (0 - 180)
24: w8= 0.214249 (id=1) (linear=0) penality: 1 * (0 - 100)
fmin= 1e+300
Save configuration parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd.in]
Save fitting parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd_parameters.csv] (save_parameters)
Final data:
2Theta I initial final
20 4995 859.5 -265.9
21 652 1107 -27.6
22 559.3 1561 415.4
23 1719 2960 1834
24 4.366e+04 3.918e+04 4.351e+04
25 2284 4979 3603
26 3539 4788 3398
27 5843 7684 6040
28 1.401e+04 1.67e+04 1.419e+04
29 5.91e+04 6.784e+04 5.949e+04
30 8.487e+05 8.506e+05 8.421e+05
31 2.323e+05 2.192e+05 2.291e+05
32 3.563e+04 3.716e+04 3.609e+04
33 8.211e+04 8.984e+04 8.2e+04
34 7988 9991 9880
35 5412 7866 6396
36 1.028e+04 1.321e+04 1.104e+04
37 1.114e+05 1.228e+05 1.119e+05
38 6.439e+04 6.515e+04 6.495e+04
39 7447 8646 7355
40 3380 3706 2469
Save input, initial, and final data to [xrd-fit.xlsx]
Plot optimized
*** fit.last_message: Message in tkFit_mxy_flex._callback(): xdiff=4.6177e-05 becomes smaller than xatol=0.0001
- フィッティング結果が不十分であれば、フィッティング変数ファイル
peaks_parameters.csv を編集して変数名を調整し、再度 fit
を実行する
- 変数の誤差:
フィッティングが終了したら、尤度関数を計算し、フィッティング結果の精度を確認する
test> python ..\optimize_peakfit1.py error --xmin=20
--xmax=40
コンソール出力 (peaks-out.txt):
Accuracy within one sigma:
000: bg_c0 : -1084.17 -56.65 + 56.21 in ( -1140.82 - -1027.96)
001: I01 : 49836.8 -254.4 + 831.8 in ( 49582.4 - 50668.6)
002: xc1 : 24.0783 -0.002503 + 0.002518 in ( 24.0758 - 24.0808)
003: w1 : 0.192073 -0.002452 + 0.002492 in ( 0.189621 - 0.194565)
004: I02 : 1.11443e+06 -67.01 + 3172 in ( 1.11437e+06 - 1.1176e+06)
005: xc2 : 29.8781 -0.0001193 + 9.752e-05 in ( 29.878 - 29.8782)
006: w2 : 0.196387 -0.0001114 + 0.0001067 in ( 0.196276 - 0.196494)
007: I03 : 58210.9 -1856 + 52.18 in ( 56354.4 - 58263)
008: xc3 : 30.3935 -0.003164 + 0.00325 in ( 30.3903 - 30.3967)
009: w3 : 0.423976 -0.003241 + 0.003293 in ( 0.420735 - 0.427269)
010: I04 : 196342 -123.1 + 1779 in ( 196219 - 198122)
011: xc4 : 31.0659 -0.000634 + 0.0006202 in ( 31.0653 - 31.0666)
012: w4 : 0.186371 -0.000606 + 0.000636 in ( 0.185765 - 0.187007)
013: I05 : 221120 -221 + 925 in ( 220899 - 222045)
014: xc5 : 32.7201 -0.0005703 + 0.0005755 in ( 32.7195 - 32.7206)
015: w5 : 0.199356 -0.0005818 + 0.0005674 in ( 0.198775 - 0.199924)
016: I06 : 1032.92 * + * in ( * - * )
017: xc6 : 66.0772 * + * in ( * - * )
018: w6 : 0 * + 4.865 in ( * - 4.86527)
019: I07 : 375113 -64.37 + 3239 in ( 375049 - 378352)
020: xc7 : 37.3201 -0.0003222 + 0.0003405 in ( 37.3197 - 37.3204)
021: w7 : 0.201038 -0.0003389 + 0.0003424 in ( 0.200699 - 0.201381)
022: I08 : 72114.5 -74.36 + 2582 in ( 72040.1 - 74696.3)
023: xc8 : 37.7768 -0.001775 + 0.001774 in ( 37.775 - 37.7785)
024: w8 : 0.214249 -0.001823 + 0.001823 in ( 0.212426 - 0.216072)
例えば最後の行は、
・ w8 (8本目のピークの半値幅) の
フィッティング最適値が 0.214249
・ 尤度関数が exp(-S2 / 2Δw2) = 0.5
を満たす w の範囲 (正規分布の標準偏差) が 0.214249 - 0.001823 ~ 0.214249 + 0.001823
であることを示している。
尤度関数の最大値が赤線 (フィッティング最適値)
からずれている場合は、最適解に到達していないことを意味している。
尤度関数の幅が広い場合は、その変数を精度よく決定できないことを示している。
注意:
最適化した値で尤度関数が最大になっていないパラメータがあるので、妥当性を再検討する。
ここでは自動的にピークサーチを行ったので、不要なピークが含まれている
- LASSO回帰: 不要と思われるピークを提案してくれる
test> python ..\optimize_peakfit1.py lasso --xmin=20
--xmax=40
下のグラフから、正則化定数αを増やしていくと、I01,
I08, I05,I03の順番で係数が0になることがわかる。
fitの結果から強度パラメータを抜き出すと、
Final parameters:
01: I01= 49836.8 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
04: I02= 1.11443e+06 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
07: I03= 58210.9 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
10: I04= 196342 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
13: I05= 221120 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
16: I06= 1032.92 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
19: I07= 375113 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
22: I08= 72114.5 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
これらの回折角度は
Final parameters:
02: xc1= 24.0783 (id=1) (linear=0) penality: 1 * (0 - 180)
05: xc2= 29.8781 (id=1) (linear=0) penality: 1 * (0 - 180)
08: xc3= 30.3935 (id=1) (linear=0) penality: 1 * (0 - 180)
11: xc4= 31.0659 (id=1) (linear=0) penality: 1 * (0 - 180)
14: xc5= 32.7201 (id=1) (linear=0) penality: 1 * (0 - 180)
17: xc6= 66.0772 (id=1) (linear=0) penality: 1 * (0 - 180)
20: xc7= 37.3201 (id=1) (linear=0) penality: 1 * (0 - 180)
23: xc8= 37.7768 (id=1) (linear=0) penality: 1 * (0 - 180)
であり、xc2とxc3、xc7とxc8が近いことがわかるので、弱いピーク
#3と#7を削除する。
- xrd_parameters.csvからピーク#3と#7のパラメータを削除する
varname,unit,pk_scale,optid,linid,pk,dx,kmin,kmax,kpenalty
bg_c0,,,1,0,-1084.1710623279334,0.1,-1.000000e+10,1.000000e+10,1
I01,,,1,1,49836.80388396804,1,-1.000000e+10,1.000000e+10,1
xc1,,,1,0,24.07826592868892,0.5,0,180,1
w1,,,1,0,0.19207272330526537,0.2,0,100,1
I02,,,1,1,1114432.9796296076,1,-1.000000e+10,1.000000e+10,1
xc2,,,1,0,29.878107965657684,0.5,0,180,1
w2,,,1,0,0.19638701408940276,0.2,0,100,1
I04,,,1,1,196342.25888826093,1,-1.000000e+10,1.000000e+10,1
xc4,,,1,0,31.065931193335476,0.5,0,180,1
w4,,,1,0,0.18637077173755823,0.2,0,100,1
I05,,,1,1,221119.70931944283,1,-1.000000e+10,1.000000e+10,1
xc5,,,1,0,32.72006994455345,0.5,0,180,1
w5,,,1,0,0.19935632981909376,0.2,0,100,1
I06,,,1,1,1032.9211622936602,1,-1.000000e+10,1.000000e+10,1
xc6,,,1,0,66.07715035546582,0.5,0,180,1
w6,,,1,0,0,0.2,0,100,1
注意:
#6のピークの半値幅が0になってしまったので、他のピークを参考に修正
w6,,,1,0,0.2,0.2,0,100,1
I08,,,1,1,72114.48436247082,1,-1.000000e+10,1.000000e+10,1
xc8,,,1,0,37.77676618011259,0.5,0,180,1
w8,,,1,0,0.81424944837144938,0.2,0,100,1
注意: ピークを減らして sim
をしたところ、#8のピークの半値幅が広すぎたので、小さく変更
w8,,,1,0,0.21424944837144938,0.2,0,100,1
- 線形最小二乗法を再実行し、係数の初期値を決定
test> python ..\optimize_peakfit1.py lfit --xmin=20 --xmax=40
lfitで実行した場合は、シミュレーション図をプロットする
(initの場合はグラフは描かない)
- フィッティング: 非線形最小二乗法を再実行する
test> python ..\optimize_peakfit1.py fit
コンソール出力 (peaks-out.txt):
Final parameters:
00: bg_c0= 1340 (id=1) (linear=0) penality: 1 * (-1e+10 - 1e+10)
01: I01= 50370.9 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
02: xc1= 24.0784 (id=1) (linear=0) penality: 1 * (0 - 180)
03: w1= 0.187958 (id=1) (linear=0) penality: 1 * (0 - 100)
04: I02= 1.12519e+06 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
05: xc2= 29.8826 (id=1) (linear=0) penality: 1 * (0 - 180)
06: w2= 0.206628 (id=1) (linear=0) penality: 1 * (0 - 100)
07: I04= 198745 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
08: xc4= 31.0453 (id=1) (linear=0) penality: 1 * (0 - 180)
09: w4= 0.239953 (id=1) (linear=0) penality: 1 * (0 - 100)
10: I05= 222180 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
11: xc5= 32.7205 (id=1) (linear=0) penality: 1 * (0 - 180)
12: w5= 0.196184 (id=1) (linear=0) penality: 1 * (0 - 100)
13: I06=-6.13954e+08 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
14: xc6= 180 (id=1) (linear=0) penality: 1 * (0 - 180)
15: w6= 0.300323 (id=1) (linear=0) penality: 1 * (0 - 100)
16: I08= 373060 (id=1) (linear=1) penality: 1 * (-1e+10 - 1e+10)
17: xc8= 37.343 (id=1) (linear=0) penality: 1 * (0 - 180)
18: w8= 0.247018 (id=1) (linear=0) penality: 1 * (0 - 100)
fmin= 1e+300
Save configuration parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd.in]
Save fitting parameters to [D:\git\tkProg\tkprog_COE\optimize\optimize_peakfit\test\xrd_parameters.csv] (save_parameters)
Final data:
2Theta I initial final
20 4995 -994.4 -2.394
21 652 -759.8 206
22 559.3 -314.6 613.9
23 1719 1139 1969
24 4.366e+04 4.32e+04 4.383e+04
25 2284 2926 3664
26 3539 2666 3475
27 5843 5329 6105
28 1.401e+04 1.364e+04 1.432e+04
29 5.91e+04 6.084e+04 6.11e+04
30 8.487e+05 8.592e+05 8.609e+05
31 2.323e+05 2.295e+05 2.314e+05
32 3.563e+04 3.739e+04 3.739e+04
33 8.211e+04 8.217e+04 8.122e+04
34 7988 9659 1.002e+04
35 5412 6746 7016
36 1.028e+04 1.379e+04 1.343e+04
37 1.114e+05 1.299e+05 1.278e+05
38 6.439e+04 4.909e+04 4.608e+04
39 7447 7804 7648
40 3380 2217 2492
Save input, initial, and final data to [xrd-fit.xlsx]
Plot optimized
*** fit.last_message: Message in tkFit_mxy_flex._callback(): xdiff=5.57912e-13 becomes smaller than
xatol=1e-08
- 変数の誤差:
フィッティングが終了したら、尤度関数を計算し、フィッティング結果の精度を確認する
test> python ..\optimize_peakfit1.py error --xmin=20
--xmax=40
コンソール出力 (peaks-out.txt):
Accuracy within one sigma:
000: bg_c0 : 1340 -243 + 248.6 in ( 1096.98 - 1588.55)
001: I01 : 50370.9 -2021 + 2027 in ( 48350 - 52397.7)
002: xc1 : 24.0784 -0.01083 + 0.01083 in ( 24.0676 - 24.0892)
003: w1 : 0.187958 -0.0104 + 0.01068 in ( 0.177561 - 0.19864)
004: I02 : 1.12519e+06 -1494 + 2493 in ( 1.1237e+06 - 1.12769e+06)
005: xc2 : 29.8826 -0.0004947 + 0.0004972 in ( 29.8821 - 29.8831)
006: w2 : 0.206628 -0.0005037 + 0.0005051 in ( 0.206125 - 0.207133)
007: I04 : 198745 -1594 + 2011 in ( 197150 - 200756)
008: xc4 : 31.0453 -0.002971 + 0.002966 in ( 31.0423 - 31.0482)
009: w4 : 0.239953 -0.003141 + 0.003162 in ( 0.236812 - 0.243114)
010: I05 : 222180 -1961 + 2001 in ( 220219 - 224181)
011: xc5 : 32.7205 -0.002485 + 0.002484 in ( 32.7181 - 32.723)
012: w5 : 0.196184 -0.002454 + 0.002469 in ( 0.19373 - 0.198653)
013: I06 : -6.13954e+08 -6.086e+07 + 6.085e+07 in (-6.74811e+08 - -5.531e+08)
014: xc6 : 180 -6.848 + * in ( 173.152 - * )
015: w6 : 0.300323 -0.01526 + 0.01453 in ( 0.285059 - 0.314849)
016: I08 : 373060 -1670 + 1866 in ( 371391 - 374927)
017: xc8 : 37.343 -0.00162 + 0.001623 in ( 37.3414 - 37.3447)
018: w8 : 0.247018 -0.001684 + 0.001689 in ( 0.245333 - 0.248707)
- シミューレション結果のプロット
> python ..\optimize_peakfit.py sim --xmin=20 --xmax=40
- 注: errorの結果から、ピーク#6の位置が決まっていないので、削除する
simの結果から、37.6°近傍のピークを落としている
(Kα2を考慮していないことに注意)ので、追加する
などの修正をしながら最終回を探す