如何实现半自动峰值拾取
Posted
技术标签:
【中文标题】如何实现半自动峰值拾取【英文标题】:How can I implement semi-automatic peak-picking 【发布时间】:2013-03-16 09:37:46 【问题描述】:我正在研究光致发光温度系列。因此,我有几个在不同温度下拍摄的强度与能量 (eV) 光谱。
我的问题是到目前为止我发现的信号处理/峰值查找包(Peaks、hyperSpec、msProcess、Timp 和其他面向质谱/化学计量学的包)并不真正适合我的需求:
峰找不到“肩部”(峰位置太近,产生混合峰(见 3.75 eV)) hyperSpec 和 msProcess 对于我的使用来说过于自动化:光致发光峰的位置取决于温度,因此峰识别在整个温度系列中是不可重复的。我认为我应该实现的是:检测峰和肩(自动或使用 locate()
进行原始估计),要求手动识别找到的峰,并输出标签、位置、强度和 @987654321每个峰的@。这将使我能够准确跟踪温度序列中给定峰值(由其标签标识)的位置、强度和半高宽。
这是温度序列图的示例:
所以我的问题是:
-
你知道已经实现了类似功能的包吗?
您认为我建议的方法合理/可行吗?
非常感谢!
蒂博·鲁尔
PS:我希望我已经足够清楚了,请随时向我寻求澄清。 PS2:我希望这个问题不要太笼统,如果需要我可以提供一个典型的光谱。
【问题讨论】:
您认为我们对您的工作了解一切。我建议您稍微简化一下术语,然后用外行的方式对其进行分解。这里的重叠峰是什么?什么是 FWHM? 好的,我想知道我是否应该这样做。非常感谢! 我过去使用的一种方法是 1) 通过数据获取smooth.spline()
; 2) 定位这个平滑函数的极值(例如查看diff()
的符号变化;3)将这些猜测作为优化函数的起点。
也尝试阅读有关 fda
包的小插图,我感觉您的问题很可能属于功能数据分析领域。
非常感谢您的建议!我现在正在调查它。乍一看(我试图确认),主要问题是峰值不应该随参数改变位置。
【参考方案1】:
免责声明:我个人从未做过任何严重的峰值拟合。
话虽如此,我在这里看到了两种方式,最终可能并没有那么不同:
功能数据分析,就像 @baptiste 所说的那样。 拟合预设数量的已知形状的峰(例如高斯或洛伦兹或福伊特) 然后将这些的拟合参数作为新的特征集进行进一步分析。 FWHM 将在拟合参数中编码。哪种方法更适合您可能取决于您计划的进一步分析。
还有一些零碎的东西:
当您在寻找肩峰时,一阶导数将不允许您检测所有峰。您可能会从二阶导数的最小值获得足够有用的峰值拟合起点。但是,对于仅在某个较大峰上显示为肩峰的峰,这些位置将非常偏离(在较大峰的低强度侧太远)。 package signal 实现了 Savitzky-Golay 过滤器,可以帮助实现这种方法。 去卷积可能是检测峰位置的更好选择。 您应该知道,这些方法往往会迅速“消耗”您的信噪比,如果您的基线低于峰值,则解决方案可能会大打折扣。我不知道 fda 是否在这方面做得更好,但我怀疑这是您要解决的问题所固有的。 你会想要检查你得到的解决方案的稳定性。 SNR 和可能的基线。(不,hyperSpec 不提供类似的东西。但是,如果您最终获得了普遍适用的功能,欢迎您通过 hyperSpec 分发它,它仍然可以是您自己的包.如果这是一项实质性的编程工作,你可以考虑用这个申请一个谷歌夏季代码项目——今年的申请期即将开始)。
【讨论】:
非常感谢您的建议!反卷积和功能数据分析的主要问题是它们不允许“跟随”位置随温度变化的给定峰。因此,我认为最有希望的方法是使用nls()
将一组峰值拟合到数据中。然而,另一个问题是峰的数量随温度而变化(发生转变),所以我可能不得不使用在(a)给定温度下变化的模型(也许也可以适应这些转变温度)。
另一种方法是使用locate()
手动选择峰值,然后使用这些起始值与nls()
进行拟合。这将允许半自动存储不同温度下不同峰的强度、位置和 FWHM。这可能是一种更稳健的方法。
@ThibaudRuelle:不,他们不遵循,但他们可以生成一组新功能,然后您可以在这些功能上使用,例如将位置与温度联系起来。我想多元曲线分辨率的功能版本可能是您正在寻找的 - 但我想我刚刚发明了这个非常棒的方法;-)。至于locate
,这可能至少与衍生产品具有相同的问题。但如果你选择它,hyperSpec::spc.identify
可能会帮助你(它默认寻找本地最大值,但你可以关闭它)。
我会花更多时间考虑一下,但我想我可能必须从手工开始。这只是一个学期的项目,所以很遗憾,我花在它上面的时间有限。我会及时向大家发布。谢谢!
最后,结构太复杂了,考虑到最后期限,我不得不手工完成。然而,有一个想法是使用迭代起始值来跟踪从光谱到光谱的“移动”峰,我将尝试实现这一点(我希望在不久的将来)。 @cbeleites 如果我想出一些值得引入到 hyperspec 包中的东西,我会通知你。以上是关于如何实现半自动峰值拾取的主要内容,如果未能解决你的问题,请参考以下文章