使用scipy.interpolate计算FWHM时的问题

2 投票
1 回答
3915 浏览
提问于 2025-04-18 10:50

我在找一些数据的全宽半最大值(FWHM)时遇到了问题。一开始,我试着用 interpolate.interp1d 来拟合曲线。这样我就能创建一个函数,当我输入一个 x 值时,它会返回一个插值的 y 值。问题是,我需要这个功能的反向,也就是说,我想把自变量和因变量对调。但是当我尝试这样做时,出现了错误,因为自变量的数据必须是排序的。如果我对数据进行排序,就会丢失索引,从而失去图形的形状。

我尝试了:

x = np.linspace(0, line.shape[0], line.shape[0])
self.x_curve = interpolate.interp1d(x, y, 'linear')

这里的 y 是我的数据。

为了得到反向,我尝试了:

self.x_curve = interpolate.interp1d(sorted(y), x, 'linear')

但得到的值不对。

然后我继续尝试使用 UnivariateSpline 来找到根,从而找出全宽半最大值(参考这个问题:寻找峰值的全宽半最大值),但是 roots() 方法总是给我一个空列表 []

这是我使用的:

x_curve = interpolate.UnivariateSpline(x, y)
r = x_curve.roots()
print(r)

这里是数据的图像(使用 UnivariateSpline):

数据图

有什么想法吗?谢谢。

1 个回答

3

使用 UnivariateSpline.roots() 来计算全宽半高(FWHM)时,数据必须先调整,使得在全宽半高的位置值为0。

由于数据的背景比较嘈杂,我会先估算一下基线。比如说:

y_baseline = y[(x<200) & (x>350)].mean()

(根据需要调整 x 的范围)。然后将数据调整,使得基线的中间和峰值都在0的位置。因为你的数据有一个最小值,而不是像例子中那样有最大值,所以我使用 y.min()

y_shifted = y - (y.min()+y_baseline)/2.0

现在对这个调整后的数据进行样条拟合,这样 roots() 就能找到根值,而根值之间的差就是全宽半高。

x_curve = interpolate.UnivariateSpline(x, y_shifted, s=0)
x_curve.roots()

如果你想从平滑的数据中估算全宽半高,可以增加 s 参数的值。

撰写回答