3.9.2.1.3 Fit Multiple Peaks

Version Info

Minimum Origin Version Required: Origin 8.1 SR0

Need to do before Running Examples

Prior to running the following example, the nlsf_utils.c file need to be loaded and compiled. This can be done from script with the following command or just add this file to your workspace.

run.LoadOC(Originlab\nlsf_utils.c);

Examples

The following code shows how to use NLFitSesssion to fit on multiple peaks in one dataset.

Before running new a worksheet and import \Samples\Curve Fitting\Multiple Peaks.dat, delete other columns just keep the first two columns. Then run "test_NLFitSession" in Command Window.

#include <Origin.h>
#include <..\originlab\NLFitSession.h>

#define ERR_RETURN(_ERR_MSG) { \
    out_str(_ERR_MSG); \
    return; \
}
 
void test_NLFitSession(int nNumPeaks = 3)
{
    Worksheet   wks = Project.ActiveLayer();
    if( !wks )
        return; 
 
    // assume there is one pair XY columns in active worksheet including two peaks data
    XYRange drInput;
    drInput.Add(wks, 0, "X");
    drInput.Add(wks, 1, "Y");
    drInput.Add(); 
 
    vector vX1, vY1;
    drInput.GetData(vY1, vX1, NULL, 0);
 
    NLFitSession nlfSession;
 
    // Set Function
    if ( !nlfSession.SetFunction("Gauss", NULL, nNumPeaks) ) // set function with peak number
        ERR_RETURN("Fail to set function!");
 
    // Set Data and only need to set the last dataset with global fit mode, as to allow share parameters
    if ( !nlfSession.SetData(vY1, vX1) )
        ERR_RETURN("Fail to set data for the first dataset!")
 
    // Parameter initialization
    if ( !nlfSession.ParamsInitValues() )
        ERR_RETURN("Fail to init parameters values!")
 
    // Show parameters before fitting
    nlfSession.GetChiSqr(); // call GetChiSqr order to set parameter settings on internal fit object
    show_params(nlfSession, nNumPeaks, "Before ftting");
 
    //Set the maximum allowed number of iterate times, if fit not converged, try to set a bigger number
    nlfSession.SetMaxNumIter(400);
 
    // Do fit
    int nFitOutcome;
    bool bRet = nlfSession.Fit(&nFitOutcome); //if success    
 
    string strOutcome = nlfSession.GetFitOutCome(nFitOutcome);
    out_str("Outcome of the fitting session : " + strOutcome);
 
    if( bRet )
    {
        // Show parameters after fitting
        show_params(nlfSession, nNumPeaks, "After ftting");
 
        // Get the fitting result
        vector vFitY1(vX1.GetSize());
        nlfSession.GetYFromX(vX1, vFitY1, vX1.GetSize(), -1); //get cumulative fitted data
 
        // Put fitting data into new column in worksheet
        append_column_data(wks, vFitY1, "Fit Data");  
        
        GraphPage gp;
        gp.Create();
        GraphLayer gl = gp.Layers();
        gl.AddPlot(wks);
    }
}  
 
void append_column_data(Worksheet& wks, vector& vData, LPCSTR lpcstrLongName)
{
    int nCol = wks.AddCol();
    if( NULL != lpcstrLongName )
        wks.Columns(nCol).SetLongName(lpcstrLongName);
 
    Dataset ds(wks, nCol);
    ds = vData;
}  
 
void show_params(NLFitSession& nlfSession, int nCount, LPCSTR lpcscTitle)
{
    vector<double>  vParamValues;
    vector<int>     vParamOffsets;
    vector<string>  vsParamNames;
 
    //get parameters values and names
    nlfSession.GetParamValuesAndOffsets(vParamValues, vParamOffsets);
    nlfSession.GetParamNamesInFunction(vsParamNames);
 
    //output paramter values with names
    for ( int index = 0; index  < nCount; index++ )
    {
        printf("%s, parameters of Peak %d:\n", lpcscTitle, index + 1);
        for ( int nParam = vParamOffsets[index], ii = 0; nParam < vParamOffsets[index + 1]; nParam++, ii++ )
        {
            printf("%s = %lf\n", vsParamNames[ii], vParamValues[nParam]);
        }
    }
}