📄 ipf.m
字号:
% keys.
% Top half of the figure shows original signal
global AUTOZERO
Startx=round(xo-(dx/2));
Endx=round(xo+(dx/2)-1);
if Endx>length(Y),
Endx=length(Y);
end
if Startx<1,
Startx=1;
end
PlotRange=[Startx:Endx];
if PlotRange<5, PlotRange=[xo:xo+5];,end
xx=X(PlotRange);
yy=Y(PlotRange);
% Remove comments from the next 5 lines to enable auto-zero operation
if AUTOZERO==1,
X1=min(xx);
X2=max(xx);
Y1=mean(yy(1:length(xx)/10));
Y2=mean(yy((length(xx)-length(xx)/10):length(xx)));
yy=yy-((Y2-Y1)/(X2-X1)*(xx-X1)+Y1);end % if
subplot(2,1,1);plot(xx,yy,'b.'); % Plot the original signal in blue
hold on
% Mark starting peak positions with vertical dashed lines
% Determine locations for peak (vertical line) markers
n=max(xx)-min(xx);
start=[];
startpos=[n/(NumPeaks+1):n/(NumPeaks+1):n-(n/(NumPeaks+1))]+min(xx);
for marker=1:NumPeaks,
markx=startpos(marker);
start=[start markx n/20];
subplot(2,1,1);plot([markx markx],[min(yy) max(yy)],'m--')
end % for
hold off
title('Pan and Zoom to isolate peaks to be fit in upper window.')
xlabel('Line up the estimated peak positions roughly with the vertical lines')
% axis([round(xo-(dx/2)) round(xo+(dx/2)-1) min(yy) max(yy)])
axis([X(Startx) X(Endx) min(yy) max(yy)]);
% Bottom half of the figure shows full signal
subplot(2,1,2);plot(X,Y)
hold on
for marker=1:NumPeaks,
markx=startpos(marker);
subplot(2,1,2);plot([markx markx],[min(Y) max(Y)],'m--')
end % for
hold off
xlabel([' # Peaks = 1-5; Shape = G,L,O,P,E; F to fit; B = baseline; C = custom.'])
% ----------------------------------------------------------------------
function [FitResults,MeanFitError]=FitAndPlot(xx,yy,NumPeaks,Shape,delta,start,extra)
% Given isolated segment of signal (xx,yy), plots it in upper half, computes fit with
% "NumPeaks" component peaks of shape "Shape", starting with start values
% "start", then plots residuals in lower half.
% T. C. O'Haver (toh@umd.edu), Version 2, March 2008, uses unconstrained
% fit.
global PEAKHEIGHTS
%global extra
%global MeanFitError
PEAKHEIGHTS=zeros(1,NumPeaks);
n=length(xx);
x0=min(xx);
h=figure(1);
% Perform peak fitting for selected peak shape using fminsearch function
options = optimset('TolX',.01);
switch Shape
case 1
FitParameters=fminsearch(@fitgaussian,start,options,xx,yy);
ShapeString='Gaussian';
case 2
FitParameters=fminsearch(@fitlorentzian,start,options,xx,yy);
ShapeString='Lorentzian';
case 3
FitParameters=fminsearch(@fitlogistic,start,options,xx,yy);
ShapeString='Logistic';
case 4
FitParameters=fminseefarch(@fitpearson,start,options,xx,yy,extra);
ShapeString='Pearson';
case 5
FitParameters=fminsearch(@fitexpgaussian,start,options,xx,yy,-extra);
ShapeString='ExpGaussian';
otherwise
end % switch
% Construct model from fitted parameters
A=zeros(NumPeaks,n);
AA=zeros(NumPeaks,100);
xxx=linspace(min(xx),max(xx));
for m=1:NumPeaks,
switch Shape
case 1
A(m,:)=gaussian(xx,FitParameters(2*m-1),FitParameters(2*m));
AA(m,:)=gaussian(xxx,FitParameters(2*m-1),FitParameters(2*m));
case 2
A(m,:)=lorentzian(xx,FitParameters(2*m-1),FitParameters(2*m));
AA(m,:)=lorentzian(xxx,FitParameters(2*m-1),FitParameters(2*m));
case 3
A(m,:)=logistic(xx,FitParameters(2*m-1),FitParameters(2*m));
AA(m,:)=logistic(xxx,FitParameters(2*m-1),FitParameters(2*m));
case 4
A(m,:)=pearson(xx,FitParameters(2*m-1),FitParameters(2*m),extra);
AA(m,:)=pearson(xxx,FitParameters(2*m-1),FitParameters(2*m),extra);
case 5
A(m,:)=expgaussian(xx,FitParameters(2*m-1),FitParameters(2*m),-extra)';
AA(m,:)=expgaussian(xxx,FitParameters(2*m-1),FitParameters(2*m),-extra)';
otherwise
end % switch
end % for
model=PEAKHEIGHTS'*A; % Multiplies each row by the corresponding amplitude and adds them up
mmodel=PEAKHEIGHTS'*AA;
% Top half of the figure shows original signal and the fitted model.
subplot(2,1,1);plot(xx,yy,'b.'); % Plot the original signal in blue dots
hold on
for m=1:NumPeaks,
plot(xxx,PEAKHEIGHTS(m)*AA(m,:),'g') % Plot the individual component peaks in green lines
area(m)=trapz(xx,PEAKHEIGHTS(m)*A(m,:)); % Compute the area of each component peak using trapezoidal method
end
% Mark starting peak positions with vertical dashed lines
for marker=1:NumPeaks,
markx=start((2*marker)-1);
subplot(2,1,1);plot([markx markx],[0 max(yy)],'m--')
end % for
plot(xxx,mmodel,'r'); % Plot the total model (sum of component peaks) in red lines
hold off;
axis([min(xx) max(xx) min(yy) max(yy)]);
title('Pan and Zoom to select peaks; #peaks 1-5; Shape=G,L,O,P,E; F=fit; B=baseline; C=custom')
xlabel('Vertical dotted lines indicate first guess peak positions');
% Bottom half of the figure shows the residuals and displays RMS error between original signal and model
residual=yy-model;
subplot(2,1,2);plot(xx,residual,'b.')
MeanFitError=100*norm(residual)./(sqrt(n)*max(yy));
xlabel(['Peaks = ' num2str(NumPeaks) ' Shape = ' ShapeString ' Error = ' num2str(MeanFitError) ' Extra = ' num2str(extra) ] )
axis([min(xx) max(xx) min(residual) max(residual)]);
% Put results into a matrix, one row for each peak, showing peak index number,
% position, amplitude, and width.
for m=1:NumPeaks,
if m==1,
FitResults=[round(m) FitParameters(2*m-1) PEAKHEIGHTS(m) abs(FitParameters(2*m)) area(m)];
else
FitResults=[FitResults ; [round(m) FitParameters(2*m-1) PEAKHEIGHTS(m) abs(FitParameters(2*m)) area(m)]];
end % if
end % for
% Display Fit Results on upper graph
subplot(2,1,1);
residualaxis=axis;
text(residualaxis(1), 0.8*residualaxis(4) ,num2str(FitResults));
% ----------------------------------------------------------------------
function err = fitgaussian(lambda,t,y)
% Fitting function for a Gaussian band spectrum.
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = gaussian(t,lambda(2*j-1),lambda(2*j))';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = gaussian(x,pos,wid)
% gaussian(X,pos,wid) = gaussian peak centered on pos, half-width=wid
% X may be scalar, vector, or matrix, pos and wid both scalar
% Examples: gaussian([0 1 2],1,2) gives result [0.5000 1.0000 0.5000]
% plot(gaussian([1:100],50,20)) displays gaussian band centered at 50 with width 20.
g = exp(-((x-pos)./(0.6006.*wid)) .^2);
% ----------------------------------------------------------------------
function err = fitlorentzian(lambda,t,y)
% Fitting function for single lorentzian, lambda(1)=position, lambda(2)=width
% Fitgauss assumes a lorentzian function
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = lorentzian(t,lambda(2*j-1),lambda(2*j))';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = lorentzian(x,position,width)
% lorentzian(x,position,width) Lorentzian function.
% where x may be scalar, vector, or matrix
% position and width scalar
% T. C. O'Haver, 1988
% Example: lorentzian([1 2 3],2,2) gives result [0.5 1 0.5]
g=ones(size(x))./(1+((x-position)./(0.5.*width)).^2);
% ----------------------------------------------------------------------
function err = fitlogistic(lambda,t,y)
% Fitting function for logistic, lambda(1)=position, lambda(2)=width
% between the data and the values computed by the current
% function of lambda. Fitlogistic assumes a logistic function
% T. C. O'Haver, May 2006
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = logistic(t,lambda(2*j-1),lambda(2*j))';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = logistic(x,pos,wid)
% logistic function. pos=position; wid=half-width (both scalar)
% logistic(x,pos,wid), where x may be scalar, vector, or matrix
% pos=position; wid=half-width (both scalar)
% T. C. O'Haver, 1991
n = exp(-((x-pos)/(.477.*wid)) .^2);
g = (2.*n)./(1+n);
% ----------------------------------------------------------------------
function err = fitlognormal(lambda,t,y)
% Fitting function for lognormal, lambda(1)=position, lambda(2)=width
% between the data and the values computed by the current
% function of lambda. Fitlognormal assumes a lognormal function
% T. C. O'Haver, May 2006
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = lognormal(t,lambda(2*j-1),lambda(2*j))';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = lognormal(x,pos,wid)
% lognormal function. pos=position; wid=half-width (both scalar)
% lognormal(x,pos,wid), where x may be scalar, vector, or matrix
% pos=position; wid=half-width (both scalar)
% T. C. O'Haver, 1991
g = exp(-(log(x/pos)/(0.01.*wid)) .^2);
% ----------------------------------------------------------------------
function err = fitpearson(lambda,t,y,shapeconstant)
% Fitting functions for a Pearson 7 band spectrum.
% T. C. O'Haver (toh@umd.edu), Version 1.3, October 23, 2006.
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = pearson(t,lambda(2*j-1),lambda(2*j),shapeconstant)';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = pearson(x,pos,wid,m)
% Pearson VII function.
% g = pearson7(x,pos,wid,m) where x may be scalar, vector, or matrix
% pos=position; wid=half-width (both scalar)
% m=some number
% T. C. O'Haver, 1990
g=ones(size(x))./(1+((x-pos)./((0.5.^(2/m)).*wid)).^2).^m;
% ----------------------------------------------------------------------
function err = fitexpgaussian(lambda,t,y,timeconstant)
% Fitting functions for a exponentially-broadened Gaussian band spectrum.
% T. C. O'Haver, October 23, 2006.
global PEAKHEIGHTS
A = zeros(length(t),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = expgaussian(t,lambda(2*j-1),lambda(2*j),timeconstant);
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = expgaussian(x,pos,wid,timeconstant)
% Exponentially-broadened gaussian(x,pos,wid) = gaussian peak centered on pos, half-width=wid
% x may be scalar, vector, or matrix, pos and wid both scalar
% T. C. O'Haver, 2006
g = exp(-((x-pos)./(0.6006.*wid)) .^2);
g = ExpBroaden(g',timeconstant);
% ----------------------------------------------------------------------
function yb = ExpBroaden(y,t)
% ExpBroaden(y,t) convolutes y by an exponential decay of time constant t
% by multiplying Fourier transforms and inverse transforming the result.
fy=fft(y);
a=exp(-[1:length(y)]./t);
fa=fft(a);
fy1=fy.*fa';
yb=real(ifft(fy1))./sum(a);
% ----------------------------------------------------------------------
function err = fitNewPeakShape(lambda,x,y)
% Replace "NewPeakShape" with the peak function of your choice.
% T. C. O'Haver, 2006
global PEAKHEIGHTS
A = zeros(length(x),round(length(lambda)/2));
for j = 1:length(lambda)/2,
A(:,j) = NewPeakShape(x,lambda(2*j-1),lambda(2*j))';
end
PEAKHEIGHTS = A\y';
z = A*PEAKHEIGHTS;
err = norm(z-y');
% ----------------------------------------------------------------------
function g = NewPeakShape(x,a,b)
% Replace this with the peak function of your choice.
% a and b are the two non-linear parameters.
g=sin(a.*x+b);
% ----------------------------------------------------------------------
% Note: Add this to your Matlab path if you don't already have it.
%% function [index,closestval]=val2ind(x,val)
%% Returns the index and the value of the element of vector x that is closest to val
%% If more than one element is equally close, returns vectors of indicies and values
%% Tom O'Haver (toh@umd.edu) October 2006
%% Examples: If x=[1 2 4 3 5 9 6 4 5 3 1], then val2ind(x,6)=7 and val2ind(x,5.1)=[5 9]
%% [indices values]=val2ind(x,3.3) returns indices = [4 10] and values = [3 3]
% dif=abs(x-val);
% index=find((dif-min(dif))==0);
% closestval=x(index);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -