利用python处理拉曼数据
最近在实验中需要处理 Raman mapping数据,由于数据量较大,因此考虑用python来进行处理。经查阅后发现,利用python来做光谱数据分析的还非常少,相关的库也不多,最后好不容易,找到了MIT一个组写的关于峰拟合的库---peakutils,因此我便以该库作为基础,利用python编写程序对光谱数据进行分析。
该程序需要有三个基本的功能:扣除背底、峰拟合、峰积分。
具体代码如下
import matplotlib.pyplot as plt
import num py as np
import peakutils
#利用raman峰对数据归一化处理,通过对Raman peak 拟合得到峰值。
def normalized(intensity):
intensity_r=intensity[:800] #选取拉曼峰所在区域
base=peakutils.baseline(intentity_r) #背底拟合
intensity_m=intensity_r-base #扣除背底
return intensity/max(intensity_m) #返回归一化数据
#从文件中读取光谱数据,根据数据格式,对数据进行截取。该程序处理的是Raman line mapping 数据。
def get_data(path):
intensity=[] #每个扫描点对应的光谱数据
location=[] #扫面点坐标
count=1
with open(path,"r") as f:
for line in f.readlines():
if count==1:
wavelength=[float(i) for i in line.split("\t")[1:]] #文件中,第一行为扫描波长,获取扫描的波长范围
else:
tenp=[float for i in line.split("\t")] #每行的数据切割,放到列表中
location.append(temp[0]) #获取扫描点的坐标,
intensity.append(temp[1:]) #获取扫描点的光谱数据,是一个列表
count=count+1
return np.array(location),np.array(wavelength),np.array(intensity) #将列表转换为np.array 对象
#峰拟合,积分
def int_zpl(zpl,wavelength,amp,region_w):
#zpl, 零声子线,即待积分的峰的位置 ,单位 nm
#wavelength 光谱数据中波长,单位nm
#amp 光谱数据中信号强度
#region_w 积分峰的宽度,单位 nm
delta=wavelength[1]-wavelength[0] #光谱扫描步长
region_num=int(region_w/delta) #将积分区域转换为计数长度
center=int((zpl-wavelength[0])/delta) #找到积分峰中心在光谱数据列表中的位置。
#选出积分区域,便于扣除背底拟合峰形
wavelength_zpl=wavelength[center-region_num:center+region_num]
amp_zpl=amp[center-region_num:center+region_num]
bl=peakutils.baseline(amp_zpl,deg=1) #背底,选为线性
# plt.plot(wavelength_zpl,amp_zpl,"*")
# plt.plot(wavelength_zpl,lorentz(wavelength_zpl,*popt)+bl)
area=integrate.trapz(amp_zpl-bl,wavelength_zpl) #对拟合峰进行积分
# plt.show()
return area
#%% 对mapping文件进行处理
def bat(path):
wavelength,location,amps=get_data(path)
amps_n=normalized(wavelength,amps)
areas=[]
print(location)
zpl=737 #选择积分峰
region_w=5/2.0 #选定积分区域,单位nm
for amp in amps: 每个循环处理一个点的光谱数据
area=int_zpl(zpl,wavelength,amp,region_w)
areas.append(area)
areas=np.array(areas)
plt.plot(location,areas)
np.savetxt("d:/plot/结果/raman/"+str(zpl)+"s.txt",np.column_stack((location,areas)),fmt="%.4f",delimiter="\t") #保存数据
def main():
path="d:/plot/raman/sd128.txt"
bat(path)
if __name__ == "__main__" :
main()
本文一方面是自己对该方法的总结,另一方面也是给有需要的人的参考。本人所知有限,如有更科学的分析方法,请务必告知,也欢迎一起交流学习。