谱峰的检测是色谱、质谱等几乎所有谱图处理中重要的一环。关于谱峰检测的算法有很多,Zhang et al【1】等总结了一些算法,但是可惜我水平差,看不懂。 于是我想到了一个简单的算法-相邻值比较。如果一个点Y n 大于Y (n-1) 也大于Y (n+1) 的话,那么Yn就是峰。实际的结果是如果谱图基线不平的话,最终可能会出现很多的峰。这个算法过于简单。 第二个算法就是按照斜率的算法,首先找到波谷,然后再去计算后面的最高值与波谷之间所形成角度,如果这个角度大于阀值,则后面的这个最高值就是峰。虽然这个算法也不是完美的,但是至少要比第一个的好上许多,再仔细雕琢的话,就会成为一个比较简单的找峰算法。 其余的复杂算法有很多,有人使用小波分析什么的,总之林林种种。一个新算法搞好了,就可以发在bioinformatics上。我只是处理一些简单的数据,没必要再从头开始学R或matlab。简简单单最好了。 例子程序: procedure TForm3.FindPeaks(); var N:integer; i,j,k:Integer; MinValue,MaxValue:Double; x1,y1,x2,y2:Double; begin N:=Series1.XValues.Count; // Series1: TFastLineSeries; Series1 与Series2 来自于TChart MinValue :=Series1.YValues.MinValue; MaxValue :=Series1.YValues.MaxValue; x1:= Series1.XValue ; y1:= Series1.YValue ; for i := 2 to N - 2 do begin if Series1.YValue = y1 then begin x1:=Series1.XValue ; y1:=Series1.YValue ; end else begin if Series1.YValue = Series1.YValue then begin x2:=Series1.XValue ; y2:=Series1.YValue ; if ((y2-y1)/(x2-x1)) Threshold then begin //Threshold := 2; if (y2-y1) ((MaxValue-MinValue)*0.1) then begin // 0.1 为阀值 Series2.AddXY(Series1.XValue ,Series1.YValue ); // Series2: TPointSeries; x1:=Series1.XValue ; y1:=Series1.YValue ; end; end; end; end; end; end; 【1】Jianqiu Zhang, Elias Gonzalez, Travis Hestilow, William Haskins and Yufei Huang, Review of Peak Detection Algorithms in Liquid-Chromatography-Mass Spectrometry, Current Genomics, 2009, 10, 388-401.