import os
import sys
import csv
import re
from math import exp, sqrt
import numpy as np
from math import log, exp
from numpy import arange
from scipy.interpolate import interp1d
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib import cm
"""
光電子分光法のための元素とピークレベルを検索するスクリプト。
このスクリプトは、指定された結合エネルギーと許容誤差範囲に基づいて、
CSVファイルから光電子分光法(XPS)で観測される可能性のある元素とピークを検索します。
ユーザーは検索する結合エネルギーと許容誤差を入力します。
:doc:`BESearch_usage`
"""
argv = sys.argv
prog_path = argv[0]
Source1 = 'XPS-BE-Source.csv'
#Source2 = 'XPS-BE-Small.csv'
if not os.path.isfile(Source1):
dirname = os.path.dirname(prog_path)
Source1 = os.path.join(dirname, Source1)
SearchVal = '' #510; # eV
SearchErr = '' # 5; # eV
#=============================
# General functions
#=============================
[ドキュメント]
def pfloat(s, strict = True, defval = 0.0):
"""
文字列を安全に浮動小数点数に変換します。
変換できない場合や、文字列内に数字が含まれている場合は、
その数字部分を抽出して変換を試みます。
`strict`が`True`の場合は完全な数値文字列のみを許容し、
`False`の場合は文字列内の最初の数値パターンを抽出します。
:param s: (str) 変換対象の文字列。
:param strict: (bool) `True`の場合、文字列全体が浮動小数点数として解釈できないと`defval`を返します。
`False`の場合、文字列から浮動小数点数パターンを検索します。
:param defval: (float or str or None) 変換失敗時のデフォルト値。
`None`が指定され、数値パターンが見つからない場合は元の文字列`s`が返されることがあります。
:returns: (float or str or None) 変換された浮動小数点数、または変換失敗時のデフォルト値や元の文字列。
"""
try:
return float(s)
except:
pass
if s is None or strict:
return defval
match = re.search(r'([\+\-]?[\d\.eE]+)', s)
if not match:
return defval
val = match.group()
try:
return float(val)
except:
if defval is None:
return s
return defval
[ドキュメント]
def Search(p, t, e):
"""
指定された結合エネルギー範囲内の元素ピークを検索し、表示します。
`p` (辞書)から結合エネルギー値を抽出し、`t` (目標値)と`e` (誤差範囲)に基づいて
`t - e`から`t + e`の範囲内に含まれるピークを特定します。
一致したピークの情報(原子番号、元素名、状態、結合エネルギー)を整形して出力します。
:param p: (dict) 元素ピークデータを含む辞書。キーは"原子番号 元素名 状態"、値は結合エネルギー(float)。
:param t: (float) 検索する目標結合エネルギー (eV)。
:param e: (float) 検索する結合エネルギーの許容誤差 (eV)。
:returns: None
"""
print("Hit for {} - {} - {} eV ...".format(t - e, t, t + e))
for key in p.keys():
v = p[key]
# print("comp: $v ($t +- $e ?)")
if t - e <= v <= t + e:
an, name, st = key.split()
print(" {:>2} {:>2} {:>8} {:>8.2f} eV".format(an, name, st, v))
[ドキュメント]
def ReadCSV(infile):
"""
指定されたCSVファイルから元素ピークデータを読み込み、辞書として返します。
ファイルを開き、各行を解析して元素名、状態、結合エネルギーを抽出します。
ヘッダー行から状態(s, p, dなど)を識別し、データ行から原子番号、元素名、
および対応する結合エネルギーを読み取ります。
結合エネルギー値は`pfloat`関数を使用して浮動小数点数に変換されます。
ファイル読み込みに失敗した場合、`NameError`が発生する可能性があります。
:param infile: (str) 読み込むCSVファイルのパス。
:returns: (dict) 読み込まれた元素ピークデータ。キーは"原子番号 元素名 状態"、値は結合エネルギー(float)。
"""
try:
print("Read [{}]".format(infile))
f = open(infile, 'r')
except:
# except IOError:
print("Error: Can not read [{}]".format(infile))
else:
hash = {}
header = None
st = []
val = []
while 1:
line = f.readline()
if not line:
break
if 's' in line and 'p' in line and 'd' in line:
st = line.split(',')
# print("st=", st)
# exit()
else:
val = line.split(',')
# print(" v0=", val)
# exit()
for i in range(len(val)):
# print("val[{}]={}".format(i,val[i]))
if val[i] == '':
val[i] = None
elif re.search(r'([A-Z][a-z]?)', val[i]):
pass
else:
val[i] = pfloat(val[i], False, 0.0)
# print(" v=", val)
for i in range(2, len(val)):
if val[i]:
o = st[i]
key = "{} {} {}".format(val[0], val[1], o)
hash[key] = pfloat(val[i])
print(" {} {}".format(key, hash[key]))
f.close()
return hash
[ドキュメント]
def main():
"""
プログラムのメイン処理を実行します。
ユーザーに検索する結合エネルギーと許容誤差を入力させます。
指定されたCSVファイルから元素ピークデータを読み込み、
`Search`関数を呼び出して結果を表示します。
:returns: None
"""
global SearchVal, SearchErr
print("")
print("====================================")
print(" Search possible elements and peaks from binding energy and possible range")
print("====================================")
print("")
if SearchVal == '':
print("Input search value (Def: 510 eV): ", end = '')
line = input().strip()
if line == '':
SearchVal = 510.0
else:
SearchVal = pfloat(line)
if SearchErr == '':
print("Input error value (Def: 10 eV): ", end = '')
line = input().strip()
if line == '':
SearchErr = 10.0
else:
SearchErr = pfloat(line)
print("Read [{}] =====================================".format(Source1))
pBE1 = ReadCSV(Source1);
# print "Read [{}] =====================================".format(Source2));
# pBE2 = ReadCSV(Source2);
print("File read end=====")
print("")
print("=====================================")
Search(pBE1, SearchVal, SearchErr)
print("")
if __name__ == '__main__':
main()