Fit Multiple XY Data in a loop

Version Info

Minimum Origin Version Required: Origin 8 SR6

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.



The following code shows how to use the NLFitSesssion to fit many datasets to the same function.

#include <Origin.h>
#include <..\originlab\NLFitSession.h>
// assume active worksheet with XYYYY data, all with a single peak
// so we can fit all of them to gauss function and gnerate a new worksheet to hold the fitting results.
void test1()
        Worksheet wks = Project.ActiveLayer();
        Worksheet wksOut;
        fit_all_cols(wks, wksOut);

static bool fit_all_cols(Worksheet& wks, Worksheet& wksOutput, string strFunc = "Gauss")
        NLFitSession    FitSession;
        int             nDataIndex = 0; // only one set in our case
        DWORD           dwRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
        // 1. Set fucntion
        if(!FitSession.SetFunction(strFunc, NULL)) // set function, category name can be ignore
            return error_report("invalid fit function");
        vector<string>  vsParamNames;
        int             nNumParamsInFunction = FitSession.GetParamNamesInFunction(vsParamNames);
        int                        nFitOutcome, nFitErr = -1;
        for(int nYCol = 1; nYCol < wks.GetNumCols(); nYCol++)
            DataRange   drInputData;
            drInputData.Add(wks, 0, "X");
            drInputData.Add(wks, nYCol, "Y");
            int         nNumData = drInputData.GetNumData(dwRules);
            //2 set the dataset
            vector  vX1, vY1;
            drInputData.GetData( dwRules, nDataIndex, NULL, NULL, &vY1, &vX1 );     
            if(!FitSession.SetData(vY1, vX1, NULL, nDataIndex, nNumData))  
                return error_report("err setting data");
            // 3. Call parameter init codes to init parameters
                return error_report("err ParamsInitValues");
            // 4. Iterate with default settings
                string strOutcome = FitSession.GetFitOutCome(nFitOutcome);
                printf("fit failed:%d->%s\n", nFitErr, strOutcome);
                return false;
                // 5. success, get results and put to wksOutput
                FitParameter    params[20];// whatever the max possible number of parameters in your function
                RegStats                fitStats;
                NLSFFitInfo             fitInfo;
                FitSession.GetFitResultsStats(&fitStats, &fitInfo, false, nDataIndex);
                FitSession.GetFitResultsParams(params, &fitStats);
                _append_fit_results(wksOutput, vsParamNames, params, fitStats, fitInfo);
        return true;
static void _append_fit_results(Worksheet& wks, const vector<string>& vsParamNames, const FitParameter* pParams, const RegStats& fitStats, const NLSFFitInfo& fitInfo)
        Column  c0Time = wks.Columns(0);
        int                nR1 = c0Time.GetUpperBound();
        // check if empty, then setup cols
        if(nR1 < 0)
                vector<string> vsExtraCols = {"Tick Count", "Adj Rsquare", "Iterations"};
                int nTotalCols = vsParamNames.GetSize() + vsExtraCols.GetSize();
                if(wks.GetNumCols() < nTotalCols)
                        wks.SetSize(0, nTotalCols);
                        vector<string> vs;vs = vsExtraCols;
                        for(int nCol = 0;nCol < vs.GetSize();nCol++)
                                Column cc = wks.Columns(nCol);
        wks.SetCell(nR1, 0, GetTickCount()/1000.0);
        wks.SetCell(nR1, 1, fitStats.AdjRSq);
        wks.SetCell(nR1, 2, fitInfo.Iterations);
        //fit parameters
        for(int ii = 0, nCol = 3; ii < vsParamNames.GetSize(); ii++, nCol++)
                wks.SetCell(nR1, nCol, pParams[ii].Value);