optimize.optimize_peakfit.optimize_peakfit のソースコード

"""
多重ピークフィッティングモジュール

このモジュールは、複数のピークを持つデータセットに対し、最適化されたフィッティングを実行するための
メインスクリプトを提供します。データ入力、初期条件設定、様々なフィッティングアルゴリズム、
結果のプロットといった機能を含みます。

:doc:`optimize_peakfit_usage`
"""
import os
import platform
import sys
import re

sys.path.append('.')

try:
    import tklib.tkimport as imp
except Exception as e:
    print()
    print("######################################################################")
    print("###########  ERROR ERROR ERROR ERROR ERROR ERROR #####################")
    print("######################################################################")
    print(f"# Failed to import [tklib.tkimport] module ({e}).")
    print(f"#  Add [tkProg]{os.sep}tklib{os.sep}python to PYTHONPATH variable")
    print(f"#  Current PYTHONPATH:", sys.path)
    print("######################################################################")
    input("Press ENTER to terminate>>")
    exit()

np  = imp.import_lib("numpy", stop_by_error = False)
pd  = imp.import_lib("pandas", stop_by_error = False)
mpl = imp.import_lib("matplotlib", stop_by_error = False)
imp.messages(stop_by_error = True)


from numpy import sqrt, exp, log, log10
from scipy.optimize import minimize
from scipy.signal import savgol_filter 
from matplotlib import pyplot as plt
import pandas


from tklib.tkutils import print_data, pint, pfloat, format_strlist
from tklib.tkvariousdata import tkVariousData
from tklib.tkapplication import tkApplication
from tklib.tkparams import tkParams

from tklib.tksci.tksci import e, kB
from tklib.tksci.tkmlr import tkMLData, tkMLR

from tklib.tkgraphic.tkplot_pyplot import select_plt, tkPlot_pyplot
from tklib.tkgraphic.tkplotevent import tkPlotEvent, RangeSelector
from tklib.tksci.tkFit_lib import conv_input, save_data, add_history

import tklib.tksci.tkoptimize_flex as opt
import optimize_peakfit_mf as mf
import peakfit as omodel


ProgramName = "Fitting to multiple peaks"


[ドキュメント] def init(app, cfg, mf): """ ピークフィッティングの初期条件を設定し、線形最小二乗法で初期フィッティングを実行します。 入力データと設定ファイルに基づいてフィッティングパラメータを構築し、 初期の線形フィッティングを実行して、ピークの初期位置と強度を推定します。 結果は設定オブジェクトに保存されます。 :param app: tkApplicationインスタンス。アプリケーションの状態とユーティリティを提供します。 :type app: tklib.tkapplication.tkApplication :param cfg: tkParamsインスタンス。プログラムの設定パラメータを保持します。 :type cfg: tklib.tkparams.tkParams :param mf: optimize_peakfit_mfモジュールのインスタンス。フィッティング関連のヘルパー関数を提供します。 :type mf: module :returns: None """ print("") print("Initialize fitting condition:") fit = opt.clean(app, cfg, mf) config_path = cfg.parameterfile fitparam_path = fit.fitfile_path print(f" Read [{cfg.infile}]") xlabels, ylabels, xdata_list, ydata_list, _ = mf.read_input_data(app, cfg.infile, cfg = cfg) xlist = xdata_list[0] ylist = ydata_list[0] options = {"nsmooth": cfg.nsmooth, "norder": cfg.norder, "threshold": cfg.threshold, "ydiff1_threshold": cfg.ydiff1_threshold} app.varname, app.unit, app.pk_scale, app.optid, app.linid, app.x0, app.dx, app.kmin, app.kmax, app.kpenalty \ = omodel.build_fit_params(xlist, ylist, options) for i, varname in enumerate(app.varname): app.add_argument(opt = f"--{varname}", type = "float", defval = app.x0[i]) print() fit = mf.init_fit(app, cfg) # Linear LSQ pk_all = opt.linear_fit(app, cfg, mf, omodel, fit, print_level = True) fit.pk = pk_all print() mf.save_parameter_files(config_path, fitparam_path, fit, cfg) app.terminate(pause = True)
[ドキュメント] def main(): """ プログラムのメインエントリポイント。 コマンドライン引数の解析、設定ファイルの読み込み、ログのセットアップを行い、 `cfg.mode` パラメータに基づいて適切なフィッティングまたはデータ処理モードを呼び出します。 `mk_config` モードでは設定ファイルを作成します。 :returns: None """ app = tkApplication() if len(sys.argv) > 1 and sys.argv[1] == 'mk_config': app.make_config_files(arg_config_file = 'arg_config.xlsx', fit_config_file = 'fit_config.xlsx') app.terminate("\n", pause = True) #初期値の確定順序 #intialize(): 起動時引数と初期値の設定 cfg = mf.initialize(app) #--infile引数をチェックし、読み込みファイル名を最初に確定する cfg.infile = app.check_arg('--infile', defval = None, vartype = 'str') #cfg.infileからログファイル名を作り、console出力をredirectする cfg.logfile = app.replace_path(cfg.infile) app.redirect(heading = f"Open logfile [{cfg.logfile}]", targets = ["stdout", cfg.logfile], mode = 'w') app.set_exception() try: app.print_title(f"# {ProgramName}") except: pass #cfg.infileが入力ファイルか設定ファイルであるかによって、infileとconfig_pathを返す # 設定ファイルである場合、infile_storedをNoneにして、後で設定ファイルからcfg.infileを読み込む cfg.infile, cfg.parameterfile, infile_stored \ = app.analyze_infile(cfg.infile, infile_ext = [".xlsx"], config_ext = [".in", ".ini", ".prm"], print_level = 1) #起動時引数で与えられたパラメータをcfgに設定 print() print("Update parameters from command line arguments") app.update_vars(cfg, apply_default = True) # cfg.print_parameters() mf.initialize_minimize_func(app) #設定ファイルを読み込み、cfgに設定。#cfg.infileも書き換えられる print() print(f"Read configration file [{cfg.parameterfile}]") mf.read_parameters(cfg.parameterfile, cfg) # cfg.print_parameters() #infile_stored = Noneの場合、設定ファイルのcfg.infileをinfile_storedに再保存 #infile_storedが最終的な読み込みファイル名になる if infile_stored is None: infile_stored = cfg.infile #起動時引数で与えられたパラメータを最優先にするため、再設定 app.force_given_args(cfg) # cfg.print_parameters() # exit() # --daemonフラグが立っていたらdaemonize() if cfg.get("daemon", 0): print("\ndaemon flag is set:") print(" fplot flag is set to -1") cfg.fplot = -1 app.daemonize(stdout_path = 'daemon.log', stderr_path = 'daemon.log', print_level = 1) # --nohupフラグが立っていたらHUPシグナルを無視 if cfg.get("nohup", 0): app.nohup() #cfg.infileを infile_storedに最終設定 cfg.infile = infile_stored cfg.print_parameters() # exit() cfg.historyfile = app.replace_path(cfg.infile, template = ["{dirname}", "{filebody}-history.xlsx"]) cfg.stopfile = app.replace_path(cfg.infile, template = ["{dirname}", "stop"]) print(f"infile: {cfg.infile}") print(f"parameterfile: {cfg.parameterfile}") print(f"stop file: {cfg.stopfile}") if os.path.isfile(cfg.stopfile): print(f"\nWarning: stop file [{cfg.stopfile}] exisits") print(" remove it") os.remove(cfg.stopfile) if cfg.file1 in ['clean', 'inf', 'kill', 'plot', 'init', 'search', 'lfit', 'lasso', 'fit', 'update', 'sim', "error"]: cfg.mode = cfg.file1 cfg.file1 = '' if cfg.mode == 'clean': opt.clean(app, cfg, mf) elif cfg.mode == 'kill': opt.kill(app, 'python') elif cfg.mode == 'inf': opt.inf(app, cfg, mf) elif cfg.mode == 'init': init(app, cfg, mf) elif cfg.mode == 'search': omodel.peak_search(app, cfg, mf) elif cfg.mode == 'lfit': opt.linear_fit_func(app, cfg, mf, omodel) elif cfg.mode == 'lasso': opt.lasso(app, cfg, mf, omodel) elif cfg.mode == 'sim': opt.sim(app, cfg, mf) elif cfg.mode == 'scan': opt.scan(app, cfg, mf) elif cfg.mode == 'mapping': opt.mapping(app, cfg, mf) elif cfg.mode == 'sampling': opt.sampling(app, cfg, mf) elif cfg.mode == 'fit1': opt.fit1(app, cfg, mf) elif cfg.mode == 'fit': if cfg.get("daemon", 0): opt.fit_simple(app, cfg, mf, optid_mode = 'optid') else: opt.fit(app, cfg, mf, optid_mode = 'optid') elif cfg.mode == 'fitlp': if cfg.get("daemon", 0): opt.fit_simple(app, cfg, mf, optid_mode = 'linid') else: opt.fit(app, cfg, mf, optid_mode = 'linid') elif cfg.mode == 'error': opt.error(app, cfg, mf) elif cfg.mode == 'mlr': opt.mlr(app, cfg, mf) elif cfg.mode == 'plot': omodel.plot_input(app, cfg, mf) elif cfg.mode == 'plot_history': plot_history(app, cfg, mf) elif cfg.mode == 'plot_fit': plot_fit(app, cfg, mf) elif cfg.mode in globals() and callable(globals()[cfg.mode]): # cfg.modeで与えられた関数が定義されていれば、呼び出す globals()[cfg.mode](app, cfg) else: app.terminate(message = "\n", usage = app.usage, post_message = f"Error in main: Invalide mode [{cfg.mode}]", pause = True, )
if __name__ == "__main__": main()