xrd_fit.py 技術ドキュメント

プログラムの動作

xrd_fit.py は、X線回折 (XRD) シミュレーション、実験データのフィッティング、およびフリンジ解析による膜厚自動推定を行うためのPythonスクリプトです。このプログラムは、薄膜試料のXRDパターンから、材料の組成比 (\(x\))、緩和度 (relax)、膜厚 (thick) といった物理的構造パラメータを非破壊で推定することを目的としています。

主な機能は以下の通りです。

  • XRDパターンシミュレーション (sim モード): xrayutilitiesライブラリの動的理論に基づき、指定された構造パラメータ(組成、緩和度、膜厚)を用いてXRDパターンを計算し表示します。

  • XRDデータ読み込み表示 (read モード): テキストファイル形式の2θ-Intensityデータを読み込み、プロットして表示します。

  • 構造パラメータ最適化フィッティング (fit モード): 実験データに対してシミュレーションパターンをフィッティングし、構造パラメータ(組成、緩和度、膜厚)を最適化します。複数の最適化アルゴリズム(ランダム探索、Nelder-Mead、BFGS、CG、粒子群最適化(PSO))をサポートします。

  • 膜厚自動推定 (guess モード): 実験データに現れるフリンジ(振動構造)を解析し、高速フーリエ変換(FFT)や線形回帰を用いて膜厚の候補値を自動で推定します。推定結果はパラメータファイルに保存され、フィッティングの初期値として利用できます。

  • リアルタイムプロット: フィッティングや膜厚推定の進捗状況をMatplotlibのグラフでリアルタイムに表示します。

原理

XRDシミュレーションの原理

xrd_fit.py は、xrayutilities ライブラリを用いて、動的理論に基づいたXRDシミュレーションを実行します。

  1. 材料定義: 基板と膜それぞれの結晶構造情報 (CIFファイル) を読み込み、xrayutilities.materials.Crystal オブジェクトを生成します。六方晶系の結晶を前提としており、弾性定数が未定義の場合はデフォルト値が適用されます。

  2. 合金層: 膜は基板と膜材料の合金として扱われ、組成比 \(x\) が導入されます。

  3. 層スタック: 基板層と膜層を組み合わせてxrayutilities.simpack.PseudomorphicStack001を作成します。膜は基板に対して擬似整合 (pseudomorphic) な成長をすると仮定し、緩和度 (relaxation) パラメータを考慮して格子定数を調整します。

  4. モデル構築: 上記のスタック情報、X線エネルギー(デフォルトはCu Kα1線)、回折ピークの広がり(resolution_width)を設定し、xrayutilities.simpack.DynamicalModel を構築します。

  5. 強度計算: 構築されたモデルに対し、指定された角度範囲と回折指数 (デフォルト: HKL = (0,0,2)) でシミュレーションを実行し、強度分布を計算します。

最適化フィッティングの原理

フィッティングは、シミュレーションで得られたXRDパターンと実験データとの間の残差(目的関数)を最小化することで行われます。

  1. 目的関数: 以下の残差 \(R\) を最小化します。 $\(R = \sum_{i} (Y_{exp, i} - Y_{sim, i})^2 + P\)\( ここで \)Y_{exp, i}\( は実験強度、\)Y_{sim, i}\( はシミュレーション強度です。 `--residual_scale` オプションで `log` を選択した場合、強度は対数変換されてから残差が計算されます。 \)\(R = \sum_{i} (\log(I_{exp, i} + \epsilon) - \log(I_{sim, i} + \epsilon))^2 + P\)\( \)\epsilon\( は数値計算上の安定性のための小さな値です。 \)P\( は物理的に妥当な範囲 (\)x \in [0,1]\(, \)relax \in [0,1]\(, \)thick > 0$) からパラメータが外れた場合に大きな値を返すペナルティ項です。

  2. 最適化アルゴリズム: scipy.optimize.minimize を利用した汎用的な最適化アルゴリズムと、粒子群最適化 (PSO) のカスタム実装、およびシンプルなランダム探索をサポートします。

    • ランダム探索 (random): パラメータをランダムに微小量変化させ、残差が改善した場合にそのパラメータを採択するシンプルな探索手法です。

    • Nelder-Mead, BFGS, CG (nelder-mead, bfgs, cg): scipy.optimize.minimize が提供する局所最適化アルゴリズムです。初期値の与え方や探索効率に違いがあります。

    • 粒子群最適化 (PSO) (pso): 複数の粒子(候補解)が解空間を探索し、自身の過去の最良解 (pbest) と群全体の最良解 (gbest) に基づいて移動するグローバル最適化手法です。 各粒子 \(p\) の位置 \(\mathbf{x}_p\) と速度 \(\mathbf{v}_p\) は、以下の式で更新されます。 $\(\mathbf{v}_p(t+1) = w \mathbf{v}_p(t) + c_1 r_1 (\mathbf{pbest}_p - \mathbf{x}_p(t)) + c_2 r_2 (\mathbf{gbest} - \mathbf{x}_p(t))\)\( \)\(\mathbf{x}_p(t+1) = \mathbf{x}_p(t) + \mathbf{v}_p(t+1)\)\( ここで、\)w\( は慣性重み、\)c_1\( は自己学習係数、\)c_2\( は社会学習係数、\)r_1, r_2\( は \)[0,1]$ の一様乱数です。 PSOは、一定の反復回数で改善が見られない場合(pso_stall_max)や、粒子の位置が十分に収束した場合(pso_spread_rtol)に早期停止します。

膜厚推定の原理 (guess モード)

膜厚推定モードでは、実験データに現れるフリンジ(LaueフリンジやPendellösungフリンジ)の周期性を解析して膜厚を求めます。

  1. 信号前処理:

    • 指定された角度範囲 (--guess_low, --guess_high) のデータを抽出。

    • 強度を対数変換(またはそのまま使用)。

    • Savitzky-Golayフィルター (scipy.signal.savgol_filter) で滑らかなエンベロープを抽出し、元の信号からエンベロープを差し引くことでフリンジ成分(残差)を抽出します。

  2. 高速フーリエ変換 (FFT) による解析:

    • 角度2θを波数 \(q_z\) に変換します。 $\(q_z = \frac{4\pi}{\lambda} \sin\theta\)\( ここで \)\lambda\( はX線波長、\)\theta$ は半角 (2θ の半分) です。

    • フリンジ成分に対してFFTを適用し、スペクトルのピークから主要なフリンジ周期 \(\Delta q_z\) を特定します。

    • 膜厚 \(T\) は以下の関係から推定されます。 $\(T = \frac{2\pi}{\Delta q_z}\)$

  3. フリンジピーク検出と線形回帰:

    • 残差信号からフリンジピークを検出 (scipy.signal.find_peaks)。

    • ピーク間の距離を基準にフリンジが欠損している箇所でピーク群をクラスターに分割 (cluster_gap_factor)。

    • 各クラスター内で、連続するフリンジピークに整数次数の n を割り当てます。

    • n\(q_z\) の関係が線形であるという仮定に基づき、線形回帰 (numpy.polyfit) を行います。 $\(q_z = A \cdot n + B\)$

    • この回帰の傾き \(A = \frac{\Delta q_z}{\Delta n}\) を用いて、膜厚 \(T\) を推定します。 $\(T = \frac{2\pi}{A}\)$

    • よりロバストな推定のため、外れ値を除外する2段階の線形回帰が適用されます。

必要な非標準ライブラリとインストール方法

xrd_fit.py の実行には、以下の非標準Pythonライブラリが必要です。

  • numpy: 数値計算

  • matplotlib: グラフ描画

  • xrayutilities: XRDシミュレーション

  • scipy: 最適化、信号処理

これらのライブラリは、以下の pip コマンドでインストールできます。

pip install numpy matplotlib xrayutilities scipy

必要な入力ファイル

プログラムの動作モードによって、以下のファイルが必要となります。

  • XRD実験データファイル (--infile)

    • 形式: 2列のテキストファイル (スペースまたはタブ区切り)。

    • 内容:

      • 1列目: 2θ角度 [deg]

      • 2列目: X線回折強度 [arb. u.]

    • 例 (my_exp_data.txt):

      32.000  123.45
      32.005  125.67
      32.010  128.90
      ...
      
    • --mode sim--infile を指定しない場合、プログラム内部でターゲットパラメータから模擬データが生成されます。

  • 基板の結晶構造ファイル (--substrate_file)

    • 形式: Crystallographic Information File (CIF)。

    • 内容: 基板材料の結晶構造情報。

    • デフォルト: GaN.cif

  • 膜の結晶構造ファイル (--film_file)

    • 形式: Crystallographic Information File (CIF)。

    • 内容: 膜材料の結晶構造情報。

    • デフォルト: AlN.cif

  • パラメータ設定ファイル (自動生成/読み込み)

    • 形式: CSV (Comma Separated Values) ファイル。

    • 内容: 最適化する構造パラメータ (x, relax, thick) の値と、最適化対象とするかどうかのフラグ (optid)。

    • ファイル名: --infile が指定された場合は [infile_basename]-parameters.csv、そうでない場合は parameters.csv

    • このファイルは、プログラムが初回実行時にデフォルト値で自動生成するか、既存のファイルを読み込みます。手動で編集して初期値を設定することも可能です。

    • 例 (my_exp_data-parameters.csv):

      varname,value,optid
      best0:x,0.2000000000000000,1
      best0:relax,0.0000000000000000,1
      best0:thick,1500.0000000000000000,1
      pso0:x,0.1987654321000000,1
      pso0:relax,0.0012345678900000,1
      pso0:thick,1498.7654321000000000,1
      

      varname[セット名]:[パラメータ名] の形式で指定されます。デフォルトの最適化結果は best0 セットに保存されます。PSOモードでは pso0, pso1 などの名前で各粒子の初期位置が保存されることがあります。

生成される出力ファイル

プログラムは実行モードに応じて以下のファイルを生成します。

  • パラメータ設定ファイル ([infile_basename]-parameters.csv または parameters.csv)

    • 内容: フィッティングの最適化結果(組成 \(x\)、緩和度 relax、膜厚 thick の最終値)と、各パラメータが最適化対象であったかどうかのフラグが保存されます。PSOモードでは、複数の粒子(候補解)のパラメータもこのファイルに保存されます。

    • 形式: 「必要な入力ファイル」セクションで示されたCSV形式と同様です。

  • 膜厚推定ピークデータファイル ([infile_basename]-guess-peaks.csv または guess-peaks.csv)

    • モード: guess モード実行時に生成されます。

    • 内容: フリンジ解析で検出された各ピークのID、フリンジ次数 \(n\)、波数 \(q\)、2θ角度、および2段階線形回帰における使用状況と残差情報が保存されます。

    • 形式: CSVファイル。

    • 例:

      cluster_id,n,q,2theta,used_stage1,used_stage2,resid_stage1,resid_stage2
      0,0,2.23456789,33.12345,1,1,0.000123,-0.000012
      0,1,2.24567890,33.23456,1,1,0.000056,0.000005
      ...
      
  • 膜厚推定クラスターデータファイル ([infile_basename]-guess-clusters.csv または guess-clusters.csv)

    • モード: guess モード実行時に生成されます。

    • 内容: フリンジ解析で検出された各クラスター(フリンジ群)ごとの情報(ピーク数、FFTによる推定膜厚、線形回帰による推定膜厚、信頼度など)が保存されます。

    • 形式: CSVファイル。

    • 例:

      cluster_id,npeaks,dq_est,thick_fft,thick_reg,confidence
      0,10,0.01234567,510.123,510.567,10.0
      1,5,0.01234567,510.123,511.123,5.0
      
  • リアルタイムプロットウィンドウ:

    • fit および guess モードでは、Matplotlibによるグラフウィンドウがリアルタイムで更新され、フィッティングの進捗やフリンジ解析の結果(信号、エンベロープ、残差、FFTスペクトル、n-qプロットなど)が表示されます。これらのウィンドウはファイルとして自動保存されませんが、ユーザーが手動で保存できます。

コマンドラインでの使用例 (Usage)

xrd_fit.py --help を実行すると、以下のヘルプメッセージが表示されます。

usage: xrd_fit.py [-h] [--mode {sim,read,fit,guess}]
                  [--method {random,nelder-mead,bfgs,cg,pso}] [--infile INFILE]
                  [--substrate_file SUBSTRATE_FILE] [--film_file FILM_FILE]
                  [--fix FIX] [--nmaxiter NMAXITER] [--tol TOL]
                  [--yscale {linear,log}] [--residual_scale {linear,log}]
                  [--guess_low GUESS_LOW] [--guess_high GUESS_HIGH]
                  [--nsmooth_points NSMOOTH_POINTS] [--nsmooth_order NSMOOTH_ORDER]
                  [--nguess_keep NGUESS_KEEP]
                  [--cluster_gap_factor CLUSTER_GAP_FACTOR]
                  [--pso_nparticles PSO_NPARTICLES] [--pso_w PSO_W]
                  [--pso_c1 PSO_C1] [--pso_c2 PSO_C2]
                  [--pso_stall_max PSO_STALL_MAX] [--pso_spread_rtol PSO_SPREAD_RTOL]

動的理論に基づくXRDシミュレーション、フィッティング、および膜厚推定

options:
  -h, --help            show this help message and exit
  --mode {sim,read,fit,guess}
                        実行モード: sim (シミュレーション), read (読込), fit (最適化), guess (膜厚推定) (デフォルト: sim)
  --method {random,nelder-mead,bfgs,cg,pso}
                        最適化手法。fitモード時に有効 (デフォルト: pso)
  --infile INFILE       2theta-intensityデータを含むテキストファイルへのパス (デフォルト: )
  --substrate_file SUBSTRATE_FILE
                        基板のCIFファイルパス (デフォルト: GaN.cif)
  --film_file FILM_FILE 膜のCIFファイルパス (デフォルト: AlN.cif)
  --fix FIX             固定するパラメータ(カンマ区切り、例: "x,relax") (デフォルト: )
  --nmaxiter NMAXITER   最大反復回数 (デフォルト: 1000)
  --tol TOL             収束判定の許容誤差 (デフォルト: 1e-07)
  --yscale {linear,log}
                        プロットのY軸スケール (デフォルト: "log")
  --residual_scale {linear,log}
                        残差計算に使用するスケール (デフォルト: "log")
  --guess_low GUESS_LOW
                        guessモードでの解析開始角度 [deg] (デフォルト: 16.0)
  --guess_high GUESS_HIGH
                        guessモードでの解析終了角度 [deg] (デフォルト: 17.3)
  --nsmooth_points NSMOOTH_POINTS
                        guessモードでの平滑化ウィンドウ点数 (デフォルト: 31)
  --nsmooth_order NSMOOTH_ORDER
                        guessモードでの平滑化多項式次数 (デフォルト: 3)
  --nguess_keep NGUESS_KEEP
                        guessモードで保持する膜厚候補の数 (デフォルト: 5)
  --cluster_gap_factor CLUSTER_GAP_FACTOR
                        フリンジクラスター判定用のギャップ係数 (デフォルト: 1.6)
  --pso_nparticles PSO_NPARTICLES
                        PSOの粒子数 (デフォルト: 12)
  --pso_w PSO_W         PSOの慣性重み (デフォルト: 0.72)
  --pso_c1 PSO_C1       PSOの自己学習係数 (デフォルト: 1.49)
  --pso_c2 PSO_C2       PSOの社会学習係数 (デフォルト: 1.49)
  --pso_stall_max PSO_STALL_MAX
                        改善がない場合にPSOを停止する最大反復数 (デフォルト: 15)
  --pso_spread_rtol PSO_SPREAD_RTOL
                        粒子の分散に基づく停止条件の相対許容誤差 (デフォルト: 0.1)

コマンドラインでの具体的な使用例

以下の例では、my_exp_data.txt という実験データファイルが存在し、GaN.cifAlN.cif がプログラムと同じディレクトリにあると仮定します。

  1. シミュレーションモードで模擬データを生成し、プロットする

    • --infile を指定しない場合、プログラム内のデフォルトパラメータ (TARGET_X, TARGET_RELAX, TARGET_THICK) を使用してシミュレーションが実行されます。

    python xrd_fit.py --mode sim
    
    • 実行結果: Matplotlibウィンドウにシミュレーション結果のXRDパターンが表示されます。

  2. 読み込みモードで実験データをプロットする

    python xrd_fit.py --mode read --infile my_exp_data.txt --yscale log
    
    • 実行結果: Matplotlibウィンドウに my_exp_data.txt のXRDパターンがY軸対数スケールで表示されます。

  3. 膜厚推定モードでフリンジ解析を実行する

    python xrd_fit.py --mode guess --infile my_exp_data.txt --guess_low 34.0 --guess_high 36.0 --nguess_keep 3
    
    • 実行結果:

      • ターミナルに推定された膜厚候補がリスト形式で表示されます。

      • Matplotlibウィンドウにフリンジ解析の各ステップ(信号、エンベロープ、残差、FFTスペクトル、n-qプロット)が表示されます。

      • my_exp_data-guess-peaks.csvmy_exp_data-guess-clusters.csv が出力されます。

      • my_exp_data-parameters.csv が生成または更新され、最も信頼性の高い膜厚候補が best0:thick として保存されます。

  4. フィッティングモードでPSO最適化を実行する

    • --infile で指定されたデータに対して、パラメータ x, relax, thick を最適化します。

    python xrd_fit.py --mode fit --method pso --infile my_exp_data.txt --nmaxiter 500 --pso_nparticles 20
    
    • 実行結果:

      • ターミナルに反復回数、現在の残差、各パラメータ値が表示されます。

      • Matplotlibウィンドウに実験データと現在のシミュレーションパターンのフィッティング状況がリアルタイムで表示されます。

      • フィッティング完了後、my_exp_data-parameters.csv に最適化されたパラメータの最終値が保存されます。

  5. フィッティングモードでNelder-Mead最適化を実行し、特定のパラメータを固定する

    • この例では、組成 x を初期値に固定し、relaxthick のみを最適化します。

    python xrd_fit.py --mode fit --method nelder-mead --infile my_exp_data.txt --fix x --nmaxiter 1000
    
    • 実行結果: fix x オプションにより、my_exp_data-parameters.csv 内の xoptid0 に設定され、最適化中に \(x\) の値は変化しません。それ以外の動作は上記のフィッティング例と同様です。