首页 文章

在Python3中使用scipy将多个Lorentzians拟合为数据

提问于
浏览
2

好的,所以我很欣赏这需要一点耐心,但请耐心等待 . 我正在分析一些拉曼光谱,并编写了一个程序的基础,使用Scipy curve_fit将多个洛伦兹拟合到我的数据上的峰值 . 诀窍是我有这么多数据,我希望程序自动识别洛伦兹人的初步猜测,而不是手动执行 . 总的来说,程序给它带来了好处(并且可能对具有类似用例和更简单数据的其他人有用),但我不太了解Scipy足以优化curve_fit以使其适用于许多不同的例子 .

代码回购这里:https://github.com/btjones-me/raman_spectroscopy

它运行良好的一个例子可以参见图1 .

问题的一部分是我的峰值发现算法,有时很难为每个洛伦兹人找到合适的起始位置 . 你可以在图2中看到这一点 .

接下来的问题是,由于某些原因,curve_fit偶尔会发生灾难性的分歧(我最好的猜测是由于舍入错误) . 您可以在图3中看到此行为 .

最后,虽然我通常会对每个洛伦兹的高度和x位置做出很好的猜测,但我还没有找到一种预测曲线宽度或FWHM的好方法 . 预测这可能有助于curve_fit .

如果有人能以任何方式帮助解决这些问题,我将非常感激 . 我对包括其他第三方库在内的任何其他方法或建议持开放态度,只要它们改进了当前的实现 . 非常感谢任何试过这个的人!

在这里它完全符合我的意图:
Fig1

在下面您可以看到峰值发现方法未能识别所有峰值 . 有许多峰值查找算法,但我使用的是Scipy 's ' find_peaks_cwt()' (it' s通常不会这么糟糕,这是一个极端情况) .
Fig2

在这里,我真的理解为什么,也不要阻止它发生 . 可能它发生在我告诉它找到比光谱中可用的更多/更少的峰值时,但只是猜测 .
Fig3

我在Python 3.5.2中完成了这个 . PS我知道我不会为代码布局赢得任何奖牌,但总是对代码风格和更好的实践进行评论 .

1 回答

  • 1

    我偶然发现了这个因为我试图解决完全相同的问题,这是我的解决方案 . 对于每个峰值,我只适合我的lorentzian在域的区域或 - 1/2距离到下一个最近的峰值 . 这是我的功能,它打破了域名:

    def get_local_indices(peak_indices):
    #returns the array indices of the points closest to each peak (distance to next peak/2)
    chunks = []
    
    for i in range(len(peak_indices)):
        peak_index = peak_indices[i]
        if i>0 and i<len(peak_indices)-1:
            distance = min(abs(peak_index-peak_indices[i+1]),abs(peak_indices[i-1]-peak_index))
        elif i==0:
            distance = abs(peak_index-peak_indices[i+1])
        else:
            distance = abs(peak_indices[i-1]-peak_index)
    
    
        min_index = peak_index-int(distance/2)
        max_index = peak_index+int(distance/2)
        indices = np.arange(min_index,max_index)
    
        chunks.append(indices)
    
    return chunks
    

    这里是结果图的图片,虚线表示洛伦兹人适合的区域:Lorentzian Fitting Plot

相关问题