spectrum_.convolution のソースコード

"""
ガウス関数またはローレンツ関数を用いたデータの畳み込み(平滑化)スクリプト。

概要:
    入力データに対して指定した関数を畳み込み、ノイズの除去やブロードニングのシミュレーションを行います。
    DOS(状態密度)などの鋭いピークを持つデータの視認性を高めるのに適しています。

詳細説明:
    1. Excel等の入力ファイルから 2 列の数値データ(x, y)を読み込みます。
    2. ガウス関数(デフォルト)またはローレンツ関数を窓関数として生成します。
    3. 数値的な畳み込み積分を実行し、平滑化された y データを算出します。
    4. 結果を Excel ファイル(テンプレート対応)に保存し、グラフを表示します。

関連リンク: :doc:`convolution_usage`
"""

import sys
import numpy as np
import pandas as pd
from math import sqrt, exp, pi
import matplotlib.pyplot as plt

# 自作ライブラリ(パスが通っていることが前提)
from tklib.tkvariousdata import tkVariousData
from tklib.tkapplication import tkApplication

#======================
# デフォルトパラメータ
#======================
INFILE_DEF  = 'dos.xlsx'
OUTFILE_TEMPLATE = "StandardGraph.xlsm"
FUNC_TYPE_DEF = 'gauss'
WIDTH_DEF = 0.2

[ドキュメント] def convolve_func(x, width, func_type='gauss'): """ 畳み込みに使用する重み関数(窓関数)の値を計算します。 :param x: float: 中心からの距離。 :param width: float: 関数の幅パラメータ。 :param func_type: str: 'gauss' または 'lorentz'。 :returns: float: 重み。 """ if func_type == 'lorentz': coeff = 1.0 / (width * pi) dvx = x / width return coeff * (1.0 / (1.0 + dvx * dvx)) else: coeff = 1.0 / (sqrt(pi) * width) dvx = x / width return coeff * exp(-dvx*dvx)
[ドキュメント] def convolution(x, y, width, func_type): """ 数値データの畳み込み積分を実行します。 詳細説明: 幅の 5 倍の範囲を有効な積分範囲とし、各データ点に対して 周辺のデータの重み付き平均(積分)を計算します。 """ ndata = len(x) dx = x[1] - x[0] # 積分範囲をインデックス数に変換 di = int((width * 5.0) / dx + 1.1) ys = [0.0] * ndata for j in range(ndata): y0 = y[j] # 周辺範囲に重みを配分 for k in range(-di, di + 1): if j + k < 0 or j + k >= ndata: continue # 重み関数の寄与を計算 f = dx * convolve_func(dx * k, width, func_type) ys[j+k] += y0 * f return ys
[ドキュメント] def main(): """ メイン実行ルーチン。引数解析、計算、保存、プロットを制御します。 """ app = tkApplication() # 引数の取得 argv = sys.argv n = len(argv) infile = argv[1] if n >= 2 else INFILE_DEF width = float(argv[2]) if n >= 3 else WIDTH_DEF func_type = argv[3] if n >= 4 else FUNC_TYPE_DEF logfile = app.replace_path(infile) outfile = app.replace_path(infile, template=["{dirname}", "{filebody}-convoluted.xlsm"]) # 出力をログファイルにリダイレクト(必要に応じて) print(f"Open logfile [{logfile}]") app.redirect(targets=["stdout", logfile], mode='w') print(f"\nConvoluting data in [{infile}]") print(f"Function Type: {func_type}, Width: {width}") # データの読み込み data_reader = tkVariousData(infile) header, datalist = data_reader.Read_minimum_matrix(close_fp=True) x, y = datalist[0], datalist[1] # 畳み込み実行 ys = convolution(x, y, width, func_type) # 保存処理 print(f"Save to [{outfile}]") tkVariousData().to_excel(outfile, ['x', 'y(input)', 'y(convoluted)'], [x, y, ys], template=OUTFILE_TEMPLATE) # グラフプロット fig, ax1 = plt.subplots(figsize=(8, 6)) ax1.plot(x, y, label='Raw data', linestyle='-', linewidth=0.5, marker='o', markersize=0.5, alpha=0.5) ax1.plot(x, ys, label=f'Convoluted ({func_type})', linewidth=1.5) ax1.set_xlabel("x") ax1.set_ylabel("y") ax1.legend() plt.tight_layout() plt.show(block=False) print("\nPress ENTER to exit>>") input()
if __name__ == '__main__': main()