Fitpeaks: Difference between revisions

From Eigenvector Research Documentation Wiki
Jump to navigation Jump to search
imported>Jeremy
(Importing text file)
 
imported>Neal
 
(23 intermediate revisions by 3 users not shown)
Line 1: Line 1:
===Purpose===
===Purpose===
Peak fitting routine.
Peak fitting routine.
===Synopsis===
===Synopsis===
:[peakdefo,fval,exitflag,out,fit,res] = fitpeaks(peakdef,y,ax,options)
 
:[peakdefo,fval,exitflag,out,fit,res] = fitpeaks(peakdef,y,''ax,options'')
 
===Description===
===Description===
Based on the initial guess in input peakdef, FITPEAKS estimates the peak fit (also the Jacobian and Hessian), and makes a call to LMOPTIMIZEBND to find the best fit of the peaks to the data. (See LMOPTIMIZEBND for additional information.) Results are output to peakdefo.
 
Information about individual peaks is stored in standard peak structures (see PEAKSTRUCT). Information on multiple peaks is stored in a multi-record structure. Given a standard peak structure (peakdef) that contains an initial guess of peak locations and widths, FITPEAKS finds new parameters that best fits peaks to the rows of the '' '' data matrix (y). Results are output to a standard peak structure (peakdefo).
Based on the initial guess in input <tt>peakdef</tt>, FITPEAKS estimates the peak fit (also the Jacobian and Hessian), and makes a call to LMOPTIMIZEBND to find the best fit of the peaks to the data. (See LMOPTIMIZEBND for additional information.) Results are output to <tt>peakdefo</tt>.
Fields of (peakdef) required in the initial guess for each peak are (.fun), (.param), (.lb), (.penlb), (.ub), and (.penub).
 
INPUTS:
Information about individual peaks is stored in standard peak structures (see PEAKSTRUCT). Information on multiple peaks is stored in a multi-record structure. Given a standard peak structure <tt>peakdef</tt> that contains an initial guess of peak locations and widths, FITPEAKS finds new parameters that best fits peaks to the rows of the <math>\scriptstyle M \, x \, N</math> data matrix <tt>y</tt>. Results are output to a standard peak structure <tt>peakdefo</tt>.
* peakdef = multi-record standard peak structure with the following fields:
 
* name: 'Peak', name indicating that this is a standard peak structure.
Fields of <tt>peakdef</tt> required in the initial guess for each peak are <tt>.fun</tt>, <tt>.param</tt>, <tt>.lb</tt>, <tt>.penlb</tt>, <tt>.ub</tt>, and <tt>.penub</tt>.
* id: ' ', double or character string peak identification.
 
* fun: [ {'Gaussian'} | 'Lorentzian' | 'PVoigt1' | 'PVoigt2' ], defines the peak function (see definitions in the Algorithm section).
====Inputs====
* param: Parameter list for each peak function. The number of parameters depends on the peak function used:
 
*  'Gaussian': [height, location, width],
* '''peakdef''' = multi-record standard peak structure with the following fields:
*  'Lorentzian': [height, location, width],
** '''name''': 'Peak', name indicating that this is a standard peak structure.
*  'PVoigt1': [height, location, width, fraction Gaussian],
** '''id''': ' ', double or character string peak identification.
*  'PVoigt2': [height, location, width, fraction Gaussian].
** '''fun''': [ {'Gaussian'} | 'Lorentzian' | 'PVoigt1' | 'PVoigt2' ], defines the peak function (see definitions in the Algorithm section).
* lb: [ ], Lower bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
** '''param''': Parameter list for each peak function. The number of parameters depends on the peak function used:
* penlb: [ ], Penalty wt for lower bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
**''''Gaussian'''': [height, location, width] (width is expressed as standard deviation - multiply by 2*sqrt(2*(-log(0.5))) = 2.3548 to calculate full-width at half-height.)
* ub: [ ], Upper bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
**''''Lorentzian'''': [height, location, width] (width is expressed as half-width - multiply by 2 to calculate full-width at half-height.)
* penub: [ ], Penalty wt for upper bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
**''''PVoigt1'''': [height, location, width, fraction Gaussian]
* area: [ ], Estimated peak area.
**''''PVoigt2'''': [height, location, width, fraction Gaussian]
* y = ''M''x''N'' measured responses with peaks to fit. Each row of (y) is fit to the peaks given in (peakdef).
***  ''''GaussianSkew'''': [height, location, width, skewparameter]
OPTIONAL INPUTS:
** '''lb''': [ ], Lower bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
* ax = 1x''N'' x-axis to fit to {default ax=1:N}.
** '''penlb''': [ ], Penalty wt for lower bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
* options = discussed below in the Options Section.
** '''ub''': [ ], Upper bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
OUTPUTS:
** '''penub''': [ ], Penalty wt for upper bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
* peakdefo = The input peak structure (peakdef) with parameters changed to correspond to the best fit values.
** '''area''': [ ], Estimated peak area.
* fval = Scalar value of the objective function evaluated at termination of FITPEAKS.
* '''y''' = ''M''x''N'' measured responses with peaks to fit. Each row of (y) is fit to the peaks given in (peakdef).
* exitflag = Describes the exit condition (see LMOPTIMIZEBND).
 
* out = Structure array with information on the optimization/fitting (see LMOPTIMIZEBND).
====Optional Inputs====
* fit = Model fit of the peaks, i.e it is the best fit to (y).
 
* res = Residuals of fit of the peaks.
* '''ax''' = 1x''N'' x-axis to fit to {default <tt>ax</tt>=1:N}.
 
* '''options''' = discussed below in the Options Section.
 
====Outputs====
 
* '''peakdefo''' = The input peak structure <tt>peakdef</tt> with parameters changed to correspond to the best fit values.
 
* '''fval''' = Scalar value of the objective function evaluated at termination of FITPEAKS.
 
* '''exitflag''' = Describes the exit condition (see LMOPTIMIZEBND).
 
* '''out''' = Structure array with information on the optimization/fitting (see LMOPTIMIZEBND).
 
* '''fit''' = Model fit of the peaks, i.e it is the best fit to <tt>y</tt>.
 
* '''res''' = Residuals of fit of the peaks.
 
===Algorithm===
===Algorithm===
Peaks are fit to the functions defined below based on the definitions in the field (peakdef.fun). The functions can be evaluated using independent functions or a wrapper function PEAKFUNCTION. See PEAKFUNCTION for more help.
 
For peakdef.fun = 'Gaussian' the function is
Peaks are fit to the functions defined below based on the definitions in the field (<tt>peakdef.fun</tt>). The functions can be evaluated using independent functions or a wrapper function PEAKFUNCTION. See PEAKFUNCTION for more help.
 
 
where   is the   element of optional input (ax), and   corresponds to the peak parameters in the three-element vector (peakdef.param). Constraints that should be used are (bounds in peakdef) are   and .
For <tt>peakdef.fun</tt> = 'Gaussian' the function is
For peakdef.fun = 'Lorentzian' the function is
 
  .
 
Constraints that should be used are (bounds in peakdef) are   and .
::<math>f(a_i, \mathbf {x}) = x_1 \exp \left ( \frac {- \left (a_i - x_2 \right )^2} {2\left (x_3 \right )^2} \right )</math>
For peakdef.fun = 'PVoigt1' the function is
 
 
 
where   corresponds to the peak parameters in the four-element vector (peakdef.param). Constraints that should be used are (bounds in peakdef) are   and , while . The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.
where <math>\scriptstyle a_i,\,i = 1, \ldots N</math>  is the ''i<sup>th</sup>'' element of optional input <tt>ax</tt>, and <math>\scriptstyle \mathbf {x} = \left [x_1 \; x_2 \; x_3 \right ]</math>  corresponds to the peak parameters in the three-element vector <tt>peakdef.param</tt>. Constraints that should be used are (bounds in <tt>peakdef</tt>) are <math>\scriptstyle x_1 \ge 0</math>  and <math>\scriptstyle x_3 \ge 0</math> .
For peakdef.fun = 'PVoigt2' the function is
 
 
For <tt>peakdef.fun</tt> = 'Lorentzian' the function is
where   corresponds to the peak parameters in the four-element vector (peakdef.param). Constraints that should be used (bounds in peakdef) are   and , while . The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.
 
A comparison of the four peaks is given in the figure below, and was generated using the following code:
 
ax    = 0:0.1:100;
::<math>f(a_i, \mathbf {x}) = x_1 \left [ 1+ \left ( \frac {a_i - x_2 } {x_3} \right ) ^2 \right ] ^ {-1} = x_1 \left [ \frac { \left ( x_3 \right ) ^2 } {\left ( x_3 \right ) ^2 + \left ( a_i - x_2 \right) ^2 }\right ]</math>
y      = zeros(4,length(ax));
 
plot(ax,peakgaussian([2 51 8],ax),'-b', ...
 
:      ax,peaklorentzian([2 51 8],ax),'--k', ...
Constraints that should be used are (bounds in <tt>peakdef</tt>) are <math>\scriptstyle x_1 \ge 0</math>  and <math>\scriptstyle x_3 \ge 0</math> .
:      ax,peakpvoigt1([2 51 8 0.5],ax),':g', ...
 
:      ax,peakpvoigt2([2 51 8 0.5],ax),'-.r')
For <tt>peakdef.fun</tt> = 'PVoigt1' the function is
legend('Gaussian','Lorentzian','PVoigt1','PVoigt2')
 
 
::<math>f(a_i, \mathbf {x}) = x_1 \left [ x_4
\exp \left ( \frac {-4 \ln(2) \left (a_i - x_2 \right ) ^2 } {\left ( x_3 \right ) ^2} \right )
+ \left ( 1-x_4 \right )
\left [
\frac { \left (x_3 \right )^2}
{\left ( a_i -x_2 \right ) ^2 + \left ( x_3 \right ) ^2}
\right ]
\right ]</math>
 
 
where <math>\scriptstyle \mathbf {x} = \left [x_1 \; x_2 \; x_3 \; x_4 \right ]</math> corresponds to the peak parameters in the four-element vector <tt>peakdef.param</tt>. Constraints that should be used are (bounds in <tt>peakdef</tt>) are <math>\scriptstyle x_1 \ge 0</math>  and <math>\scriptstyle x_3 \ge 0</math>, while <math>\scriptstyle 1 \ge x_4 \ge 0</math>. The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.
 
For <tt>peakdef.fun</tt> = 'PVoigt2' the function is
 
 
::<math>f(a_i, \mathbf {x}) = x_1 \left [ x_4
\exp \left ( \frac {- \left (a_i - x_2 \right ) ^2 } {2 \left ( x_3 \right ) ^2} \right )
+ \left ( 1-x_4 \right )
\left [
\frac { \left (x_3 \right )^2}
{\left ( a_i -x_2 \right ) ^2 + \left ( x_3 \right ) ^2}
\right ]
\right ]</math>
 
 
where <math>\scriptstyle \mathbf {x} = \left [x_1 \; x_2 \; x_3 \; x_4 \right ]</math> corresponds to the peak parameters in the four-element vector <tt>peakdef.param</tt>. Constraints that should be used (bounds in <tt>peakdef</tt>) are <math>\scriptstyle x_1 \ge 0</math>  and <math>\scriptstyle x_3 \ge 0</math>, while <math>\scriptstyle 1 \ge x_4 \ge 0</math> . The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.
 
For <tt>peakdef.fun</tt> = 'GaussianSkew' (a skewed Gaussian) the function is
 
 
 
::<math>f\left( \mathbf{x} \right)={{x}_{1}}{{e}^{\tfrac{-{{\left( x-{{x}_{2}} \right)}^{2}}}{2x_{3}^{2}}}}\int_{-\infty }^{{{x}_{4}}\left( \tfrac{x-{{x}_{2}}}{{{x}_{3}}} \right)}{{{e}^{\tfrac{-{{t}^{2}}}{2}}}dt}</math>
 
 
where <math>\scriptstyle \mathbf {x} = \left [x_1 \; x_2 \; x_3 \; x_4 \right ]</math> corresponds to the peak parameters in the four-element vector <tt>peakdef.param</tt>. Constraints that should be used (bounds in <tt>peakdef</tt>) are <math>\scriptstyle x_1 \ge 0</math>  and <math>\scriptstyle x_3 \ge 0</math>. The peak area is <math>\pi {{x}_{1}}{{x}_{3}}</math>.
 
A comparison of the first four peaks is given in the figure below, and was generated using the following code:
 
<pre>
  ax    = 0:0.1:100;
  y      = zeros(4,length(ax));
  plot(ax,peakgaussian([2 51 8],ax),'-b', ...
      ax,peaklorentzian([2 51 8],ax),'--k', ...
      ax,peakpvoigt1([2 51 8 0.5],ax),':g', ...
      ax,peakpvoigt2([2 51 8 0.5],ax),'-.r')
  legend('Gaussian','Lorentzian','PVoigt1','PVoigt2')
</pre>
 
 
 
[[Image:Peakfit_peakshapes.png]]
 
===Options===
===Options===
*options  = structure array with the following fields:
 
* name: 'options', name indicating that this is an options structure.
'''options''' = structure array with the following fields:
* display: [ 'off' | {'on'} ] governs level of display to the command window.
 
* optimopts: options structure from LMOPTIMIZEBND. This field is passed to LMOPTIMIZEBND and can be used to control the optimization / fitting.
* '''name''': 'options', name indicating that this is an options structure.
 
* '''display''': [ 'off' | {'on'} ] governs level of display to the command window.
 
* '''optimopts''': options structure from LMOPTIMIZEBND. This field is passed to LMOPTIMIZEBND and can be used to control the optimization / fitting.
 
===Examples===
===Examples===
:%Make a single known peak
 
ax            = 0:0.1:100;
<pre>%Make a single known peak
y            = peakgaussian([2 51 8],ax);
ax            = 0:0.1:100;
:%Define first estimate and peak type
y            = peakgaussian([2 51 8],ax);
peakdef      = peakstruct;
 
peakdef.param = [0.1  43  5]; %coef, position, spread
%Define first estimate and peak type
peakdef.lb    = [0    0  0.0001]; %lower bounds on param
peakdef      = peakstruct;
peakdef.penlb = [1e-6 1e-6 1e-6];
peakdef.param = [0.1  43  5]; %coef, position, spread
peakdef.ub    = [10 99.9 40]; %upper bounds on params
peakdef.lb    = [0    0  0.0001]; %lower bounds on param
peakdef.penub = [1e-6 1e-6 1e-6];
peakdef.penlb = [1e-6 1e-6 1e-6];
:%Estimate fit and plot
peakdef.ub    = [10 99.9 40]; %upper bounds on params
yint  = peakfunction(peakdef,ax);
peakdef.penub = [1e-6 1e-6 1e-6];
[peakdef,fval,exitflag,out] = fitpeaks(peakdef,y,ax);
 
yfit  = peakfunction(peakdef,ax); figure
%Estimate fit and plot
plot(ax,yint,'m',ax,y,'b',ax,yfit,'r--')
yint  = peakfunction(peakdef,ax);
legend('Initial','Actual','Fit')
[peakdef,fval,exitflag,out] = fitpeaks(peakdef,y,ax);
yfit  = peakfunction(peakdef,ax); figure
plot(ax,yint,'m',ax,y,'b',ax,yfit,'r--')
legend('Initial','Actual','Fit')</pre>
 
===See Also===
===See Also===
[[peakfind]], [[lmoptimizebnd]], [[peakfunction]], [[peakgaussian]], [[peaklorentzian]], [[peakpvoigt1]], [[peakpvoigt2]], [[peakstruct]]
[[peakfind]], [[lmoptimizebnd]], [[peakfunction]], [[peakgaussian]], [[peaklorentzian]], [[peakpvoigt1]], [[peakpvoigt2]], [[peakstruct]]

Latest revision as of 15:39, 21 January 2011

Purpose

Peak fitting routine.

Synopsis

[peakdefo,fval,exitflag,out,fit,res] = fitpeaks(peakdef,y,ax,options)

Description

Based on the initial guess in input peakdef, FITPEAKS estimates the peak fit (also the Jacobian and Hessian), and makes a call to LMOPTIMIZEBND to find the best fit of the peaks to the data. (See LMOPTIMIZEBND for additional information.) Results are output to peakdefo.

Information about individual peaks is stored in standard peak structures (see PEAKSTRUCT). Information on multiple peaks is stored in a multi-record structure. Given a standard peak structure peakdef that contains an initial guess of peak locations and widths, FITPEAKS finds new parameters that best fits peaks to the rows of the data matrix y. Results are output to a standard peak structure peakdefo.

Fields of peakdef required in the initial guess for each peak are .fun, .param, .lb, .penlb, .ub, and .penub.

Inputs

  • peakdef = multi-record standard peak structure with the following fields:
    • name: 'Peak', name indicating that this is a standard peak structure.
    • id: ' ', double or character string peak identification.
    • fun: [ {'Gaussian'} | 'Lorentzian' | 'PVoigt1' | 'PVoigt2' ], defines the peak function (see definitions in the Algorithm section).
    • param: Parameter list for each peak function. The number of parameters depends on the peak function used:
      • 'Gaussian': [height, location, width] (width is expressed as standard deviation - multiply by 2*sqrt(2*(-log(0.5))) = 2.3548 to calculate full-width at half-height.)
      • 'Lorentzian': [height, location, width] (width is expressed as half-width - multiply by 2 to calculate full-width at half-height.)
      • 'PVoigt1': [height, location, width, fraction Gaussian]
      • 'PVoigt2': [height, location, width, fraction Gaussian]
      • 'GaussianSkew': [height, location, width, skewparameter]
    • lb: [ ], Lower bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
    • penlb: [ ], Penalty wt for lower bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
    • ub: [ ], Upper bounds on the function parameters. This is a row vector with the same number of elements as peakdef.param.
    • penub: [ ], Penalty wt for upper bounds, >=0. This is a row vector with the same number of elements as peakdef.param. If set to 0 this constraint is not employed.
    • area: [ ], Estimated peak area.
  • y = MxN measured responses with peaks to fit. Each row of (y) is fit to the peaks given in (peakdef).

Optional Inputs

  • ax = 1xN x-axis to fit to {default ax=1:N}.
  • options = discussed below in the Options Section.

Outputs

  • peakdefo = The input peak structure peakdef with parameters changed to correspond to the best fit values.
  • fval = Scalar value of the objective function evaluated at termination of FITPEAKS.
  • exitflag = Describes the exit condition (see LMOPTIMIZEBND).
  • out = Structure array with information on the optimization/fitting (see LMOPTIMIZEBND).
  • fit = Model fit of the peaks, i.e it is the best fit to y.
  • res = Residuals of fit of the peaks.

Algorithm

Peaks are fit to the functions defined below based on the definitions in the field (peakdef.fun). The functions can be evaluated using independent functions or a wrapper function PEAKFUNCTION. See PEAKFUNCTION for more help.

For peakdef.fun = 'Gaussian' the function is



where is the ith element of optional input ax, and corresponds to the peak parameters in the three-element vector peakdef.param. Constraints that should be used are (bounds in peakdef) are and .

For peakdef.fun = 'Lorentzian' the function is



Constraints that should be used are (bounds in peakdef) are and .

For peakdef.fun = 'PVoigt1' the function is



where corresponds to the peak parameters in the four-element vector peakdef.param. Constraints that should be used are (bounds in peakdef) are and , while . The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.

For peakdef.fun = 'PVoigt2' the function is



where corresponds to the peak parameters in the four-element vector peakdef.param. Constraints that should be used (bounds in peakdef) are and , while . The Pseudo-Voigt peak shape is an estimate of the Gaussian and Lorentzian peak shapes convolved.

For peakdef.fun = 'GaussianSkew' (a skewed Gaussian) the function is



where corresponds to the peak parameters in the four-element vector peakdef.param. Constraints that should be used (bounds in peakdef) are and . The peak area is .

A comparison of the first four peaks is given in the figure below, and was generated using the following code:

  ax     = 0:0.1:100;
  y      = zeros(4,length(ax));
  plot(ax,peakgaussian([2 51 8],ax),'-b', ...
       ax,peaklorentzian([2 51 8],ax),'--k', ...
       ax,peakpvoigt1([2 51 8 0.5],ax),':g', ...
       ax,peakpvoigt2([2 51 8 0.5],ax),'-.r')
  legend('Gaussian','Lorentzian','PVoigt1','PVoigt2')


Peakfit peakshapes.png

Options

options = structure array with the following fields:

  • name: 'options', name indicating that this is an options structure.
  • display: [ 'off' | {'on'} ] governs level of display to the command window.
  • optimopts: options structure from LMOPTIMIZEBND. This field is passed to LMOPTIMIZEBND and can be used to control the optimization / fitting.

Examples

%Make a single known peak
ax            = 0:0.1:100;
y             = peakgaussian([2 51 8],ax);

%Define first estimate and peak type
peakdef       = peakstruct;
peakdef.param = [0.1  43   5]; %coef, position, spread
peakdef.lb    = [0     0  0.0001]; %lower bounds on param
peakdef.penlb = [1e-6 1e-6 1e-6];
peakdef.ub    = [10 99.9 40]; %upper bounds on params
peakdef.penub = [1e-6 1e-6 1e-6];

%Estimate fit and plot
yint   = peakfunction(peakdef,ax);
[peakdef,fval,exitflag,out] = fitpeaks(peakdef,y,ax);
yfit   = peakfunction(peakdef,ax); figure
plot(ax,yint,'m',ax,y,'b',ax,yfit,'r--')
legend('Initial','Actual','Fit')

See Also

peakfind, lmoptimizebnd, peakfunction, peakgaussian, peaklorentzian, peakpvoigt1, peakpvoigt2, peakstruct